xwayland: Move socket and launcher code to it's own file
authorKristian Høgsberg <krh@bitplanet.net>
Mon, 21 May 2012 20:48:05 +0000 (16:48 -0400)
committerKristian Høgsberg <krh@bitplanet.net>
Mon, 21 May 2012 21:03:17 +0000 (17:03 -0400)
src/xwayland/Makefile.am
src/xwayland/launcher.c [new file with mode: 0644]
src/xwayland/xserver-launcher.c
src/xwayland/xwayland.h

index 6dd248b..5ca5810 100644 (file)
@@ -16,6 +16,7 @@ xserver_launcher_la_CFLAGS = $(GCC_CFLAGS) $(COMPOSITOR_CFLAGS)
 xserver_launcher_la_SOURCES =                  \
        xserver-launcher.c                      \
        selection.c                             \
+       launcher.c                              \
        xserver-protocol.c                      \
        xserver-server-protocol.h               \
        hash.c                                  \
diff --git a/src/xwayland/launcher.c b/src/xwayland/launcher.c
new file mode 100644 (file)
index 0000000..d8880bd
--- /dev/null
@@ -0,0 +1,378 @@
+/*
+ * 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.
+ */
+
+#define _GNU_SOURCE
+
+#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 "xserver-server-protocol.h"
+
+
+static int
+weston_xserver_handle_event(int listen_fd, uint32_t mask, void *data)
+{
+       struct weston_xserver *mxs = data;
+       char display[8], s[8];
+       int sv[2], client_fd;
+
+       if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, sv) < 0) {
+               fprintf(stderr, "socketpair failed\n");
+               return 1;
+       }
+
+       mxs->process.pid = fork();
+       switch (mxs->process.pid) {
+       case 0:
+               /* SOCK_CLOEXEC closes both ends, so we need to unset
+                * the flag on the client fd. */
+               client_fd = dup(sv[1]);
+               if (client_fd < 0)
+                       return 1;
+
+               snprintf(s, sizeof s, "%d", client_fd);
+               setenv("WAYLAND_SOCKET", s, 1);
+
+               snprintf(display, sizeof display, ":%d", mxs->display);
+
+               if (execl(XSERVER_PATH,
+                         XSERVER_PATH,
+                         display,
+                         "-wayland",
+                         "-rootless",
+                         "-retro",
+                         "-nolisten", "all",
+                         "-terminate",
+                         NULL) < 0)
+                       fprintf(stderr, "exec failed: %m\n");
+               exit(-1);
+
+       default:
+               fprintf(stderr, "forked X server, pid %d\n", mxs->process.pid);
+
+               close(sv[1]);
+               mxs->client = wl_client_create(mxs->wl_display, sv[0]);
+
+               weston_watch_process(&mxs->process);
+
+               wl_event_source_remove(mxs->abstract_source);
+               wl_event_source_remove(mxs->unix_source);
+               break;
+
+       case -1:
+               fprintf(stderr, "failed to fork\n");
+               break;
+       }
+
+       return 1;
+}
+
+static void
+weston_xserver_shutdown(struct weston_xserver *wxs)
+{
+       char path[256];
+
+       snprintf(path, sizeof path, "/tmp/.X%d-lock", wxs->display);
+       unlink(path);
+       snprintf(path, sizeof path, "/tmp/.X11-unix/X%d", wxs->display);
+       unlink(path);
+       if (wxs->process.pid == 0) {
+               wl_event_source_remove(wxs->abstract_source);
+               wl_event_source_remove(wxs->unix_source);
+       }
+       close(wxs->abstract_fd);
+       close(wxs->unix_fd);
+       if (wxs->wm)
+               weston_wm_destroy(wxs->wm);
+       wxs->loop = NULL;
+}
+
+static void
+weston_xserver_cleanup(struct weston_process *process, int status)
+{
+       struct weston_xserver *mxs =
+               container_of(process, struct weston_xserver, process);
+
+       mxs->process.pid = 0;
+       mxs->client = NULL;
+       mxs->resource = NULL;
+
+       mxs->abstract_source =
+               wl_event_loop_add_fd(mxs->loop, mxs->abstract_fd,
+                                    WL_EVENT_READABLE,
+                                    weston_xserver_handle_event, mxs);
+
+       mxs->unix_source =
+               wl_event_loop_add_fd(mxs->loop, mxs->unix_fd,
+                                    WL_EVENT_READABLE,
+                                    weston_xserver_handle_event, mxs);
+
+       if (mxs->wm) {
+               fprintf(stderr, "xserver exited, code %d\n", status);
+               weston_wm_destroy(mxs->wm);
+               mxs->wm = NULL;
+       } else {
+               /* If the X server crashes before it binds to the
+                * xserver interface, shut down and don't try
+                * again. */
+               fprintf(stderr, "xserver crashing too fast: %d\n", status);
+               weston_xserver_shutdown(mxs);
+       }
+}
+
+static void
+bind_xserver(struct wl_client *client,
+            void *data, uint32_t version, uint32_t id)
+{
+       struct weston_xserver *wxs = data;
+
+       /* If it's a different client than the xserver we launched,
+        * don't start the wm. */
+       if (client != wxs->client)
+               return;
+
+       wxs->resource = 
+               wl_client_add_object(client, &xserver_interface,
+                                    &xserver_implementation, id, wxs);
+
+       wxs->wm = weston_wm_create(wxs);
+       if (wxs->wm == NULL) {
+               fprintf(stderr, "failed to create wm\n");
+       }
+
+       xserver_send_listen_socket(wxs->resource, wxs->abstract_fd);
+       xserver_send_listen_socket(wxs->resource, wxs->unix_fd);
+}
+
+static int
+bind_to_abstract_socket(int display)
+{
+       struct sockaddr_un addr;
+       socklen_t size, name_size;
+       int fd;
+
+       fd = socket(PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0);
+       if (fd < 0)
+               return -1;
+
+       addr.sun_family = AF_LOCAL;
+       name_size = snprintf(addr.sun_path, sizeof addr.sun_path,
+                            "%c/tmp/.X11-unix/X%d", 0, display);
+       size = offsetof(struct sockaddr_un, sun_path) + name_size;
+       if (bind(fd, (struct sockaddr *) &addr, size) < 0) {
+               fprintf(stderr, "failed to bind to @%s: %s\n",
+                       addr.sun_path + 1, strerror(errno));
+               close(fd);
+               return -1;
+       }
+
+       if (listen(fd, 1) < 0) {
+               close(fd);
+               return -1;
+       }
+
+       return fd;
+}
+
+static int
+bind_to_unix_socket(int display)
+{
+       struct sockaddr_un addr;
+       socklen_t size, name_size;
+       int fd;
+
+       fd = socket(PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0);
+       if (fd < 0)
+               return -1;
+
+       addr.sun_family = AF_LOCAL;
+       name_size = snprintf(addr.sun_path, sizeof addr.sun_path,
+                            "/tmp/.X11-unix/X%d", display) + 1;
+       size = offsetof(struct sockaddr_un, sun_path) + name_size;
+       unlink(addr.sun_path);
+       if (bind(fd, (struct sockaddr *) &addr, size) < 0) {
+               fprintf(stderr, "failed to bind to %s (%s)\n",
+                       addr.sun_path, strerror(errno));
+               close(fd);
+               return -1;
+       }
+
+       if (listen(fd, 1) < 0) {
+               unlink(addr.sun_path);
+               close(fd);
+               return -1;
+       }
+
+       return fd;
+}
+
+static int
+create_lockfile(int display, char *lockfile, size_t lsize)
+{
+       char pid[16], *end;
+       int fd, size;
+       pid_t other;
+
+       snprintf(lockfile, lsize, "/tmp/.X%d-lock", display);
+       fd = open(lockfile, O_WRONLY | O_CLOEXEC | O_CREAT | O_EXCL, 0444);
+       if (fd < 0 && errno == EEXIST) {
+               fd = open(lockfile, O_CLOEXEC, O_RDONLY);
+               if (fd < 0 || read(fd, pid, 11) != 11) {
+                       fprintf(stderr, "can't read lock file %s: %s\n",
+                               lockfile, strerror(errno));
+                       errno = EEXIST;
+                       return -1;
+               }
+
+               other = strtol(pid, &end, 0);
+               if (end != pid + 10) {
+                       fprintf(stderr, "can't parse lock file %s\n",
+                               lockfile);
+                       close(fd);
+                       errno = EEXIST;
+                       return -1;
+               }
+
+               if (kill(other, 0) < 0 && errno == ESRCH) {
+                       /* stale lock file; unlink and try again */
+                       fprintf(stderr,
+                               "unlinking stale lock file %s\n", lockfile);
+                       close(fd);
+                       if (unlink(lockfile))
+                               /* If we fail to unlink, return EEXIST
+                                  so we try the next display number.*/
+                               errno = EEXIST;
+                       else
+                               errno = EAGAIN;
+                       return -1;
+               }
+
+               errno = EEXIST;
+               return -1;
+       } else if (fd < 0) {
+               fprintf(stderr, "failed to create lock file %s: %s\n",
+                       lockfile, strerror(errno));
+               return -1;
+       }
+
+       /* Subtle detail: we use the pid of the wayland
+        * compositor, not the xserver in the lock file. */
+       size = snprintf(pid, sizeof pid, "%10d\n", getpid());
+       if (write(fd, pid, size) != size) {
+               unlink(lockfile);
+               close(fd);
+               return -1;
+       }
+
+       close(fd);
+
+       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
+weston_xserver_init(struct weston_compositor *compositor)
+{
+       struct wl_display *display = compositor->wl_display;
+       struct weston_xserver *mxs;
+       char lockfile[256], display_name[8];
+
+       mxs = malloc(sizeof *mxs);
+       memset(mxs, 0, sizeof *mxs);
+
+       mxs->process.cleanup = weston_xserver_cleanup;
+       mxs->wl_display = display;
+       mxs->compositor = compositor;
+
+       mxs->display = 0;
+
+ retry:
+       if (create_lockfile(mxs->display, lockfile, sizeof lockfile) < 0) {
+               if (errno == EAGAIN) {
+                       goto retry;
+               } else if (errno == EEXIST) {
+                       mxs->display++;
+                       goto retry;
+               } else {
+                       free(mxs);
+                       return -1;
+               }
+       }
+
+       mxs->abstract_fd = bind_to_abstract_socket(mxs->display);
+       if (mxs->abstract_fd < 0 && errno == EADDRINUSE) {
+               mxs->display++;
+               unlink(lockfile);
+               goto retry;
+       }
+
+       mxs->unix_fd = bind_to_unix_socket(mxs->display);
+       if (mxs->unix_fd < 0) {
+               unlink(lockfile);
+               close(mxs->abstract_fd);
+               free(mxs);
+               return -1;
+       }
+
+       snprintf(display_name, sizeof display_name, ":%d", mxs->display);
+       fprintf(stderr, "xserver listening on display %s\n", display_name);
+       setenv("DISPLAY", display_name, 1);
+
+       mxs->loop = wl_display_get_event_loop(display);
+       mxs->abstract_source =
+               wl_event_loop_add_fd(mxs->loop, mxs->abstract_fd,
+                                    WL_EVENT_READABLE,
+                                    weston_xserver_handle_event, mxs);
+       mxs->unix_source =
+               wl_event_loop_add_fd(mxs->loop, mxs->unix_fd,
+                                    WL_EVENT_READABLE,
+                                    weston_xserver_handle_event, mxs);
+
+       wl_display_add_global(display, &xserver_interface, mxs, bind_xserver);
+
+       mxs->destroy_listener.notify = weston_xserver_destroy;
+       wl_signal_add(&compositor->destroy_signal, &mxs->destroy_listener);
+
+       return 0;
+}
index 5a302bf..b05f4ac 100644 (file)
@@ -452,30 +452,25 @@ static void
 weston_wm_window_schedule_repaint(struct weston_wm_window *window);
 
 static void
-weston_xserver_surface_activate(struct wl_listener *listener, void *data)
+weston_wm_window_activate(struct wl_listener *listener, void *data)
 {
        struct weston_surface *surface = data;
        struct weston_wm_window *window = get_wm_window(surface);
-       struct weston_xserver *wxs =
-               container_of(listener,
-                            struct weston_xserver, activate_listener);
-
-       if (!wxs->wm)
-               return;
+       struct weston_wm *wm = window->wm;
 
        if (window)
-               weston_wm_activate(wxs->wm, window, XCB_TIME_CURRENT_TIME);
+               weston_wm_activate(wm, window, XCB_TIME_CURRENT_TIME);
        else
-               xcb_set_input_focus (wxs->wm->conn,
+               xcb_set_input_focus (wm->conn,
                                     XCB_INPUT_FOCUS_POINTER_ROOT,
                                     XCB_NONE,
                                     XCB_TIME_CURRENT_TIME);
 
-       if (wxs->wm->focus_window)
-               weston_wm_window_schedule_repaint(wxs->wm->focus_window);
-       wxs->wm->focus_window = window;
-       if (wxs->wm->focus_window)
-               weston_wm_window_schedule_repaint(wxs->wm->focus_window);
+       if (wm->focus_window)
+               weston_wm_window_schedule_repaint(wm->focus_window);
+       wm->focus_window = window;
+       if (wm->focus_window)
+               weston_wm_window_schedule_repaint(wm->focus_window);
 }
 
 static int
@@ -1026,7 +1021,7 @@ weston_wm_create_wm_window(struct weston_wm *wm)
 
 }
 
-static struct weston_wm *
+struct weston_wm *
 weston_wm_create(struct weston_xserver *wxs)
 {
        struct wl_seat *seat;
@@ -1131,12 +1126,16 @@ weston_wm_create(struct weston_xserver *wxs)
        wm->selection_listener.notify = weston_wm_set_selection;
        wl_signal_add(&seat->selection_signal, &wm->selection_listener);
 
+       wm->activate_listener.notify = weston_wm_window_activate;
+       wl_signal_add(&wxs->compositor->activate_signal,
+                     &wm->activate_listener);
+
        fprintf(stderr, "created wm\n");
 
        return wm;
 }
 
-static void
+void
 weston_wm_destroy(struct weston_wm *wm)
 {
        /* FIXME: Free windows in hash. */
@@ -1144,118 +1143,9 @@ weston_wm_destroy(struct weston_wm *wm)
        xcb_disconnect(wm->conn);
        wl_event_source_remove(wm->source);
        wl_list_remove(&wm->selection_listener.link);
-       free(wm);
-}
-
-static int
-weston_xserver_handle_event(int listen_fd, uint32_t mask, void *data)
-{
-       struct weston_xserver *mxs = data;
-       char display[8], s[8];
-       int sv[2], client_fd;
-
-       if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, sv) < 0) {
-               fprintf(stderr, "socketpair failed\n");
-               return 1;
-       }
-
-       mxs->process.pid = fork();
-       switch (mxs->process.pid) {
-       case 0:
-               /* SOCK_CLOEXEC closes both ends, so we need to unset
-                * the flag on the client fd. */
-               client_fd = dup(sv[1]);
-               if (client_fd < 0)
-                       return 1;
-
-               snprintf(s, sizeof s, "%d", client_fd);
-               setenv("WAYLAND_SOCKET", s, 1);
-
-               snprintf(display, sizeof display, ":%d", mxs->display);
-
-               if (execl(XSERVER_PATH,
-                         XSERVER_PATH,
-                         display,
-                         "-wayland",
-                         "-rootless",
-                         "-retro",
-                         "-nolisten", "all",
-                         "-terminate",
-                         NULL) < 0)
-                       fprintf(stderr, "exec failed: %m\n");
-               exit(-1);
-
-       default:
-               fprintf(stderr, "forked X server, pid %d\n", mxs->process.pid);
-
-               close(sv[1]);
-               mxs->client = wl_client_create(mxs->wl_display, sv[0]);
-
-               weston_watch_process(&mxs->process);
-
-               wl_event_source_remove(mxs->abstract_source);
-               wl_event_source_remove(mxs->unix_source);
-               break;
-
-       case -1:
-               fprintf(stderr, "failed to fork\n");
-               break;
-       }
-
-       return 1;
-}
-
-static void
-weston_xserver_shutdown(struct weston_xserver *wxs)
-{
-       char path[256];
-
-       snprintf(path, sizeof path, "/tmp/.X%d-lock", wxs->display);
-       unlink(path);
-       snprintf(path, sizeof path, "/tmp/.X11-unix/X%d", wxs->display);
-       unlink(path);
-       if (wxs->process.pid == 0) {
-               wl_event_source_remove(wxs->abstract_source);
-               wl_event_source_remove(wxs->unix_source);
-       }
-       close(wxs->abstract_fd);
-       close(wxs->unix_fd);
-       if (wxs->wm)
-               weston_wm_destroy(wxs->wm);
-       wxs->loop = NULL;
-}
-
-static void
-weston_xserver_cleanup(struct weston_process *process, int status)
-{
-       struct weston_xserver *mxs =
-               container_of(process, struct weston_xserver, process);
-
-       mxs->process.pid = 0;
-       mxs->client = NULL;
-       mxs->resource = NULL;
-
-       mxs->abstract_source =
-               wl_event_loop_add_fd(mxs->loop, mxs->abstract_fd,
-                                    WL_EVENT_READABLE,
-                                    weston_xserver_handle_event, mxs);
-
-       mxs->unix_source =
-               wl_event_loop_add_fd(mxs->loop, mxs->unix_fd,
-                                    WL_EVENT_READABLE,
-                                    weston_xserver_handle_event, mxs);
+       wl_list_remove(&wm->activate_listener.link);
 
-       if (mxs->wm) {
-               fprintf(stderr, "xserver exited, code %d\n", status);
-               weston_wm_destroy(mxs->wm);
-               mxs->wm = NULL;
-       } else {
-               /* If the X server crashes before it binds to the
-                * xserver interface, shut down and don't try
-                * again. */
-               fprintf(stderr, "xserver crashing too fast: %d\n", status);
-               weston_xserver_shutdown(mxs);
-       }
+       free(wm);
 }
 
 static void
@@ -1341,240 +1231,6 @@ xserver_set_window_id(struct wl_client *client, struct wl_resource *resource,
        xserver_map_shell_surface(wm, window);
 }
 
-static const struct xserver_interface xserver_implementation = {
+const struct xserver_interface xserver_implementation = {
        xserver_set_window_id
 };
-
-static void
-bind_xserver(struct wl_client *client,
-            void *data, uint32_t version, uint32_t id)
-{
-       struct weston_xserver *wxs = data;
-
-       /* If it's a different client than the xserver we launched,
-        * don't start the wm. */
-       if (client != wxs->client)
-               return;
-
-       wxs->resource = 
-               wl_client_add_object(client, &xserver_interface,
-                                    &xserver_implementation, id, wxs);
-
-       wxs->wm = weston_wm_create(wxs);
-       if (wxs->wm == NULL) {
-               fprintf(stderr, "failed to create wm\n");
-       }
-
-       xserver_send_listen_socket(wxs->resource, wxs->abstract_fd);
-       xserver_send_listen_socket(wxs->resource, wxs->unix_fd);
-}
-
-static int
-bind_to_abstract_socket(int display)
-{
-       struct sockaddr_un addr;
-       socklen_t size, name_size;
-       int fd;
-
-       fd = socket(PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0);
-       if (fd < 0)
-               return -1;
-
-       addr.sun_family = AF_LOCAL;
-       name_size = snprintf(addr.sun_path, sizeof addr.sun_path,
-                            "%c/tmp/.X11-unix/X%d", 0, display);
-       size = offsetof(struct sockaddr_un, sun_path) + name_size;
-       if (bind(fd, (struct sockaddr *) &addr, size) < 0) {
-               fprintf(stderr, "failed to bind to @%s: %s\n",
-                       addr.sun_path + 1, strerror(errno));
-               close(fd);
-               return -1;
-       }
-
-       if (listen(fd, 1) < 0) {
-               close(fd);
-               return -1;
-       }
-
-       return fd;
-}
-
-static int
-bind_to_unix_socket(int display)
-{
-       struct sockaddr_un addr;
-       socklen_t size, name_size;
-       int fd;
-
-       fd = socket(PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0);
-       if (fd < 0)
-               return -1;
-
-       addr.sun_family = AF_LOCAL;
-       name_size = snprintf(addr.sun_path, sizeof addr.sun_path,
-                            "/tmp/.X11-unix/X%d", display) + 1;
-       size = offsetof(struct sockaddr_un, sun_path) + name_size;
-       unlink(addr.sun_path);
-       if (bind(fd, (struct sockaddr *) &addr, size) < 0) {
-               fprintf(stderr, "failed to bind to %s (%s)\n",
-                       addr.sun_path, strerror(errno));
-               close(fd);
-               return -1;
-       }
-
-       if (listen(fd, 1) < 0) {
-               unlink(addr.sun_path);
-               close(fd);
-               return -1;
-       }
-
-       return fd;
-}
-
-static int
-create_lockfile(int display, char *lockfile, size_t lsize)
-{
-       char pid[16], *end;
-       int fd, size;
-       pid_t other;
-
-       snprintf(lockfile, lsize, "/tmp/.X%d-lock", display);
-       fd = open(lockfile, O_WRONLY | O_CLOEXEC | O_CREAT | O_EXCL, 0444);
-       if (fd < 0 && errno == EEXIST) {
-               fd = open(lockfile, O_CLOEXEC, O_RDONLY);
-               if (fd < 0 || read(fd, pid, 11) != 11) {
-                       fprintf(stderr, "can't read lock file %s: %s\n",
-                               lockfile, strerror(errno));
-                       errno = EEXIST;
-                       return -1;
-               }
-
-               other = strtol(pid, &end, 0);
-               if (end != pid + 10) {
-                       fprintf(stderr, "can't parse lock file %s\n",
-                               lockfile);
-                       close(fd);
-                       errno = EEXIST;
-                       return -1;
-               }
-
-               if (kill(other, 0) < 0 && errno == ESRCH) {
-                       /* stale lock file; unlink and try again */
-                       fprintf(stderr,
-                               "unlinking stale lock file %s\n", lockfile);
-                       close(fd);
-                       if (unlink(lockfile))
-                               /* If we fail to unlink, return EEXIST
-                                  so we try the next display number.*/
-                               errno = EEXIST;
-                       else
-                               errno = EAGAIN;
-                       return -1;
-               }
-
-               errno = EEXIST;
-               return -1;
-       } else if (fd < 0) {
-               fprintf(stderr, "failed to create lock file %s: %s\n",
-                       lockfile, strerror(errno));
-               return -1;
-       }
-
-       /* Subtle detail: we use the pid of the wayland
-        * compositor, not the xserver in the lock file. */
-       size = snprintf(pid, sizeof pid, "%10d\n", getpid());
-       if (write(fd, pid, size) != size) {
-               unlink(lockfile);
-               close(fd);
-               return -1;
-       }
-
-       close(fd);
-
-       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
-weston_xserver_init(struct weston_compositor *compositor)
-{
-       struct wl_display *display = compositor->wl_display;
-       struct weston_xserver *mxs;
-       char lockfile[256], display_name[8];
-
-       mxs = malloc(sizeof *mxs);
-       memset(mxs, 0, sizeof *mxs);
-
-       mxs->process.cleanup = weston_xserver_cleanup;
-       mxs->wl_display = display;
-       mxs->compositor = compositor;
-
-       mxs->display = 0;
-
- retry:
-       if (create_lockfile(mxs->display, lockfile, sizeof lockfile) < 0) {
-               if (errno == EAGAIN) {
-                       goto retry;
-               } else if (errno == EEXIST) {
-                       mxs->display++;
-                       goto retry;
-               } else {
-                       free(mxs);
-                       return -1;
-               }
-       }                               
-
-       mxs->abstract_fd = bind_to_abstract_socket(mxs->display);
-       if (mxs->abstract_fd < 0 && errno == EADDRINUSE) {
-               mxs->display++;
-               unlink(lockfile);
-               goto retry;
-       }
-
-       mxs->unix_fd = bind_to_unix_socket(mxs->display);
-       if (mxs->unix_fd < 0) {
-               unlink(lockfile);
-               close(mxs->abstract_fd);
-               free(mxs);
-               return -1;
-       }
-
-       snprintf(display_name, sizeof display_name, ":%d", mxs->display);
-       fprintf(stderr, "xserver listening on display %s\n", display_name);
-       setenv("DISPLAY", display_name, 1);
-
-       mxs->loop = wl_display_get_event_loop(display);
-       mxs->abstract_source =
-               wl_event_loop_add_fd(mxs->loop, mxs->abstract_fd,
-                                    WL_EVENT_READABLE,
-                                    weston_xserver_handle_event, mxs);
-       mxs->unix_source =
-               wl_event_loop_add_fd(mxs->loop, mxs->unix_fd,
-                                    WL_EVENT_READABLE,
-                                    weston_xserver_handle_event, mxs);
-
-       wl_display_add_global(display, &xserver_interface, mxs, bind_xserver);
-
-       mxs->destroy_listener.notify = weston_xserver_destroy;
-       wl_signal_add(&compositor->destroy_signal, &mxs->destroy_listener);
-
-
-       mxs->activate_listener.notify = weston_xserver_surface_activate;
-       wl_signal_add(&compositor->activate_signal, &mxs->activate_listener);
-
-       return 0;
-}
index 78b2be8..72a25cc 100644 (file)
@@ -45,7 +45,6 @@ struct weston_xserver {
        struct wl_client *client;
        struct weston_compositor *compositor;
        struct weston_wm *wm;
-       struct wl_listener activate_listener;
        struct wl_listener destroy_listener;
 };
 
@@ -60,6 +59,7 @@ struct weston_wm {
        struct weston_wm_window *focus_window;
        struct theme *theme;
        xcb_render_pictforminfo_t render_format;
+       struct wl_listener activate_listener;
 
        xcb_window_t selection_window;
        int incr;
@@ -132,3 +132,11 @@ weston_wm_handle_selection_event(struct weston_wm *wm,
 
 void
 weston_wm_set_selection(struct wl_listener *listener, void *data);
+
+extern const struct xserver_interface xserver_implementation;
+
+struct weston_wm *
+weston_wm_create(struct weston_xserver *wxs);
+void
+weston_wm_destroy(struct weston_wm *wm);
+