[RFC weston] Initial libweston implementation

Giulio Camuffo giuliocamuffo at gmail.com
Sat Aug 16 10:24:27 PDT 2014


The approach taken here is to move all the stuff that belongs in a binary,
such as the main(), module and backend loading, config handling, to
a weston.c/h, keeping the behavior untouched.
All .so modules include weston.h, so they cannot be directly used by other
users of libweston, instead the modules provide a .h which are to be called
by the compositors using libweston directly, or by plugins of them.
All the config handling (weston_config, weston_option, ..) is weston-specific,
so weston_compositor does not hold a weston_config pointer anymore. Instead,
the config is passed to each module on creation.
---

I have thought quite a lot about how to make the modules work transparently
with every libweston user, but ultimately I don't think it can be done in
a clean way. Instead, have the libweston users have their own plugins, if
they want to, sharing the actual implementation with the weston modules.
Each backend and module should provide a .h to be used by other libweston
users, for now only compositor-x11 and xwayland do so.


 Makefile.am                          | 111 +++--
 desktop-shell/shell.c                |   8 +-
 desktop-shell/shell.h                |   1 +
 fullscreen-shell/fullscreen-shell.c  |   3 +-
 {src => libweston}/bindings.c        |   0
 {src => libweston}/clipboard.c       |   0
 {src => libweston}/compositor-x11.c  | 153 +------
 libweston/compositor-x11.h           |  33 ++
 {src => libweston}/compositor.c      | 717 ++------------------------------
 {src => libweston}/compositor.h      |  25 +-
 {src => libweston}/data-device.c     |   0
 {src => libweston}/gl-renderer.c     |   0
 {src => libweston}/gl-renderer.h     |   0
 {src => libweston}/input.c           |   2 +-
 {src => libweston}/noop-renderer.c   |   0
 {src => libweston}/pixman-renderer.c |   0
 {src => libweston}/pixman-renderer.h |   0
 {src => libweston}/rpi-bcm-stubs.h   |   0
 {src => libweston}/rpi-renderer.c    |   0
 {src => libweston}/rpi-renderer.h    |   0
 {src => libweston}/screenshooter.c   |   0
 {src => libweston}/vertex-clipping.c |   0
 {src => libweston}/vertex-clipping.h |   0
 {src => libweston}/weston-egl-ext.h  |   0
 {src => libweston}/zoom.c            |   0
 src/cms-colord.c                     |   3 +-
 src/cms-static.c                     |   7 +-
 src/log.c                            |   1 +
 src/text-backend.c                   |  10 +-
 src/weston.c                         | 763 +++++++++++++++++++++++++++++++++++
 src/weston.h                         |  55 +++
 src/x11-backend.c                    | 168 ++++++++
 tests/surface-global-test.c          |   2 +-
 tests/surface-test.c                 |   2 +-
 tests/vertex-clip-test.c             |   2 +-
 tests/weston-test.c                  |   2 +-
 xwayland/launcher.c                  |  37 +-
 xwayland/xwayland-module.c           |  26 ++
 xwayland/xwayland.h                  |   4 +
 39 files changed, 1220 insertions(+), 915 deletions(-)
 rename {src => libweston}/bindings.c (100%)
 rename {src => libweston}/clipboard.c (100%)
 rename {src => libweston}/compositor-x11.c (91%)
 create mode 100644 libweston/compositor-x11.h
 rename {src => libweston}/compositor.c (85%)
 rename {src => libweston}/compositor.h (98%)
 rename {src => libweston}/data-device.c (100%)
 rename {src => libweston}/gl-renderer.c (100%)
 rename {src => libweston}/gl-renderer.h (100%)
 rename {src => libweston}/input.c (99%)
 rename {src => libweston}/noop-renderer.c (100%)
 rename {src => libweston}/pixman-renderer.c (100%)
 rename {src => libweston}/pixman-renderer.h (100%)
 rename {src => libweston}/rpi-bcm-stubs.h (100%)
 rename {src => libweston}/rpi-renderer.c (100%)
 rename {src => libweston}/rpi-renderer.h (100%)
 rename {src => libweston}/screenshooter.c (100%)
 rename {src => libweston}/vertex-clipping.c (100%)
 rename {src => libweston}/vertex-clipping.h (100%)
 rename {src => libweston}/weston-egl-ext.h (100%)
 rename {src => libweston}/zoom.c (100%)
 create mode 100644 src/weston.c
 create mode 100644 src/weston.h
 create mode 100644 src/x11-backend.c
 create mode 100644 xwayland/xwayland-module.c

diff --git a/Makefile.am b/Makefile.am
index 191dcc9..3b762f6 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -25,6 +25,8 @@ AM_CFLAGS = $(GCC_CFLAGS)
 
 AM_CPPFLAGS = 					\
 	-I$(top_srcdir)/src			\
+	-I$(top_srcdir)/libweston		\
+	-I$(top_builddir)/libweston		\
 	-I$(top_builddir)/src			\
 	-I$(top_builddir)/clients		\
 	-I$(top_builddir)/tests			\
@@ -37,36 +39,32 @@ AM_CPPFLAGS = 					\
 
 CLEANFILES = weston.ini $(BUILT_SOURCES)
 
-bin_PROGRAMS += weston
+module_LTLIBRARIES += libweston.la
 
-weston_LDFLAGS = -export-dynamic
-weston_CPPFLAGS = $(AM_CPPFLAGS) -DIN_WESTON
-weston_CFLAGS = $(GCC_CFLAGS) $(COMPOSITOR_CFLAGS) $(LIBUNWIND_CFLAGS)
-weston_LDADD = $(COMPOSITOR_LIBS) $(LIBUNWIND_LIBS) \
+libweston_la_CPPFLAGS = $(AM_CPPFLAGS) -DIN_WESTON
+libweston_la_CFLAGS = $(GCC_CFLAGS) $(COMPOSITOR_CFLAGS) $(LIBUNWIND_CFLAGS)
+libweston_la_LIBADD = $(COMPOSITOR_LIBS) $(LIBUNWIND_LIBS) \
 	$(DLOPEN_LIBS) -lm libshared.la
 
-weston_SOURCES =					\
-	src/git-version.h				\
-	src/log.c					\
-	src/compositor.c				\
-	src/compositor.h				\
-	src/input.c					\
-	src/data-device.c				\
-	src/screenshooter.c				\
-	src/clipboard.c					\
-	src/zoom.c					\
-	src/text-backend.c				\
-	src/bindings.c					\
-	src/animation.c					\
-	src/noop-renderer.c				\
-	src/pixman-renderer.c				\
-	src/pixman-renderer.h				\
+libweston_la_SOURCES =					\
+	shared/git-version.h				\
+	libweston/compositor.c				\
+	libweston/compositor.h				\
+	libweston/input.c				\
+	libweston/data-device.c				\
+	libweston/screenshooter.c			\
+	libweston/clipboard.c				\
+	libweston/zoom.c				\
+	libweston/bindings.c				\
+	libweston/noop-renderer.c			\
+	libweston/pixman-renderer.c			\
+	libweston/pixman-renderer.h			\
 	shared/matrix.c					\
 	shared/matrix.h					\
 	shared/zalloc.h					\
-	src/weston-egl-ext.h
+	libweston/weston-egl-ext.h
 
-nodist_weston_SOURCES =					\
+nodist_libweston_la_SOURCES =				\
 	protocol/screenshooter-protocol.c		\
 	protocol/screenshooter-server-protocol.h	\
 	protocol/text-cursor-position-protocol.c	\
@@ -80,13 +78,13 @@ nodist_weston_SOURCES =					\
 	protocol/scaler-protocol.c			\
 	protocol/scaler-server-protocol.h
 
-BUILT_SOURCES += $(nodist_weston_SOURCES)
+BUILT_SOURCES += $(nodist_libweston_la_SOURCES)
 
 # Track this dependency explicitly instead of using BUILT_SOURCES.  We
 # add BUILT_SOURCES to CLEANFILES, but we want to keep git-version.h
 # in case we're building from tarballs.
 
-src/compositor.c : $(top_builddir)/src/git-version.h
+libweston/compositor.c : $(top_builddir)/shared/git-version.h
 
 noinst_LTLIBRARIES +=				\
 	libsession-helper.la
@@ -111,10 +109,10 @@ endif
 endif
 
 if HAVE_GIT_REPO
-src/git-version.h : $(top_srcdir)/.git/logs/HEAD
+shared/git-version.h : $(top_srcdir)/.git/logs/HEAD
 	$(AM_V_GEN)echo "#define BUILD_ID \"$(shell git --git-dir=$(top_srcdir)/.git describe --always --dirty) $(shell git --git-dir=$(top_srcdir)/.git log -1 --format='%s (%ci)')\"" > $@
 else
-src/git-version.h :
+shared/git-version.h :
 	$(AM_V_GEN)echo "#define BUILD_ID \"unknown (not built from git or tarball)\"" > $@
 
 endif
@@ -145,8 +143,9 @@ pkgconfig_DATA = src/weston.pc
 
 westonincludedir = $(includedir)/weston
 westoninclude_HEADERS =				\
-	src/version.h				\
-	src/compositor.h			\
+	src/version.h			\
+	libweston/compositor.h			\
+	libweston/compositor-x11.h		\
 	shared/matrix.h				\
 	shared/config-parser.h			\
 	shared/zalloc.h
@@ -160,10 +159,10 @@ gl_renderer_la_CFLAGS =				\
 	$(EGL_CFLAGS)				\
 	$(GCC_CFLAGS)
 gl_renderer_la_SOURCES =			\
-	src/gl-renderer.h			\
-	src/gl-renderer.c			\
-	src/vertex-clipping.c			\
-	src/vertex-clipping.h
+	libweston/gl-renderer.h			\
+	libweston/gl-renderer.c			\
+	libweston/vertex-clipping.c		\
+	libweston/vertex-clipping.h
 endif
 
 if ENABLE_X11_COMPOSITOR
@@ -178,7 +177,10 @@ x11_backend_la_CFLAGS =				\
 	$(CAIRO_CFLAGS)				\
 	$(X11_COMPOSITOR_CFLAGS)		\
 	$(GCC_CFLAGS)
-x11_backend_la_SOURCES = src/compositor-x11.c
+x11_backend_la_SOURCES =			\
+	libweston/compositor-x11.c		\
+	libweston/compositor-x11.h		\
+	src/x11-backend.c
 endif
 
 INPUT_BACKEND_SOURCES = src/udev-input.h
@@ -269,9 +271,9 @@ rpi_backend_la_CFLAGS =				\
 	$(RPI_BCM_HOST_CFLAGS)
 rpi_backend_la_SOURCES =			\
 	src/compositor-rpi.c			\
-	src/rpi-renderer.c			\
-	src/rpi-renderer.h			\
-	src/rpi-bcm-stubs.h			\
+	libweston/rpi-renderer.c			\
+	libweston/rpi-renderer.h			\
+	libweston/rpi-bcm-stubs.h			\
 	$(INPUT_BACKEND_SOURCES)
 
 if ENABLE_EGL
@@ -659,6 +661,29 @@ wcap_decode_LDADD = $(WCAP_LIBS)
 endif
 
 
+bin_PROGRAMS += weston
+
+weston_CPPFLAGS =			\
+	-I$(top_builddir)/protocol		\
+	-I$(top_srcdir)/shared			\
+	-I$(top_srcdir)/src			\
+	-I$(top_srcdir)/libweston		\
+	-I$(top_builddir)/src			\
+	-DDATADIR='"$(datadir)"'		\
+	-DMODULEDIR='"$(moduledir)"'		\
+	-DLIBEXECDIR='"$(libexecdir)"'		\
+	-DIN_WESTON
+
+weston_LDFLAGS = -export-dynamic
+weston_LDADD = $(COMPOSITOR_LIBS) libweston.la libshared.la
+weston_CFLAGS = $(GCC_CFLAGS) $(COMPOSITOR_CFLAGS)
+weston_SOURCES =				\
+	src/weston.h				\
+	src/weston.c				\
+	src/log.c				\
+	src/animation.c				\
+	src/text-backend.c
+
 if ENABLE_DESKTOP_SHELL
 
 module_LTLIBRARIES += desktop-shell.la
@@ -667,6 +692,7 @@ desktop_shell_la_CPPFLAGS =			\
 	-I$(top_builddir)/protocol		\
 	-I$(top_srcdir)/shared			\
 	-I$(top_srcdir)/src			\
+	-I$(top_srcdir)/libweston		\
 	-I$(top_builddir)/src			\
 	-I$(top_builddir)/desktop-shell		\
 	-DDATADIR='"$(datadir)"'		\
@@ -682,7 +708,7 @@ desktop_shell_la_SOURCES =				\
 	desktop-shell/shell.c				\
 	desktop-shell/exposay.c				\
 	desktop-shell/input-panel.c
-nodist_desktop_shell_la_SOURCES =			\
+nodist_desktop_shell_la_SOURCES =				\
 	protocol/desktop-shell-protocol.c		\
 	protocol/desktop-shell-server-protocol.h	\
 	protocol/xdg-shell-protocol.c			\
@@ -700,6 +726,7 @@ fullscreen_shell_la_CPPFLAGS =			\
 	-I$(top_srcdir)/shared			\
 	-I$(top_srcdir)/src			\
 	-I$(top_builddir)/src			\
+	-I$(top_srcdir)/libweston		\
 	-DIN_WESTON
 
 fullscreen_shell_la_LDFLAGS = -module -avoid-version
@@ -744,6 +771,7 @@ xwayland_la_CPPFLAGS =				\
 	-I$(top_builddir)/protocol		\
 	-I$(top_srcdir)/shared			\
 	-I$(top_srcdir)/src			\
+	-I$(top_srcdir)/libweston		\
 	-I$(top_builddir)/src			\
 	-I$(top_builddir)/xwayland		\
 	-DDATADIR='"$(datadir)"'		\
@@ -767,7 +795,8 @@ xwayland_la_SOURCES =				\
 	xwayland/dnd.c				\
 	xwayland/launcher.c			\
 	xwayland/hash.c				\
-	xwayland/hash.h
+	xwayland/hash.h				\
+	xwayland/xwayland-module.c
 endif
 
 
@@ -893,8 +922,8 @@ config_parser_test_LDADD = libshared.la libtest-runner.la $(COMPOSITOR_LIBS)
 
 vertex_clip_test_SOURCES =			\
 	tests/vertex-clip-test.c		\
-	src/vertex-clipping.c			\
-	src/vertex-clipping.h
+	libweston/vertex-clipping.c			\
+	libweston/vertex-clipping.h
 vertex_clip_test_LDADD = libtest-runner.la -lm -lrt
 
 libtest_client_la_SOURCES =			\
diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c
index 7370972..ab59a93 100644
--- a/desktop-shell/shell.c
+++ b/desktop-shell/shell.c
@@ -34,6 +34,7 @@
 #include <math.h>
 #include <sys/types.h>
 
+#include "weston.h"
 #include "shell.h"
 #include "desktop-shell-server-protocol.h"
 #include "workspaces-server-protocol.h"
@@ -507,14 +508,14 @@ shell_configuration(struct desktop_shell *shell)
 	int duration;
 	char *s;
 
-	section = weston_config_get_section(shell->compositor->config,
+	section = weston_config_get_section(shell->config,
 					    "screensaver", NULL, NULL);
 	weston_config_section_get_string(section,
 					 "path", &shell->screensaver.path, NULL);
 	weston_config_section_get_int(section, "duration", &duration, 60);
 	shell->screensaver.duration = duration * 1000;
 
-	section = weston_config_get_section(shell->compositor->config,
+	section = weston_config_get_section(shell->config,
 					    "shell", NULL, NULL);
 	weston_config_section_get_string(section,
 					 "client", &s, LIBEXECDIR "/" WESTON_SHELL_CLIENT);
@@ -6177,7 +6178,7 @@ handle_seat_created(struct wl_listener *listener, void *data)
 
 WL_EXPORT int
 module_init(struct weston_compositor *ec,
-	    int *argc, char *argv[])
+	    int *argc, char *argv[], struct weston_config *config)
 {
 	struct weston_seat *seat;
 	struct desktop_shell *shell;
@@ -6190,6 +6191,7 @@ module_init(struct weston_compositor *ec,
 		return -1;
 
 	shell->compositor = ec;
+	shell->config = config;
 
 	shell->destroy_listener.notify = shell_destroy;
 	wl_signal_add(&ec->destroy_signal, &shell->destroy_listener);
diff --git a/desktop-shell/shell.h b/desktop-shell/shell.h
index 6e63785..6272f83 100644
--- a/desktop-shell/shell.h
+++ b/desktop-shell/shell.h
@@ -114,6 +114,7 @@ struct shell_output {
 
 struct desktop_shell {
 	struct weston_compositor *compositor;
+	struct weston_config *config;
 
 	struct wl_listener idle_listener;
 	struct wl_listener wake_listener;
diff --git a/fullscreen-shell/fullscreen-shell.c b/fullscreen-shell/fullscreen-shell.c
index 25932d4..54d1182 100644
--- a/fullscreen-shell/fullscreen-shell.c
+++ b/fullscreen-shell/fullscreen-shell.c
@@ -29,6 +29,7 @@
 #include <string.h>
 #include <assert.h>
 
+#include "weston.h"
 #include "compositor.h"
 #include "fullscreen-shell-server-protocol.h"
 
@@ -792,7 +793,7 @@ bind_fullscreen_shell(struct wl_client *client, void *data, uint32_t version,
 
 WL_EXPORT int
 module_init(struct weston_compositor *compositor,
-	    int *argc, char *argv[])
+	    int *argc, char *argv[], struct weston_config *config)
 {
 	struct fullscreen_shell *shell;
 	struct weston_seat *seat;
diff --git a/src/bindings.c b/libweston/bindings.c
similarity index 100%
rename from src/bindings.c
rename to libweston/bindings.c
diff --git a/src/clipboard.c b/libweston/clipboard.c
similarity index 100%
rename from src/clipboard.c
rename to libweston/clipboard.c
diff --git a/src/compositor-x11.c b/libweston/compositor-x11.c
similarity index 91%
rename from src/compositor-x11.c
rename to libweston/compositor-x11.c
index 56b3228..943c777 100644
--- a/src/compositor-x11.c
+++ b/libweston/compositor-x11.c
@@ -46,6 +46,7 @@
 
 #include <xkbcommon/xkbcommon.h>
 
+#include "compositor-x11.h"
 #include "compositor.h"
 #include "gl-renderer.h"
 #include "pixman-renderer.h"
@@ -54,11 +55,6 @@
 
 #define DEFAULT_AXIS_STEP_DISTANCE wl_fixed_from_int(10)
 
-static int option_width;
-static int option_height;
-static int option_scale;
-static int option_count;
-
 struct x11_compositor {
 	struct weston_compositor	 base;
 
@@ -72,6 +68,7 @@ struct x11_compositor {
 	unsigned int		 has_xkb;
 	uint8_t			 xkb_event_base;
 	int			 use_pixman;
+	int			 no_input;
 
 	int			 has_net_wm_state_fullscreen;
 
@@ -748,7 +745,7 @@ x11_output_init_shm(struct x11_compositor *c, struct x11_output *output,
 	return 0;
 }
 
-static struct x11_output *
+WL_EXPORT struct weston_output *
 x11_compositor_create_output(struct x11_compositor *c, int x, int y,
 			     int width, int height, int fullscreen,
 			     int no_input, char *configured_name,
@@ -910,7 +907,7 @@ x11_compositor_create_output(struct x11_compositor *c, int x, int y,
 	weston_log("x11 output %dx%d, window id %d\n",
 		   width, height, output->window);
 
-	return output;
+	return &output->base;
 }
 
 static struct x11_output *
@@ -1432,29 +1429,15 @@ x11_destroy(struct weston_compositor *ec)
 	free(ec);
 }
 
-static uint32_t
-parse_transform(const char *transform, const char *output_name)
+static int
+x11_setup(struct weston_compositor *ec)
 {
-	static const struct { const char *name; uint32_t token; } names[] = {
-		{ "normal",	WL_OUTPUT_TRANSFORM_NORMAL },
-		{ "90",		WL_OUTPUT_TRANSFORM_90 },
-		{ "180",	WL_OUTPUT_TRANSFORM_180 },
-		{ "270",	WL_OUTPUT_TRANSFORM_270 },
-		{ "flipped",	WL_OUTPUT_TRANSFORM_FLIPPED },
-		{ "flipped-90",	WL_OUTPUT_TRANSFORM_FLIPPED_90 },
-		{ "flipped-180", WL_OUTPUT_TRANSFORM_FLIPPED_180 },
-		{ "flipped-270", WL_OUTPUT_TRANSFORM_FLIPPED_270 },
-	};
-	unsigned int i;
-
-	for (i = 0; i < ARRAY_LENGTH(names); i++)
-		if (strcmp(names[i].name, transform) == 0)
-			return names[i].token;
+	struct x11_compositor *c = (struct x11_compositor *)ec;
 
-	weston_log("Invalid transform \"%s\" for output %s\n",
-		   transform, output_name);
+	if (x11_input_create(c, c->no_input) < 0)
+		return -1;
 
-	return WL_OUTPUT_TRANSFORM_NORMAL;
+	return 0;
 }
 
 static int
@@ -1472,23 +1455,15 @@ init_gl_renderer(struct x11_compositor *c)
 
 	return ret;
 }
-static struct weston_compositor *
+
+WL_EXPORT struct x11_compositor *
 x11_compositor_create(struct wl_display *display,
 		      int fullscreen,
 		      int no_input,
-		      int use_pixman,
-		      int *argc, char *argv[],
-		      struct weston_config *config)
+		      int use_pixman)
 {
 	struct x11_compositor *c;
-	struct x11_output *output;
-	struct weston_config_section *section;
 	xcb_screen_iterator_t s;
-	int i, x = 0, output_count = 0;
-	int width, height, scale, count;
-	const char *section_name;
-	char *name, *t, *mode;
-	uint32_t transform;
 
 	weston_log("initializing x11 backend\n");
 
@@ -1496,7 +1471,7 @@ x11_compositor_create(struct wl_display *display,
 	if (c == NULL)
 		return NULL;
 
-	if (weston_compositor_init(&c->base, display, argc, argv, config) < 0)
+	if (weston_compositor_init(&c->base, display) < 0)
 		goto err_free;
 
 	c->dpy = XOpenDisplay(NULL);
@@ -1523,6 +1498,7 @@ x11_compositor_create(struct wl_display *display,
 	}
 
 	c->base.wl_display = display;
+	c->no_input = no_input;
 	c->use_pixman = use_pixman;
 	if (c->use_pixman) {
 		if (pixman_renderer_init(&c->base) < 0)
@@ -1535,73 +1511,7 @@ x11_compositor_create(struct wl_display *display,
 
 	c->base.destroy = x11_destroy;
 	c->base.restore = x11_restore;
-
-	if (x11_input_create(c, no_input) < 0)
-		goto err_renderer;
-
-	width = option_width ? option_width : 1024;
-	height = option_height ? option_height : 640;
-	scale = option_scale ? option_scale : 1;
-	count = option_count ? option_count : 1;
-
-	section = NULL;
-	while (weston_config_next_section(c->base.config,
-					  &section, &section_name)) {
-		if (strcmp(section_name, "output") != 0)
-			continue;
-		weston_config_section_get_string(section, "name", &name, NULL);
-		if (name == NULL || name[0] != 'X') {
-			free(name);
-			continue;
-		}
-
-		weston_config_section_get_string(section,
-						 "mode", &mode, "1024x600");
-		if (sscanf(mode, "%dx%d", &width, &height) != 2) {
-			weston_log("Invalid mode \"%s\" for output %s\n",
-				   mode, name);
-			width = 1024;
-			height = 600;
-		}
-		free(mode);
-
-		if (option_width)
-			width = option_width;
-		if (option_height)
-			height = option_height;
-
-		weston_config_section_get_int(section, "scale", &scale, 1);
-		if (option_scale)
-			scale = option_scale;
-
-		weston_config_section_get_string(section,
-						 "transform", &t, "normal");
-		transform = parse_transform(t, name);
-		free(t);
-
-		output = x11_compositor_create_output(c, x, 0,
-						      width, height,
-						      fullscreen, no_input,
-						      name, transform, scale);
-		free(name);
-		if (output == NULL)
-			goto err_x11_input;
-
-		x = pixman_region32_extents(&output->base.region)->x2;
-
-		output_count++;
-		if (option_count && output_count >= option_count)
-			break;
-	}
-
-	for (i = output_count; i < count; i++) {
-		output = x11_compositor_create_output(c, x, 0, width, height,
-						      fullscreen, no_input, NULL,
-						      WL_OUTPUT_TRANSFORM_NORMAL, scale);
-		if (output == NULL)
-			goto err_x11_input;
-		x = pixman_region32_extents(&output->base.region)->x2;
-	}
+	c->base.setup = x11_setup;
 
 	c->xcb_source =
 		wl_event_loop_add_fd(c->base.input_loop,
@@ -1610,12 +1520,8 @@ x11_compositor_create(struct wl_display *display,
 				     x11_compositor_handle_event, c);
 	wl_event_source_check(c->xcb_source);
 
-	return &c->base;
+	return c;
 
-err_x11_input:
-	x11_input_destroy(c);
-err_renderer:
-	c->base.renderer->destroy(&c->base);
 err_xdisplay:
 	XCloseDisplay(c->dpy);
 err_free:
@@ -1624,28 +1530,7 @@ err_free:
 }
 
 WL_EXPORT struct weston_compositor *
-backend_init(struct wl_display *display, int *argc, char *argv[],
-	     struct weston_config *config)
+x11_compositor_get_base(struct x11_compositor *c)
 {
-	int fullscreen = 0;
-	int no_input = 0;
-	int use_pixman = 0;
-
-	const struct weston_option x11_options[] = {
-		{ WESTON_OPTION_INTEGER, "width", 0, &option_width },
-		{ WESTON_OPTION_INTEGER, "height", 0, &option_height },
-		{ WESTON_OPTION_INTEGER, "scale", 0, &option_scale },
-		{ WESTON_OPTION_BOOLEAN, "fullscreen", 'f', &fullscreen },
-		{ WESTON_OPTION_INTEGER, "output-count", 0, &option_count },
-		{ WESTON_OPTION_BOOLEAN, "no-input", 0, &no_input },
-		{ WESTON_OPTION_BOOLEAN, "use-pixman", 0, &use_pixman },
-	};
-
-	parse_options(x11_options, ARRAY_LENGTH(x11_options), argc, argv);
-
-	return x11_compositor_create(display,
-				     fullscreen,
-				     no_input,
-				     use_pixman,
-				     argc, argv, config);
+	return &c->base;
 }
diff --git a/libweston/compositor-x11.h b/libweston/compositor-x11.h
new file mode 100644
index 0000000..d422b7e
--- /dev/null
+++ b/libweston/compositor-x11.h
@@ -0,0 +1,33 @@
+
+#ifndef WESTON_COMPOSITOR_X11_H
+#define WESTON_COMPOSITOR_X11_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#include "compositor.h"
+
+struct wl_display;
+
+struct x11_compositor *
+x11_compositor_create(struct wl_display *display,
+		      int fullscreen,
+		      int no_input,
+		      int use_pixman);
+
+
+struct weston_output *
+x11_compositor_create_output(struct x11_compositor *c, int x, int y,
+			     int width, int height, int fullscreen,
+			     int no_input, char *configured_name,
+			     uint32_t transform, int32_t scale);
+
+struct weston_compositor *
+x11_compositor_get_base(struct x11_compositor *c);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/compositor.c b/libweston/compositor.c
similarity index 85%
rename from src/compositor.c
rename to libweston/compositor.c
index 96e3435..0f06049 100644
--- a/src/compositor.c
+++ b/libweston/compositor.c
@@ -47,47 +47,12 @@
 #include <sys/time.h>
 #include <time.h>
 
-#ifdef HAVE_LIBUNWIND
-#define UNW_LOCAL_ONLY
-#include <libunwind.h>
-#endif
-
 #include "compositor.h"
 #include "scaler-server-protocol.h"
 #include "../shared/os-compatibility.h"
 #include "git-version.h"
 #include "version.h"
 
-static struct wl_list child_process_list;
-static struct weston_compositor *segv_compositor;
-
-static int
-sigchld_handler(int signal_number, void *data)
-{
-	struct weston_process *p;
-	int status;
-	pid_t pid;
-
-	pid = waitpid(-1, &status, WNOHANG);
-	if (!pid)
-		return 1;
-
-	wl_list_for_each(p, &child_process_list, link) {
-		if (p->pid == pid)
-			break;
-	}
-
-	if (&p->link == &child_process_list) {
-		weston_log("unknown child process exited\n");
-		return 1;
-	}
-
-	wl_list_remove(&p->link);
-	p->cleanup(p, status);
-
-	return 1;
-}
-
 static void
 weston_output_transform_scale_init(struct weston_output *output,
 				   uint32_t transform, uint32_t scale);
@@ -229,96 +194,6 @@ weston_output_switch_mode(struct weston_output *output, struct weston_mode *mode
 	return ret;
 }
 
-WL_EXPORT void
-weston_watch_process(struct weston_process *process)
-{
-	wl_list_insert(&child_process_list, &process->link);
-}
-
-static void
-child_client_exec(int sockfd, const char *path)
-{
-	int clientfd;
-	char s[32];
-	sigset_t allsigs;
-
-	/* do not give our signal mask to the new process */
-	sigfillset(&allsigs);
-	sigprocmask(SIG_UNBLOCK, &allsigs, NULL);
-
-	/* Launch clients as the user. Do not lauch clients with wrong euid.*/
-	if (seteuid(getuid()) == -1) {
-		weston_log("compositor: failed seteuid\n");
-		return;
-	}
-
-	/* SOCK_CLOEXEC closes both ends, so we dup the fd to get a
-	 * non-CLOEXEC fd to pass through exec. */
-	clientfd = dup(sockfd);
-	if (clientfd == -1) {
-		weston_log("compositor: dup failed: %m\n");
-		return;
-	}
-
-	snprintf(s, sizeof s, "%d", clientfd);
-	setenv("WAYLAND_SOCKET", s, 1);
-
-	if (execl(path, path, NULL) < 0)
-		weston_log("compositor: executing '%s' failed: %m\n",
-			path);
-}
-
-WL_EXPORT struct wl_client *
-weston_client_launch(struct weston_compositor *compositor,
-		     struct weston_process *proc,
-		     const char *path,
-		     weston_process_cleanup_func_t cleanup)
-{
-	int sv[2];
-	pid_t pid;
-	struct wl_client *client;
-
-	weston_log("launching '%s'\n", path);
-
-	if (os_socketpair_cloexec(AF_UNIX, SOCK_STREAM, 0, sv) < 0) {
-		weston_log("weston_client_launch: "
-			"socketpair failed while launching '%s': %m\n",
-			path);
-		return NULL;
-	}
-
-	pid = fork();
-	if (pid == -1) {
-		close(sv[0]);
-		close(sv[1]);
-		weston_log("weston_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]);
-		weston_log("weston_client_launch: "
-			"wl_client_create failed while launching '%s'.\n",
-			path);
-		return NULL;
-	}
-
-	proc->pid = pid;
-	proc->cleanup = cleanup;
-	weston_watch_process(proc);
-
-	return client;
-}
-
 static void
 region_init_infinite(pixman_region32_t *region)
 {
@@ -3685,17 +3560,6 @@ compositor_bind(struct wl_client *client,
 				       compositor, NULL);
 }
 
-static void
-log_uname(void)
-{
-	struct utsname usys;
-
-	uname(&usys);
-
-	weston_log("OS: %s, %s, %s, %s\n", usys.sysname, usys.release,
-						usys.version, usys.machine);
-}
-
 WL_EXPORT int
 weston_environment_get_fd(const char *env)
 {
@@ -3719,17 +3583,35 @@ weston_environment_get_fd(const char *env)
 	return fd;
 }
 
+static const struct {
+	uint32_t bit; /* enum weston_capability */
+	const char *desc;
+} capability_strings[] = {
+	{ WESTON_CAP_ROTATION_ANY, "arbitrary surface rotation:" },
+	{ WESTON_CAP_CAPTURE_YFLIP, "screen capture uses y-flip:" },
+};
+
+static void
+weston_compositor_log_capabilities(struct weston_compositor *compositor)
+{
+	unsigned i;
+	int yes;
+
+	weston_log("Compositor capabilities:\n");
+	for (i = 0; i < ARRAY_LENGTH(capability_strings); i++) {
+		yes = compositor->capabilities & capability_strings[i].bit;
+		weston_log_continue(STAMP_SPACE "%s %s\n",
+				    capability_strings[i].desc,
+				    yes ? "yes" : "no");
+	}
+}
+
 WL_EXPORT int
 weston_compositor_init(struct weston_compositor *ec,
-		       struct wl_display *display,
-		       int *argc, char *argv[],
-		       struct weston_config *config)
+		       struct wl_display *display)
 {
 	struct wl_event_loop *loop;
-	struct xkb_rule_names xkb_names;
-	struct weston_config_section *s;
 
-	ec->config = config;
 	ec->wl_display = display;
 	wl_signal_init(&ec->destroy_signal);
 	wl_signal_init(&ec->create_surface_signal);
@@ -3777,26 +3659,6 @@ weston_compositor_init(struct weston_compositor *ec,
 	weston_plane_init(&ec->primary_plane, ec, 0, 0);
 	weston_compositor_stack_plane(ec, &ec->primary_plane, NULL);
 
-	s = weston_config_get_section(ec->config, "keyboard", NULL, NULL);
-	weston_config_section_get_string(s, "keymap_rules",
-					 (char **) &xkb_names.rules, NULL);
-	weston_config_section_get_string(s, "keymap_model",
-					 (char **) &xkb_names.model, NULL);
-	weston_config_section_get_string(s, "keymap_layout",
-					 (char **) &xkb_names.layout, NULL);
-	weston_config_section_get_string(s, "keymap_variant",
-					 (char **) &xkb_names.variant, NULL);
-	weston_config_section_get_string(s, "keymap_options",
-					 (char **) &xkb_names.options, NULL);
-
-	if (weston_compositor_xkb_init(ec, &xkb_names) < 0)
-		return -1;
-
-	weston_config_section_get_int(s, "repeat-rate",
-				      &ec->kb_repeat_rate, 40);
-	weston_config_section_get_int(s, "repeat-delay",
-				      &ec->kb_repeat_delay, 400);
-
 	text_backend_init(ec);
 
 	wl_data_device_manager_init(ec->wl_display);
@@ -3808,6 +3670,9 @@ weston_compositor_init(struct weston_compositor *ec,
 	wl_event_source_timer_update(ec->idle_source, ec->idle_time * 1000);
 
 	ec->input_loop = wl_event_loop_create();
+	ec->default_pointer_grab = NULL;
+
+	weston_compositor_log_capabilities(ec);
 
 	weston_layer_init(&ec->fade_layer, &ec->layer_list);
 	weston_layer_init(&ec->cursor_layer, &ec->fade_layer.link);
@@ -3842,8 +3707,6 @@ weston_compositor_shutdown(struct weston_compositor *ec)
 	weston_plane_release(&ec->primary_plane);
 
 	wl_event_loop_destroy(ec->input_loop);
-
-	weston_config_destroy(ec->config);
 }
 
 WL_EXPORT void
@@ -3869,138 +3732,7 @@ weston_version(int *major, int *minor, int *micro)
 	*micro = WESTON_VERSION_MICRO;
 }
 
-static const struct {
-	uint32_t bit; /* enum weston_capability */
-	const char *desc;
-} capability_strings[] = {
-	{ WESTON_CAP_ROTATION_ANY, "arbitrary surface rotation:" },
-	{ WESTON_CAP_CAPTURE_YFLIP, "screen capture uses y-flip:" },
-};
-
-static void
-weston_compositor_log_capabilities(struct weston_compositor *compositor)
-{
-	unsigned i;
-	int yes;
-
-	weston_log("Compositor capabilities:\n");
-	for (i = 0; i < ARRAY_LENGTH(capability_strings); i++) {
-		yes = compositor->capabilities & capability_strings[i].bit;
-		weston_log_continue(STAMP_SPACE "%s %s\n",
-				    capability_strings[i].desc,
-				    yes ? "yes" : "no");
-	}
-}
-
-static int on_term_signal(int signal_number, void *data)
-{
-	struct wl_display *display = data;
-
-	weston_log("caught signal %d\n", signal_number);
-	wl_display_terminate(display);
-
-	return 1;
-}
-
-#ifdef HAVE_LIBUNWIND
-
-static void
-print_backtrace(void)
-{
-	unw_cursor_t cursor;
-	unw_context_t context;
-	unw_word_t off;
-	unw_proc_info_t pip;
-	int ret, i = 0;
-	char procname[256];
-	const char *filename;
-	Dl_info dlinfo;
-
-	pip.unwind_info = NULL;
-	ret = unw_getcontext(&context);
-	if (ret) {
-		weston_log("unw_getcontext: %d\n", ret);
-		return;
-	}
-
-	ret = unw_init_local(&cursor, &context);
-	if (ret) {
-		weston_log("unw_init_local: %d\n", ret);
-		return;
-	}
-
-	ret = unw_step(&cursor);
-	while (ret > 0) {
-		ret = unw_get_proc_info(&cursor, &pip);
-		if (ret) {
-			weston_log("unw_get_proc_info: %d\n", ret);
-			break;
-		}
-
-		ret = unw_get_proc_name(&cursor, procname, 256, &off);
-		if (ret && ret != -UNW_ENOMEM) {
-			if (ret != -UNW_EUNSPEC)
-				weston_log("unw_get_proc_name: %d\n", ret);
-			procname[0] = '?';
-			procname[1] = 0;
-		}
-
-		if (dladdr((void *)(pip.start_ip + off), &dlinfo) && dlinfo.dli_fname &&
-		    *dlinfo.dli_fname)
-			filename = dlinfo.dli_fname;
-		else
-			filename = "?";
-
-		weston_log("%u: %s (%s%s+0x%x) [%p]\n", i++, filename, procname,
-			   ret == -UNW_ENOMEM ? "..." : "", (int)off, (void *)(pip.start_ip + off));
-
-		ret = unw_step(&cursor);
-		if (ret < 0)
-			weston_log("unw_step: %d\n", ret);
-	}
-}
-
-#else
-
-static void
-print_backtrace(void)
-{
-	void *buffer[32];
-	int i, count;
-	Dl_info info;
-
-	count = backtrace(buffer, ARRAY_LENGTH(buffer));
-	for (i = 0; i < count; i++) {
-		dladdr(buffer[i], &info);
-		weston_log("  [%016lx]  %s  (%s)\n",
-			(long) buffer[i],
-			info.dli_sname ? info.dli_sname : "--",
-			info.dli_fname);
-	}
-}
-
-#endif
-
-static void
-on_caught_signal(int s, siginfo_t *siginfo, void *context)
-{
-	/* This signal handler will do a best-effort backtrace, and
-	 * then call the backend restore function, which will switch
-	 * back to the vt we launched from or ungrab X etc and then
-	 * raise SIGTRAP.  If we run weston under gdb from X or a
-	 * different vt, and tell gdb "handle *s* nostop", this
-	 * will allow weston to switch back to gdb on crash and then
-	 * gdb will catch the crash with SIGTRAP.*/
-
-	weston_log("caught signal: %d\n", s);
-
-	print_backtrace();
-
-	segv_compositor->restore(segv_compositor);
-
-	raise(SIGTRAP);
-}
-
+// TODO: unexport this one?
 WL_EXPORT void *
 weston_load_module(const char *name, const char *entrypoint)
 {
@@ -4039,387 +3771,15 @@ weston_load_module(const char *name, const char *entrypoint)
 	return init;
 }
 
-static int
-load_modules(struct weston_compositor *ec, const char *modules,
-	     int *argc, char *argv[])
-{
-	const char *p, *end;
-	char buffer[256];
-	int (*module_init)(struct weston_compositor *ec,
-			   int *argc, char *argv[]);
-
-	if (modules == NULL)
-		return 0;
-
-	p = modules;
-	while (*p) {
-		end = strchrnul(p, ',');
-		snprintf(buffer, sizeof buffer, "%.*s", (int) (end - p), p);
-		module_init = weston_load_module(buffer, "module_init");
-		if (module_init)
-			module_init(ec, argc, argv);
-		p = end;
-		while (*p == ',')
-			p++;
-
-	}
-
-	return 0;
-}
-
-static const char xdg_error_message[] =
-	"fatal: environment variable XDG_RUNTIME_DIR is not set.\n";
-
-static const char xdg_wrong_message[] =
-	"fatal: environment variable XDG_RUNTIME_DIR\n"
-	"is set to \"%s\", which is not a directory.\n";
-
-static const char xdg_wrong_mode_message[] =
-	"warning: XDG_RUNTIME_DIR \"%s\" is not configured\n"
-	"correctly.  Unix access mode must be 0700 (current mode is %o),\n"
-	"and must be owned by the user (current owner is UID %d).\n";
-
-static const char xdg_detail_message[] =
-	"Refer to your distribution on how to get it, or\n"
-	"http://www.freedesktop.org/wiki/Specifications/basedir-spec\n"
-	"on how to implement it.\n";
-
-static void
-verify_xdg_runtime_dir(void)
-{
-	char *dir = getenv("XDG_RUNTIME_DIR");
-	struct stat s;
-
-	if (!dir) {
-		weston_log(xdg_error_message);
-		weston_log_continue(xdg_detail_message);
-		exit(EXIT_FAILURE);
-	}
-
-	if (stat(dir, &s) || !S_ISDIR(s.st_mode)) {
-		weston_log(xdg_wrong_message, dir);
-		weston_log_continue(xdg_detail_message);
-		exit(EXIT_FAILURE);
-	}
-
-	if ((s.st_mode & 0777) != 0700 || s.st_uid != getuid()) {
-		weston_log(xdg_wrong_mode_message,
-			   dir, s.st_mode & 0777, s.st_uid);
-		weston_log_continue(xdg_detail_message);
-	}
-}
-
-static int
-usage(int error_code)
-{
-	fprintf(stderr,
-		"Usage: weston [OPTIONS]\n\n"
-		"This is weston version " VERSION ", the Wayland reference compositor.\n"
-		"Weston supports multiple backends, and depending on which backend is in use\n"
-		"different options will be accepted.\n\n"
-
-
-		"Core options:\n\n"
-		"  --version\t\tPrint weston version\n"
-		"  -B, --backend=MODULE\tBackend module, one of drm-backend.so,\n"
-		"\t\t\t\tfbdev-backend.so, x11-backend.so or\n"
-		"\t\t\t\twayland-backend.so\n"
-		"  --shell=MODULE\tShell module, defaults to desktop-shell.so\n"
-		"  -S, --socket=NAME\tName of socket to listen on\n"
-		"  -i, --idle-time=SECS\tIdle time in seconds\n"
-		"  --modules\t\tLoad the comma-separated list of modules\n"
-		"  --log==FILE\t\tLog to the given file\n"
-		"  --no-config\t\tDo not read weston.ini\n"
-		"  -h, --help\t\tThis help message\n\n");
-
-	fprintf(stderr,
-		"Options for drm-backend.so:\n\n"
-		"  --connector=ID\tBring up only this connector\n"
-		"  --seat=SEAT\t\tThe seat that weston should run on\n"
-		"  --tty=TTY\t\tThe tty to use\n"
-		"  --use-pixman\t\tUse the pixman (CPU) renderer\n"
-		"  --current-mode\tPrefer current KMS mode over EDID preferred mode\n\n");
-
-	fprintf(stderr,
-		"Options for fbdev-backend.so:\n\n"
-		"  --tty=TTY\t\tThe tty to use\n"
-		"  --device=DEVICE\tThe framebuffer device to use\n\n");
-
-	fprintf(stderr,
-		"Options for x11-backend.so:\n\n"
-		"  --width=WIDTH\t\tWidth of X window\n"
-		"  --height=HEIGHT\tHeight of X window\n"
-		"  --fullscreen\t\tRun in fullscreen mode\n"
-		"  --use-pixman\t\tUse the pixman (CPU) renderer\n"
-		"  --output-count=COUNT\tCreate multiple outputs\n"
-		"  --no-input\t\tDont create input devices\n\n");
-
-	fprintf(stderr,
-		"Options for wayland-backend.so:\n\n"
-		"  --width=WIDTH\t\tWidth of Wayland surface\n"
-		"  --height=HEIGHT\tHeight of Wayland surface\n"
-		"  --scale=SCALE\tScale factor of ouput\n"
-		"  --fullscreen\t\tRun in fullscreen mode\n"
-		"  --use-pixman\t\tUse the pixman (CPU) renderer\n"
-		"  --output-count=COUNT\tCreate multiple outputs\n"
-		"  --sprawl\t\tCreate one fullscreen output for every parent output\n"
-		"  --display=DISPLAY\tWayland display to connect to\n\n");
-
-#if defined(BUILD_RPI_COMPOSITOR) && defined(HAVE_BCM_HOST)
-	fprintf(stderr,
-		"Options for rpi-backend.so:\n\n"
-		"  --tty=TTY\t\tThe tty to use\n"
-		"  --single-buffer\tUse single-buffered Dispmanx elements.\n"
-		"  --transform=TR\tThe output transformation, TR is one of:\n"
-		"\tnormal 90 180 270 flipped flipped-90 flipped-180 flipped-270\n"
-		"  --opaque-regions\tEnable support for opaque regions, can be "
-		"very slow without support in the GPU firmware.\n"
-		"\n");
-#endif
-
-#if defined(BUILD_RDP_COMPOSITOR)
-    fprintf(stderr,
-       "Options for rdp-backend.so:\n\n"
-       "  --width=WIDTH\t\tWidth of desktop\n"
-       "  --height=HEIGHT\tHeight of desktop\n"
-       "  --env-socket=SOCKET\tUse that socket as peer connection\n"
-       "  --address=ADDR\tThe address to bind\n"
-       "  --port=PORT\tThe port to listen on\n"
-       "  --no-clients-resize\tThe RDP peers will be forced to the size of the desktop\n"
-       "  --rdp4-key=FILE\tThe file containing the key for RDP4 encryption\n"
-       "  --rdp-tls-cert=FILE\tThe file containing the certificate for TLS encryption\n"
-       "  --rdp-tls-key=FILE\tThe file containing the private key for TLS encryption\n"
-       "\n");
-#endif
-
-	exit(error_code);
-}
-
-static void
-catch_signals(void)
-{
-	struct sigaction action;
-
-	action.sa_flags = SA_SIGINFO | SA_RESETHAND;
-	action.sa_sigaction = on_caught_signal;
-	sigemptyset(&action.sa_mask);
-	sigaction(SIGSEGV, &action, NULL);
-	sigaction(SIGABRT, &action, NULL);
-}
-
-static void
-handle_primary_client_destroyed(struct wl_listener *listener, void *data)
+WL_EXPORT void
+weston_compositor_set_idle_time(struct weston_compositor *ec, int idle_time)
 {
-	struct wl_client *client = data;
-
-	weston_log("Primary client died.  Closing...\n");
-
-	wl_display_terminate(wl_client_get_display(client));
+	ec->idle_time = idle_time;
 }
 
-int main(int argc, char *argv[])
+WL_EXPORT void
+weston_compositor_destroy(struct weston_compositor *ec)
 {
-	int ret = EXIT_SUCCESS;
-	struct wl_display *display;
-	struct weston_compositor *ec;
-	struct wl_event_source *signals[4];
-	struct wl_event_loop *loop;
-	struct weston_compositor
-		*(*backend_init)(struct wl_display *display,
-				 int *argc, char *argv[],
-				 struct weston_config *config);
-	int i, fd;
-	char *backend = NULL;
-	char *option_backend = NULL;
-	char *shell = NULL;
-	char *option_shell = NULL;
-	char *modules, *option_modules = NULL;
-	char *log = NULL;
-	char *server_socket = NULL, *end;
-	int32_t idle_time = 300;
-	int32_t help = 0;
-	const char *socket_name = NULL;
-	int32_t version = 0;
-	int32_t noconfig = 0;
-	struct weston_config *config = NULL;
-	struct weston_config_section *section;
-	struct wl_client *primary_client;
-	struct wl_listener primary_client_destroyed;
-
-	const struct weston_option core_options[] = {
-		{ WESTON_OPTION_STRING, "backend", 'B', &option_backend },
-		{ WESTON_OPTION_STRING, "shell", 0, &option_shell },
-		{ WESTON_OPTION_STRING, "socket", 'S', &socket_name },
-		{ WESTON_OPTION_INTEGER, "idle-time", 'i', &idle_time },
-		{ WESTON_OPTION_STRING, "modules", 0, &option_modules },
-		{ WESTON_OPTION_STRING, "log", 0, &log },
-		{ WESTON_OPTION_BOOLEAN, "help", 'h', &help },
-		{ WESTON_OPTION_BOOLEAN, "version", 0, &version },
-		{ WESTON_OPTION_BOOLEAN, "no-config", 0, &noconfig },
-	};
-
-	parse_options(core_options, ARRAY_LENGTH(core_options), &argc, argv);
-
-	if (help)
-		usage(EXIT_SUCCESS);
-
-	if (version) {
-		printf(PACKAGE_STRING "\n");
-		return EXIT_SUCCESS;
-	}
-
-	weston_log_file_open(log);
-
-	weston_log("%s\n"
-		   STAMP_SPACE "%s\n"
-		   STAMP_SPACE "Bug reports to: %s\n"
-		   STAMP_SPACE "Build: %s\n",
-		   PACKAGE_STRING, PACKAGE_URL, PACKAGE_BUGREPORT,
-		   BUILD_ID);
-	log_uname();
-
-	verify_xdg_runtime_dir();
-
-	display = wl_display_create();
-
-	loop = wl_display_get_event_loop(display);
-	signals[0] = wl_event_loop_add_signal(loop, SIGTERM, on_term_signal,
-					      display);
-	signals[1] = wl_event_loop_add_signal(loop, SIGINT, on_term_signal,
-					      display);
-	signals[2] = wl_event_loop_add_signal(loop, SIGQUIT, on_term_signal,
-					      display);
-
-	wl_list_init(&child_process_list);
-	signals[3] = wl_event_loop_add_signal(loop, SIGCHLD, sigchld_handler,
-					      NULL);
-
-	if (!signals[0] || !signals[1] || !signals[2] || !signals[3]) {
-		ret = EXIT_FAILURE;
-		goto out_signals;
-	}
-
-	if (noconfig == 0)
-		config = weston_config_parse("weston.ini");
-	if (config != NULL) {
-		weston_log("Using config file '%s'\n",
-			   weston_config_get_full_path(config));
-	} else {
-		weston_log("Starting with no config file.\n");
-	}
-	section = weston_config_get_section(config, "core", NULL, NULL);
-
-	if (option_backend)
-		backend = strdup(option_backend);
-	else
-		weston_config_section_get_string(section, "backend", &backend,
-						 NULL);
-
-	if (!backend) {
-		if (getenv("WAYLAND_DISPLAY") || getenv("WAYLAND_SOCKET"))
-			backend = strdup("wayland-backend.so");
-		else if (getenv("DISPLAY"))
-			backend = strdup("x11-backend.so");
-		else
-			backend = strdup(WESTON_NATIVE_BACKEND);
-	}
-
-	backend_init = weston_load_module(backend, "backend_init");
-	free(backend);
-	if (!backend_init) {
-		ret = EXIT_FAILURE;
-		goto out_signals;
-	}
-
-	ec = backend_init(display, &argc, argv, config);
-	if (ec == NULL) {
-		weston_log("fatal: failed to create compositor\n");
-		ret = EXIT_FAILURE;
-		goto out_signals;
-	}
-
-	catch_signals();
-	segv_compositor = ec;
-
-	ec->idle_time = idle_time;
-	ec->default_pointer_grab = NULL;
-
-	for (i = 1; i < argc; i++)
-		weston_log("fatal: unhandled option: %s\n", argv[i]);
-	if (argc > 1) {
-		ret = EXIT_FAILURE;
-		goto out;
-	}
-
-	weston_compositor_log_capabilities(ec);
-
-	server_socket = getenv("WAYLAND_SERVER_SOCKET");
-	if (server_socket) {
-		weston_log("Running with single client\n");
-		fd = strtol(server_socket, &end, 0);
-		if (*end != '\0')
-			fd = -1;
-	} else {
-		fd = -1;
-	}
-
-	if (fd != -1) {
-		primary_client = wl_client_create(display, fd);
-		if (!primary_client) {
-			weston_log("fatal: failed to add client: %m\n");
-			ret = EXIT_FAILURE;
-			goto out;
-		}
-		primary_client_destroyed.notify =
-			handle_primary_client_destroyed;
-		wl_client_add_destroy_listener(primary_client,
-					       &primary_client_destroyed);
-	} else {
-		if (socket_name) {
-			if (wl_display_add_socket(display, socket_name)) {
-				weston_log("fatal: failed to add socket: %m\n");
-				ret = EXIT_FAILURE;
-				goto out;
-			}
-		} else {
-			socket_name = wl_display_add_socket_auto(display);
-			if (!socket_name) {
-				weston_log("fatal: failed to add socket: %m\n");
-				ret = EXIT_FAILURE;
-				goto out;
-			}
-		}
-
-		setenv("WAYLAND_DISPLAY", socket_name, 1);
-	}
-
-	if (option_shell)
-		shell = strdup(option_shell);
-	else
-		weston_config_section_get_string(section, "shell", &shell,
-						 "desktop-shell.so");
-
-	if (load_modules(ec, shell, &argc, argv) < 0) {
-		free(shell);
-		goto out;
-	}
-	free(shell);
-
-	weston_config_section_get_string(section, "modules", &modules, "");
-	if (load_modules(ec, modules, &argc, argv) < 0) {
-		free(modules);
-		goto out;
-	}
-	free(modules);
-
-	if (load_modules(ec, option_modules, &argc, argv) < 0)
-		goto out;
-
-	weston_compositor_wake(ec);
-
-	wl_display_run(display);
-
- out:
 	/* prevent further rendering while shutting down */
 	ec->state = WESTON_COMPOSITOR_OFFSCREEN;
 
@@ -4428,15 +3788,4 @@ int main(int argc, char *argv[])
 	weston_compositor_xkb_destroy(ec);
 
 	ec->destroy(ec);
-
-out_signals:
-	for (i = ARRAY_LENGTH(signals) - 1; i >= 0; i--)
-		if (signals[i])
-			wl_event_source_remove(signals[i]);
-
-	wl_display_destroy(display);
-
-	weston_log_file_close();
-
-	return ret;
 }
diff --git a/src/compositor.h b/libweston/compositor.h
similarity index 98%
rename from src/compositor.h
rename to libweston/compositor.h
index c0fc0a6..617ef00 100644
--- a/src/compositor.h
+++ b/libweston/compositor.h
@@ -579,7 +579,6 @@ struct weston_compositor {
 
 	struct wl_display *wl_display;
 	struct weston_shell_interface shell_interface;
-	struct weston_config *config;
 
 	/* surface signals */
 	struct wl_signal create_surface_signal;
@@ -638,6 +637,7 @@ struct weston_compositor {
 	void (*destroy)(struct weston_compositor *ec);
 	void (*restore)(struct weston_compositor *ec);
 	int (*authenticate)(struct weston_compositor *c, uint32_t id);
+	int (*setup)(struct weston_compositor *c);
 
 	struct weston_launcher *launcher;
 
@@ -1059,6 +1059,8 @@ weston_compositor_pick_view(struct weston_compositor *compositor,
 			    wl_fixed_t x, wl_fixed_t y,
 			    wl_fixed_t *sx, wl_fixed_t *sy);
 
+void
+weston_compositor_destroy(struct weston_compositor *compositor);
 
 struct weston_binding;
 typedef void (*weston_key_binding_handler_t)(struct weston_seat *seat,
@@ -1152,6 +1154,9 @@ weston_compositor_run_debug_binding(struct weston_compositor *compositor,
 void
 weston_compositor_set_default_pointer_grab(struct weston_compositor *compositor,
 			const struct weston_pointer_grab_interface *interface);
+void
+weston_compositor_set_idle_time(struct weston_compositor *compositor,
+                                int idle_time);
 
 int
 weston_environment_get_fd(const char *env);
@@ -1221,8 +1226,7 @@ uint32_t
 weston_compositor_get_time(void);
 
 int
-weston_compositor_init(struct weston_compositor *ec, struct wl_display *display,
-		       int *argc, char *argv[], struct weston_config *config);
+weston_compositor_init(struct weston_compositor *ec, struct wl_display *display);
 void
 weston_compositor_shutdown(struct weston_compositor *ec);
 void
@@ -1276,10 +1280,6 @@ weston_compositor_xkb_destroy(struct weston_compositor *ec);
 /* String literal of spaces, the same width as the timestamp. */
 #define STAMP_SPACE "               "
 
-void
-weston_log_file_open(const char *filename);
-void
-weston_log_file_close(void);
 int
 weston_vlog(const char *fmt, va_list ap);
 int
@@ -1326,9 +1326,6 @@ weston_screenshooter_shoot(struct weston_output *output, struct weston_buffer *b
 struct clipboard *
 clipboard_create(struct weston_seat *seat);
 
-int
-text_backend_init(struct weston_compositor *ec);
-
 struct weston_process;
 typedef void (*weston_process_cleanup_func_t)(struct weston_process *process,
 					    int status);
@@ -1394,14 +1391,6 @@ weston_output_switch_mode(struct weston_output *output, struct weston_mode *mode
 int
 noop_renderer_init(struct weston_compositor *ec);
 
-struct weston_compositor *
-backend_init(struct wl_display *display, int *argc, char *argv[],
-	     struct weston_config *config);
-
-int
-module_init(struct weston_compositor *compositor,
-	    int *argc, char *argv[]);
-
 void
 weston_transformed_coord(int width, int height,
 			 enum wl_output_transform transform,
diff --git a/src/data-device.c b/libweston/data-device.c
similarity index 100%
rename from src/data-device.c
rename to libweston/data-device.c
diff --git a/src/gl-renderer.c b/libweston/gl-renderer.c
similarity index 100%
rename from src/gl-renderer.c
rename to libweston/gl-renderer.c
diff --git a/src/gl-renderer.h b/libweston/gl-renderer.h
similarity index 100%
rename from src/gl-renderer.h
rename to libweston/gl-renderer.h
diff --git a/src/input.c b/libweston/input.c
similarity index 99%
rename from src/input.c
rename to libweston/input.c
index 1ab55ce..d7c550b 100644
--- a/src/input.c
+++ b/libweston/input.c
@@ -1837,7 +1837,7 @@ bind_seat(struct wl_client *client, void *data, uint32_t version, uint32_t id)
 }
 
 #ifdef ENABLE_XKBCOMMON
-int
+WL_EXPORT int
 weston_compositor_xkb_init(struct weston_compositor *ec,
 			   struct xkb_rule_names *names)
 {
diff --git a/src/noop-renderer.c b/libweston/noop-renderer.c
similarity index 100%
rename from src/noop-renderer.c
rename to libweston/noop-renderer.c
diff --git a/src/pixman-renderer.c b/libweston/pixman-renderer.c
similarity index 100%
rename from src/pixman-renderer.c
rename to libweston/pixman-renderer.c
diff --git a/src/pixman-renderer.h b/libweston/pixman-renderer.h
similarity index 100%
rename from src/pixman-renderer.h
rename to libweston/pixman-renderer.h
diff --git a/src/rpi-bcm-stubs.h b/libweston/rpi-bcm-stubs.h
similarity index 100%
rename from src/rpi-bcm-stubs.h
rename to libweston/rpi-bcm-stubs.h
diff --git a/src/rpi-renderer.c b/libweston/rpi-renderer.c
similarity index 100%
rename from src/rpi-renderer.c
rename to libweston/rpi-renderer.c
diff --git a/src/rpi-renderer.h b/libweston/rpi-renderer.h
similarity index 100%
rename from src/rpi-renderer.h
rename to libweston/rpi-renderer.h
diff --git a/src/screenshooter.c b/libweston/screenshooter.c
similarity index 100%
rename from src/screenshooter.c
rename to libweston/screenshooter.c
diff --git a/src/vertex-clipping.c b/libweston/vertex-clipping.c
similarity index 100%
rename from src/vertex-clipping.c
rename to libweston/vertex-clipping.c
diff --git a/src/vertex-clipping.h b/libweston/vertex-clipping.h
similarity index 100%
rename from src/vertex-clipping.h
rename to libweston/vertex-clipping.h
diff --git a/src/weston-egl-ext.h b/libweston/weston-egl-ext.h
similarity index 100%
rename from src/weston-egl-ext.h
rename to libweston/weston-egl-ext.h
diff --git a/src/zoom.c b/libweston/zoom.c
similarity index 100%
rename from src/zoom.c
rename to libweston/zoom.c
diff --git a/src/cms-colord.c b/src/cms-colord.c
index 4ff3aac..c4adf0c 100644
--- a/src/cms-colord.c
+++ b/src/cms-colord.c
@@ -33,6 +33,7 @@
 
 #include "compositor.h"
 #include "cms-helper.h"
+#include "weston.h"
 
 struct cms_colord {
 	struct weston_compositor	*ec;
@@ -483,7 +484,7 @@ colord_cms_output_destroy(gpointer data)
 
 WL_EXPORT int
 module_init(struct weston_compositor *ec,
-	    int *argc, char *argv[])
+	    int *argc, char *argv[], struct weston_config *config)
 {
 	gboolean ret;
 	GError *error = NULL;
diff --git a/src/cms-static.c b/src/cms-static.c
index ad54fd1..4b306e2 100644
--- a/src/cms-static.c
+++ b/src/cms-static.c
@@ -27,9 +27,11 @@
 
 #include "compositor.h"
 #include "cms-helper.h"
+#include "weston.h"
 
 struct cms_static {
 	struct weston_compositor	*ec;
+	struct weston_config		*config;
 	struct wl_listener		 destroy_listener;
 	struct wl_listener		 output_created_listener;
 };
@@ -45,7 +47,7 @@ cms_output_created(struct cms_static *cms, struct weston_output *o)
 
 	if (o->name == NULL)
 		return;
-	s = weston_config_get_section(cms->ec->config,
+	s = weston_config_get_section(cms->config,
 				      "output", "name", o->name);
 	if (s == NULL)
 		return;
@@ -86,7 +88,7 @@ cms_notifier_destroy(struct wl_listener *listener, void *data)
 
 WL_EXPORT int
 module_init(struct weston_compositor *ec,
-	    int *argc, char *argv[])
+	    int *argc, char *argv[], struct weston_config *config)
 {
 	struct cms_static *cms;
 	struct weston_output *output;
@@ -99,6 +101,7 @@ module_init(struct weston_compositor *ec,
 		return -1;
 
 	cms->ec = ec;
+	cms->config = config;
 	cms->destroy_listener.notify = cms_notifier_destroy;
 	wl_signal_add(&ec->destroy_signal, &cms->destroy_listener);
 
diff --git a/src/log.c b/src/log.c
index 99bbe18..40c6558 100644
--- a/src/log.c
+++ b/src/log.c
@@ -32,6 +32,7 @@
 #include <wayland-util.h>
 
 #include "compositor.h"
+#include "weston.h"
 
 static FILE *weston_logfile = NULL;
 
diff --git a/src/text-backend.c b/src/text-backend.c
index 1d549d4..67ddad1 100644
--- a/src/text-backend.c
+++ b/src/text-backend.c
@@ -31,6 +31,7 @@
 #include "compositor.h"
 #include "text-server-protocol.h"
 #include "input-method-server-protocol.h"
+#include "weston.h"
 
 struct input_method;
 struct input_method_context;
@@ -934,11 +935,12 @@ handle_seat_created(struct wl_listener *listener,
 }
 
 static void
-text_backend_configuration(struct text_backend *text_backend)
+text_backend_configuration(struct text_backend *text_backend,
+                           struct weston_config *config)
 {
 	struct weston_config_section *section;
 
-	section = weston_config_get_section(text_backend->compositor->config,
+	section = weston_config_get_section(config,
 					    "input-method", NULL, NULL);
 	weston_config_section_get_string(section, "path",
 					 &text_backend->input_method.path,
@@ -961,7 +963,7 @@ text_backend_notifier_destroy(struct wl_listener *listener, void *data)
 
 
 WL_EXPORT int
-text_backend_init(struct weston_compositor *ec)
+text_backend_init(struct weston_compositor *ec, struct weston_config *config)
 {
 	struct text_backend *text_backend;
 
@@ -976,7 +978,7 @@ text_backend_init(struct weston_compositor *ec)
 	text_backend->destroy_listener.notify = text_backend_notifier_destroy;
 	wl_signal_add(&ec->destroy_signal, &text_backend->destroy_listener);
 
-	text_backend_configuration(text_backend);
+	text_backend_configuration(text_backend, config);
 
 	text_input_manager_create(ec);
 
diff --git a/src/weston.c b/src/weston.c
new file mode 100644
index 0000000..4f0c021
--- /dev/null
+++ b/src/weston.c
@@ -0,0 +1,763 @@
+/*
+ * Copyright © 2008-2011 Kristian Høgsberg
+ * Copyright © 2012 Collabora, Ltd.
+ *
+ * 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 <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <limits.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/wait.h>
+#include <sys/socket.h>
+#include <sys/utsname.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <math.h>
+#include <linux/input.h>
+#include <dlfcn.h>
+#include <signal.h>
+#include <setjmp.h>
+#include <sys/time.h>
+#include <time.h>
+
+#ifdef HAVE_LIBUNWIND
+#define UNW_LOCAL_ONLY
+#include <libunwind.h>
+#endif
+
+#include "weston.h"
+#include "compositor.h"
+#include "git-version.h"
+#include "version.h"
+#include "../shared/os-compatibility.h"
+
+static struct weston_compositor *segv_compositor;
+static struct wl_list child_process_list;
+
+static void
+log_uname(void)
+{
+	struct utsname usys;
+
+	uname(&usys);
+
+	weston_log("OS: %s, %s, %s, %s\n", usys.sysname, usys.release,
+						usys.version, usys.machine);
+}
+
+#ifdef HAVE_LIBUNWIND
+
+static void
+print_backtrace(void)
+{
+	unw_cursor_t cursor;
+	unw_context_t context;
+	unw_word_t off;
+	unw_proc_info_t pip;
+	int ret, i = 0;
+	char procname[256];
+	const char *filename;
+	Dl_info dlinfo;
+
+	pip.unwind_info = NULL;
+	ret = unw_getcontext(&context);
+	if (ret) {
+		weston_log("unw_getcontext: %d\n", ret);
+		return;
+	}
+
+	ret = unw_init_local(&cursor, &context);
+	if (ret) {
+		weston_log("unw_init_local: %d\n", ret);
+		return;
+	}
+
+	ret = unw_step(&cursor);
+	while (ret > 0) {
+		ret = unw_get_proc_info(&cursor, &pip);
+		if (ret) {
+			weston_log("unw_get_proc_info: %d\n", ret);
+			break;
+		}
+
+		ret = unw_get_proc_name(&cursor, procname, 256, &off);
+		if (ret && ret != -UNW_ENOMEM) {
+			if (ret != -UNW_EUNSPEC)
+				weston_log("unw_get_proc_name: %d\n", ret);
+			procname[0] = '?';
+			procname[1] = 0;
+		}
+
+		if (dladdr((void *)(pip.start_ip + off), &dlinfo) && dlinfo.dli_fname &&
+		    *dlinfo.dli_fname)
+			filename = dlinfo.dli_fname;
+		else
+			filename = "?";
+
+		weston_log("%u: %s (%s%s+0x%x) [%p]\n", i++, filename, procname,
+			   ret == -UNW_ENOMEM ? "..." : "", (int)off, (void *)(pip.start_ip + off));
+
+		ret = unw_step(&cursor);
+		if (ret < 0)
+			weston_log("unw_step: %d\n", ret);
+	}
+}
+
+#else
+
+static void
+print_backtrace(void)
+{
+	void *buffer[32];
+	int i, count;
+	Dl_info info;
+
+	count = backtrace(buffer, ARRAY_LENGTH(buffer));
+	for (i = 0; i < count; i++) {
+		dladdr(buffer[i], &info);
+		weston_log("  [%016lx]  %s  (%s)\n",
+			(long) buffer[i],
+			info.dli_sname ? info.dli_sname : "--",
+			info.dli_fname);
+	}
+}
+
+#endif
+
+static int
+usage(int error_code)
+{
+	fprintf(stderr,
+		"Usage: weston [OPTIONS]\n\n"
+		"This is weston version " VERSION ", the Wayland reference compositor.\n"
+		"Weston supports multiple backends, and depending on which backend is in use\n"
+		"different options will be accepted.\n\n"
+
+
+		"Core options:\n\n"
+		"  --version\t\tPrint weston version\n"
+		"  -B, --backend=MODULE\tBackend module, one of drm-backend.so,\n"
+		"\t\t\t\tfbdev-backend.so, x11-backend.so or\n"
+		"\t\t\t\twayland-backend.so\n"
+		"  -S, --socket=NAME\tName of socket to listen on\n"
+		"  -i, --idle-time=SECS\tIdle time in seconds\n"
+		"  --modules\t\tLoad the comma-separated list of modules\n"
+		"  --log==FILE\t\tLog to the given file\n"
+		"  --no-config\t\tDo not read weston.ini\n"
+		"  -h, --help\t\tThis help message\n\n");
+
+	fprintf(stderr,
+		"Options for drm-backend.so:\n\n"
+		"  --connector=ID\tBring up only this connector\n"
+		"  --seat=SEAT\t\tThe seat that weston should run on\n"
+		"  --tty=TTY\t\tThe tty to use\n"
+		"  --use-pixman\t\tUse the pixman (CPU) renderer\n"
+		"  --current-mode\tPrefer current KMS mode over EDID preferred mode\n\n");
+
+	fprintf(stderr,
+		"Options for fbdev-backend.so:\n\n"
+		"  --tty=TTY\t\tThe tty to use\n"
+		"  --device=DEVICE\tThe framebuffer device to use\n\n");
+
+	fprintf(stderr,
+		"Options for x11-backend.so:\n\n"
+		"  --width=WIDTH\t\tWidth of X window\n"
+		"  --height=HEIGHT\tHeight of X window\n"
+		"  --fullscreen\t\tRun in fullscreen mode\n"
+		"  --use-pixman\t\tUse the pixman (CPU) renderer\n"
+		"  --output-count=COUNT\tCreate multiple outputs\n"
+		"  --no-input\t\tDont create input devices\n\n");
+
+	fprintf(stderr,
+		"Options for wayland-backend.so:\n\n"
+		"  --width=WIDTH\t\tWidth of Wayland surface\n"
+		"  --height=HEIGHT\tHeight of Wayland surface\n"
+		"  --scale=SCALE\tScale factor of ouput\n"
+		"  --fullscreen\t\tRun in fullscreen mode\n"
+		"  --use-pixman\t\tUse the pixman (CPU) renderer\n"
+		"  --output-count=COUNT\tCreate multiple outputs\n"
+		"  --sprawl\t\tCreate one fullscreen output for every parent output\n"
+		"  --display=DISPLAY\tWayland display to connect to\n\n");
+
+#if defined(BUILD_RPI_COMPOSITOR) && defined(HAVE_BCM_HOST)
+	fprintf(stderr,
+		"Options for rpi-backend.so:\n\n"
+		"  --tty=TTY\t\tThe tty to use\n"
+		"  --single-buffer\tUse single-buffered Dispmanx elements.\n"
+		"  --transform=TR\tThe output transformation, TR is one of:\n"
+		"\tnormal 90 180 270 flipped flipped-90 flipped-180 flipped-270\n"
+		"  --opaque-regions\tEnable support for opaque regions, can be "
+		"very slow without support in the GPU firmware.\n"
+		"\n");
+#endif
+
+#if defined(BUILD_RDP_COMPOSITOR)
+    fprintf(stderr,
+       "Options for rdp-backend.so:\n\n"
+       "  --width=WIDTH\t\tWidth of desktop\n"
+       "  --height=HEIGHT\tHeight of desktop\n"
+       "  --env-socket=SOCKET\tUse that socket as peer connection\n"
+       "  --address=ADDR\tThe address to bind\n"
+       "  --port=PORT\tThe port to listen on\n"
+       "  --no-clients-resize\tThe RDP peers will be forced to the size of the desktop\n"
+       "  --rdp4-key=FILE\tThe file containing the key for RDP4 encryption\n"
+       "  --rdp-tls-cert=FILE\tThe file containing the certificate for TLS encryption\n"
+       "  --rdp-tls-key=FILE\tThe file containing the private key for TLS encryption\n"
+       "\n");
+#endif
+
+	exit(error_code);
+}
+
+static int
+load_module(struct weston_compositor *ec, const char *name,
+            int *argc, char *argv[], struct weston_config *config)
+{
+	int (*module_init)(struct weston_compositor *ec,
+			   int *argc, char *argv[],
+			   struct weston_config *config);
+
+	module_init = weston_load_module(name, "module_init");
+	if (module_init) {
+		module_init(ec, argc, argv, config);
+		return 1;
+	}
+
+	return 0;
+}
+
+static int
+load_modules(struct weston_compositor *ec, const char *modules,
+	     int *argc, char *argv[], struct weston_config *config)
+{
+	const char *p, *end;
+	char buffer[256];
+
+	if (modules == NULL)
+		return 0;
+
+	p = modules;
+	while (*p) {
+		end = strchrnul(p, ',');
+		snprintf(buffer, sizeof buffer, "%.*s", (int) (end - p), p);
+		load_module(ec, buffer, argc, argv, config);
+		p = end;
+		while (*p == ',')
+			p++;
+
+	}
+
+	return 0;
+}
+
+static void
+on_caught_signal(int s, siginfo_t *siginfo, void *context)
+{
+	/* This signal handler will do a best-effort backtrace, and
+	 * then call the backend restore function, which will switch
+	 * back to the vt we launched from or ungrab X etc and then
+	 * raise SIGTRAP.  If we run weston under gdb from X or a
+	 * different vt, and tell gdb "handle *s* nostop", this
+	 * will allow weston to switch back to gdb on crash and then
+	 * gdb will catch the crash with SIGTRAP.*/
+
+	weston_log("caught signal: %d\n", s);
+
+	print_backtrace();
+
+	segv_compositor->restore(segv_compositor);
+
+	raise(SIGTRAP);
+}
+
+static void
+catch_signals(void)
+{
+	struct sigaction action;
+
+	action.sa_flags = SA_SIGINFO | SA_RESETHAND;
+	action.sa_sigaction = on_caught_signal;
+	sigemptyset(&action.sa_mask);
+	sigaction(SIGSEGV, &action, NULL);
+	sigaction(SIGABRT, &action, NULL);
+}
+
+static void
+handle_primary_client_destroyed(struct wl_listener *listener, void *data)
+{
+	struct wl_client *client = data;
+
+	weston_log("Primary client died.  Closing...\n");
+
+	wl_display_terminate(wl_client_get_display(client));
+}
+
+static const char xdg_error_message[] =
+	"fatal: environment variable XDG_RUNTIME_DIR is not set.\n";
+
+static const char xdg_wrong_message[] =
+	"fatal: environment variable XDG_RUNTIME_DIR\n"
+	"is set to \"%s\", which is not a directory.\n";
+
+static const char xdg_wrong_mode_message[] =
+	"warning: XDG_RUNTIME_DIR \"%s\" is not configured\n"
+	"correctly.  Unix access mode must be 0700 (current mode is %o),\n"
+	"and must be owned by the user (current owner is UID %d).\n";
+
+static const char xdg_detail_message[] =
+	"Refer to your distribution on how to get it, or\n"
+	"http://www.freedesktop.org/wiki/Specifications/basedir-spec\n"
+	"on how to implement it.\n";
+
+static void
+verify_xdg_runtime_dir(void)
+{
+	char *dir = getenv("XDG_RUNTIME_DIR");
+	struct stat s;
+
+	if (!dir) {
+		weston_log(xdg_error_message);
+		weston_log_continue(xdg_detail_message);
+		exit(EXIT_FAILURE);
+	}
+
+	if (stat(dir, &s) || !S_ISDIR(s.st_mode)) {
+		weston_log(xdg_wrong_message, dir);
+		weston_log_continue(xdg_detail_message);
+		exit(EXIT_FAILURE);
+	}
+
+	if ((s.st_mode & 0777) != 0700 || s.st_uid != getuid()) {
+		weston_log(xdg_wrong_mode_message,
+			   dir, s.st_mode & 0777, s.st_uid);
+		weston_log_continue(xdg_detail_message);
+	}
+}
+
+static int on_term_signal(int signal_number, void *data)
+{
+	struct wl_display *display = data;
+
+	weston_log("caught signal %d\n", signal_number);
+	wl_display_terminate(display);
+
+	return 1;
+}
+
+static int
+sigchld_handler(int signal_number, void *data)
+{
+	struct weston_process *p;
+	int status;
+	pid_t pid;
+
+	pid = waitpid(-1, &status, WNOHANG);
+	if (!pid)
+		return 1;
+
+	wl_list_for_each(p, &child_process_list, link) {
+		if (p->pid == pid)
+			break;
+	}
+
+	if (&p->link == &child_process_list) {
+		weston_log("unknown child process exited\n");
+		return 1;
+	}
+
+	wl_list_remove(&p->link);
+	p->cleanup(p, status);
+
+	return 1;
+}
+
+WL_EXPORT void
+weston_watch_process(struct weston_process *process)
+{
+	wl_list_insert(&child_process_list, &process->link);
+}
+
+static void
+child_client_exec(int sockfd, const char *path)
+{
+	int clientfd;
+	char s[32];
+	sigset_t allsigs;
+
+	/* do not give our signal mask to the new process */
+	sigfillset(&allsigs);
+	sigprocmask(SIG_UNBLOCK, &allsigs, NULL);
+
+	/* Launch clients as the user. Do not lauch clients with wrong euid.*/
+	if (seteuid(getuid()) == -1) {
+		weston_log("compositor: failed seteuid\n");
+		return;
+	}
+
+	/* SOCK_CLOEXEC closes both ends, so we dup the fd to get a
+	 * non-CLOEXEC fd to pass through exec. */
+	clientfd = dup(sockfd);
+	if (clientfd == -1) {
+		weston_log("compositor: dup failed: %m\n");
+		return;
+	}
+
+	snprintf(s, sizeof s, "%d", clientfd);
+	setenv("WAYLAND_SOCKET", s, 1);
+
+	if (execl(path, path, NULL) < 0)
+		weston_log("compositor: executing '%s' failed: %m\n",
+			path);
+}
+
+WL_EXPORT struct wl_client *
+weston_client_launch(struct weston_compositor *compositor,
+		     struct weston_process *proc,
+		     const char *path,
+		     weston_process_cleanup_func_t cleanup)
+{
+	int sv[2];
+	pid_t pid;
+	struct wl_client *client;
+
+	weston_log("launching '%s'\n", path);
+
+	if (os_socketpair_cloexec(AF_UNIX, SOCK_STREAM, 0, sv) < 0) {
+		weston_log("weston_client_launch: "
+			"socketpair failed while launching '%s': %m\n",
+			path);
+		return NULL;
+	}
+
+	pid = fork();
+	if (pid == -1) {
+		close(sv[0]);
+		close(sv[1]);
+		weston_log("weston_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]);
+		weston_log("weston_client_launch: "
+			"wl_client_create failed while launching '%s'.\n",
+			path);
+		return NULL;
+	}
+
+	proc->pid = pid;
+	proc->cleanup = cleanup;
+	weston_watch_process(proc);
+
+	return client;
+}
+
+static int
+init_config(struct weston_compositor *ec, struct weston_config *config)
+{
+	struct xkb_rule_names xkb_names;
+	struct weston_config_section *s;
+
+	s = weston_config_get_section(config, "keyboard", NULL, NULL);
+	weston_config_section_get_string(s, "keymap_rules",
+					 (char **) &xkb_names.rules, NULL);
+	weston_config_section_get_string(s, "keymap_model",
+					 (char **) &xkb_names.model, NULL);
+	weston_config_section_get_string(s, "keymap_layout",
+					 (char **) &xkb_names.layout, NULL);
+	weston_config_section_get_string(s, "keymap_variant",
+					 (char **) &xkb_names.variant, NULL);
+	weston_config_section_get_string(s, "keymap_options",
+					 (char **) &xkb_names.options, NULL);
+
+	if (weston_compositor_xkb_init(ec, &xkb_names) < 0)
+		return -1;
+
+	weston_config_section_get_int(s, "repeat-rate",
+				      &ec->kb_repeat_rate, 40);
+	weston_config_section_get_int(s, "repeat-delay",
+				      &ec->kb_repeat_delay, 400);
+
+	return 0;
+}
+
+/* weston does a lot of stuff that's fine and required in an
+ * application, but bad in a library:
+ *
+ *  - signal handling
+ *
+ *  - sigchild handling conflicts with toolkits (but core doesn't need
+ *    launcing, except for screensaver)
+ *
+ *  - single threaded throughout
+ *
+ *  - automatically detects backend
+ *
+ *  - loads modules
+ *
+ *  - parses a config file
+ *
+ *  - sets WAYLAND_DISPLAY
+ *
+ *  - log file
+ *
+ *  - how does weston-launch work with 10 different binaries?
+ *    weston-launch currently works because weston is a trusted
+ *    binary.
+ */
+
+int main(int argc, char *argv[])
+{
+	int ret = EXIT_SUCCESS;
+	struct wl_display *display;
+	struct weston_compositor *ec;
+	struct wl_event_source *signals[4];
+	struct wl_event_loop *loop;
+	struct weston_compositor
+		*(*backend_init)(struct wl_display *display,
+				int *argc, char *argv[],
+				struct weston_config *config);
+	int i, fd;
+	char *backend = NULL;
+	char *option_backend = NULL;
+	char *shell = NULL;
+	char *option_shell = NULL;
+	char *modules, *option_modules = NULL;
+	char *log = NULL;
+	char *server_socket = NULL, *end;
+	int32_t idle_time = 300;
+	int32_t help = 0;
+	const char *socket_name = NULL;
+	int32_t version = 0;
+	int32_t noconfig = 0;
+	struct weston_config *config = NULL;
+	struct weston_config_section *section;
+	struct wl_client *primary_client;
+	struct wl_listener primary_client_destroyed;
+
+	const struct weston_option core_options[] = {
+		{ WESTON_OPTION_STRING, "backend", 'B', &option_backend },
+		{ WESTON_OPTION_STRING, "shell", 0, &option_shell },
+		{ WESTON_OPTION_STRING, "socket", 'S', &socket_name },
+		{ WESTON_OPTION_INTEGER, "idle-time", 'i', &idle_time },
+		{ WESTON_OPTION_STRING, "modules", 0, &option_modules },
+		{ WESTON_OPTION_STRING, "log", 0, &log },
+		{ WESTON_OPTION_BOOLEAN, "help", 'h', &help },
+		{ WESTON_OPTION_BOOLEAN, "version", 0, &version },
+		{ WESTON_OPTION_BOOLEAN, "no-config", 0, &noconfig },
+	};
+
+	parse_options(core_options, ARRAY_LENGTH(core_options), &argc, argv);
+
+	if (help)
+		usage(EXIT_SUCCESS);
+
+	if (version) {
+		printf(PACKAGE_STRING "\n");
+		return EXIT_SUCCESS;
+	}
+
+	weston_log_file_open(log);
+
+	weston_log("%s\n"
+		STAMP_SPACE "%s\n"
+		STAMP_SPACE "Bug reports to: %s\n"
+		STAMP_SPACE "Build: %s\n",
+		PACKAGE_STRING, PACKAGE_URL, PACKAGE_BUGREPORT,
+		BUILD_ID);
+	log_uname();
+
+	verify_xdg_runtime_dir();
+
+	display = wl_display_create();
+
+	loop = wl_display_get_event_loop(display);
+	signals[0] = wl_event_loop_add_signal(loop, SIGTERM, on_term_signal,
+					display);
+	signals[1] = wl_event_loop_add_signal(loop, SIGINT, on_term_signal,
+					display);
+	signals[2] = wl_event_loop_add_signal(loop, SIGQUIT, on_term_signal,
+					display);
+
+	wl_list_init(&child_process_list);
+	signals[3] = wl_event_loop_add_signal(loop, SIGCHLD, sigchld_handler,
+					NULL);
+
+	if (!signals[0] || !signals[1] || !signals[2] || !signals[3]) {
+		ret = EXIT_FAILURE;
+		goto out_signals;
+	}
+
+	if (noconfig == 0)
+		config = weston_config_parse("weston.ini");
+	if (config != NULL) {
+		weston_log("Using config file '%s'\n",
+			weston_config_get_full_path(config));
+	} else {
+		weston_log("Starting with no config file.\n");
+	}
+	section = weston_config_get_section(config, "core", NULL, NULL);
+
+	if (option_backend)
+		backend = strdup(option_backend);
+	else
+		weston_config_section_get_string(section, "backend", &backend,
+						NULL);
+
+	if (!backend) {
+		if (getenv("WAYLAND_DISPLAY") || getenv("WAYLAND_SOCKET"))
+			backend = strdup("wayland-backend.so");
+		else if (getenv("DISPLAY"))
+			backend = strdup("x11-backend.so");
+		else
+			backend = strdup(WESTON_NATIVE_BACKEND);
+	}
+
+	backend_init = weston_load_module(backend, "backend_init");
+	free(backend);
+	if (!backend_init) {
+		ret = EXIT_FAILURE;
+		goto out_signals;
+	}
+
+	ec = backend_init(display, &argc, argv, config);
+	if (ec == NULL) {
+		weston_log("fatal: failed to create compositor\n");
+		ret = EXIT_FAILURE;
+		goto out_signals;
+	}
+
+	catch_signals();
+	segv_compositor = ec;
+
+	ec->idle_time = idle_time;
+	ec->default_pointer_grab = NULL;
+
+	if (init_config(ec, config) < 0 || ec->setup(ec) < 0) {
+		ret = EXIT_FAILURE;
+		goto out;
+	}
+
+	for (i = 1; i < argc; i++)
+		weston_log("fatal: unhandled option: %s\n", argv[i]);
+	if (argc > 1) {
+		ret = EXIT_FAILURE;
+		goto out;
+	}
+
+	server_socket = getenv("WAYLAND_SERVER_SOCKET");
+	if (server_socket) {
+		weston_log("Running with single client\n");
+		fd = strtol(server_socket, &end, 0);
+		if (*end != '\0')
+			fd = -1;
+	} else {
+		fd = -1;
+	}
+
+	if (fd != -1) {
+		primary_client = wl_client_create(display, fd);
+		if (!primary_client) {
+			weston_log("fatal: failed to add client: %m\n");
+			ret = EXIT_FAILURE;
+			goto out;
+		}
+		primary_client_destroyed.notify =
+			handle_primary_client_destroyed;
+		wl_client_add_destroy_listener(primary_client,
+					&primary_client_destroyed);
+	} else {
+		if (socket_name) {
+			if (wl_display_add_socket(display, socket_name)) {
+				weston_log("fatal: failed to add socket: %m\n");
+				ret = EXIT_FAILURE;
+				goto out;
+			}
+		} else {
+			socket_name = wl_display_add_socket_auto(display);
+			if (!socket_name) {
+				weston_log("fatal: failed to add socket: %m\n");
+				ret = EXIT_FAILURE;
+				goto out;
+			}
+		}
+
+		setenv("WAYLAND_DISPLAY", socket_name, 1);
+	}
+
+	if (option_shell)
+		shell = strdup(option_shell);
+	else
+		weston_config_section_get_string(section, "shell", &shell,
+						"desktop-shell.so");
+
+	if (load_modules(ec, shell, &argc, argv, config) < 0) {
+		free(shell);
+		goto out;
+	}
+	free(shell);
+
+	weston_config_section_get_string(section, "modules", &modules, "");
+	if (load_modules(ec, modules, &argc, argv, config) < 0) {
+		free(modules);
+		goto out;
+	}
+	free(modules);
+
+	if (load_modules(ec, option_modules, &argc, argv, config) < 0)
+		goto out;
+
+	weston_compositor_wake(ec);
+
+	wl_display_run(display);
+
+out:
+	if (ec)
+		weston_compositor_destroy(ec);
+
+out_signals:
+	for (i = ARRAY_LENGTH(signals) - 1; i >= 0; i--)
+		if (signals[i])
+			wl_event_source_remove(signals[i]);
+
+	wl_display_destroy(display);
+
+	weston_log_file_close();
+
+	return ret;
+}
diff --git a/src/weston.h b/src/weston.h
new file mode 100644
index 0000000..92feeec
--- /dev/null
+++ b/src/weston.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright © 2008-2011 Kristian Høgsberg
+ * Copyright © 2012 Collabora, Ltd.
+ *
+ * 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.
+ */
+
+#ifndef WESTON_MAIN_H
+#define WESTON_MAIN_H
+
+struct wl_display;
+struct weston_compositor;
+struct weston_config;
+
+typedef int (*shell_init_func_t)(struct weston_compositor *c,
+                                  int *argc, char *argv[],
+                                  struct weston_config *config);
+
+int
+weston_main(int argc, char *argv[],
+            shell_init_func_t shell_init);
+
+void
+weston_log_file_open(const char *filename);
+void
+weston_log_file_close(void);
+
+struct weston_compositor *
+backend_init(struct wl_display *display, int *argc, char *argv[],
+	     struct weston_config *config);
+
+int
+module_init(struct weston_compositor *compositor,
+	    int *argc, char *argv[], struct weston_config *config);
+
+int
+text_backend_init(struct weston_compositor *ec, struct weston_config *config);
+
+#endif
diff --git a/src/x11-backend.c b/src/x11-backend.c
new file mode 100644
index 0000000..24bd07f
--- /dev/null
+++ b/src/x11-backend.c
@@ -0,0 +1,168 @@
+/*
+ * Copyright © 2008-2011 Kristian Høgsberg
+ * Copyright © 2012 Collabora, Ltd.
+ *
+ * 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<string.h>
+#include <pixman.h>
+
+#include "libweston/compositor-x11.h"
+#include "weston.h"
+
+static int option_width;
+static int option_height;
+static int option_scale;
+static int option_count;
+
+static uint32_t
+parse_transform(const char *transform, const char *output_name)
+{
+	static const struct { const char *name; uint32_t token; } names[] = {
+		{ "normal",	WL_OUTPUT_TRANSFORM_NORMAL },
+		{ "90",		WL_OUTPUT_TRANSFORM_90 },
+		{ "180",	WL_OUTPUT_TRANSFORM_180 },
+		{ "270",	WL_OUTPUT_TRANSFORM_270 },
+		{ "flipped",	WL_OUTPUT_TRANSFORM_FLIPPED },
+		{ "flipped-90",	WL_OUTPUT_TRANSFORM_FLIPPED_90 },
+		{ "flipped-180", WL_OUTPUT_TRANSFORM_FLIPPED_180 },
+		{ "flipped-270", WL_OUTPUT_TRANSFORM_FLIPPED_270 },
+	};
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_LENGTH(names); i++)
+		if (strcmp(names[i].name, transform) == 0)
+			return names[i].token;
+
+	weston_log("Invalid transform \"%s\" for output %s\n",
+		   transform, output_name);
+
+	return WL_OUTPUT_TRANSFORM_NORMAL;
+}
+
+WL_EXPORT struct weston_compositor *
+backend_init(struct wl_display *display, int *argc, char *argv[],
+	     struct weston_config *config)
+{
+	struct x11_compositor *compositor;
+	struct weston_compositor *base;
+	struct weston_output *output;
+	struct weston_config_section *section = NULL;
+	const char *section_name;
+	int i, x = 0, output_count = 0;
+	int width, height, scale, count;
+	char *name, *t, *mode;
+	uint32_t transform;
+	int fullscreen = 0;
+	int no_input = 0;
+	int use_pixman = 0;
+
+	const struct weston_option x11_options[] = {
+		{ WESTON_OPTION_INTEGER, "width", 0, &option_width },
+		{ WESTON_OPTION_INTEGER, "height", 0, &option_height },
+		{ WESTON_OPTION_INTEGER, "scale", 0, &option_scale },
+		{ WESTON_OPTION_BOOLEAN, "fullscreen", 'f', &fullscreen },
+		{ WESTON_OPTION_INTEGER, "output-count", 0, &option_count },
+		{ WESTON_OPTION_BOOLEAN, "no-input", 0, &no_input },
+		{ WESTON_OPTION_BOOLEAN, "use-pixman", 0, &use_pixman },
+	};
+
+	parse_options(x11_options, ARRAY_LENGTH(x11_options), argc, argv);
+
+	compositor = x11_compositor_create(display,
+				     fullscreen,
+				     no_input,
+				     use_pixman);
+
+	if (compositor == NULL)
+		return NULL;
+
+	base = x11_compositor_get_base(compositor);
+	width = option_width ? option_width : 1024;
+	height = option_height ? option_height : 640;
+	scale = option_scale ? option_scale : 1;
+	count = option_count ? option_count : 1;
+
+	while (weston_config_next_section(config,
+					  &section, &section_name)) {
+		if (strcmp(section_name, "output") != 0)
+			continue;
+		weston_config_section_get_string(section, "name", &name, NULL);
+		if (name == NULL || name[0] != 'X') {
+			free(name);
+			continue;
+		}
+
+		weston_config_section_get_string(section,
+						 "mode", &mode, "1024x600");
+		if (sscanf(mode, "%dx%d", &width, &height) != 2) {
+			weston_log("Invalid mode \"%s\" for output %s\n",
+				   mode, name);
+			width = 1024;
+			height = 600;
+		}
+		free(mode);
+
+		if (option_width)
+			width = option_width;
+		if (option_height)
+			height = option_height;
+
+		weston_config_section_get_int(section, "scale", &scale, 1);
+		if (option_scale)
+			scale = option_scale;
+
+		weston_config_section_get_string(section,
+						 "transform", &t, "normal");
+		transform = parse_transform(t, name);
+		free(t);
+
+		output = x11_compositor_create_output(compositor, x, 0,
+						      width, height,
+						      fullscreen, no_input,
+						      name, transform, scale);
+		free(name);
+		if (output == NULL) {
+			base->destroy(base);
+			return NULL;
+		}
+
+		x = pixman_region32_extents(&output->region)->x2;
+
+		output_count++;
+		if (option_count && output_count >= option_count)
+			break;
+	}
+
+	for (i = output_count; i < count; i++) {
+		output = x11_compositor_create_output(compositor, x, 0, width, height,
+						      fullscreen, no_input, NULL,
+						      WL_OUTPUT_TRANSFORM_NORMAL, scale);
+		if (output == NULL) {
+			base->destroy(base);
+			return NULL;
+		}
+		x = pixman_region32_extents(&output->region)->x2;
+	}
+
+	return base;
+}
diff --git a/tests/surface-global-test.c b/tests/surface-global-test.c
index edc5d9f..1026609 100644
--- a/tests/surface-global-test.c
+++ b/tests/surface-global-test.c
@@ -24,7 +24,7 @@
 
 #include <assert.h>
 
-#include "../src/compositor.h"
+#include "../libweston/compositor.h"
 
 static void
 surface_to_from_global(void *data)
diff --git a/tests/surface-test.c b/tests/surface-test.c
index 80dce81..61bf6d8 100644
--- a/tests/surface-test.c
+++ b/tests/surface-test.c
@@ -24,7 +24,7 @@
 #include <stdio.h>
 #include <assert.h>
 
-#include "../src/compositor.h"
+#include "../libweston/compositor.h"
 
 static void
 surface_transform(void *data)
diff --git a/tests/vertex-clip-test.c b/tests/vertex-clip-test.c
index 1a09437..e75e12c 100644
--- a/tests/vertex-clip-test.c
+++ b/tests/vertex-clip-test.c
@@ -30,7 +30,7 @@
 
 #include "weston-test-runner.h"
 
-#include "../src/vertex-clipping.h"
+#include "../libweston/vertex-clipping.h"
 
 #define BOUNDING_BOX_TOP_Y 100.0f
 #define BOUNDING_BOX_LEFT_X 50.0f
diff --git a/tests/weston-test.c b/tests/weston-test.c
index ca2f219..9ecad7b 100644
--- a/tests/weston-test.c
+++ b/tests/weston-test.c
@@ -27,7 +27,7 @@
 #include <assert.h>
 #include <signal.h>
 #include <unistd.h>
-#include "../src/compositor.h"
+#include "../libweston/compositor.h"
 #include "wayland-test-server-protocol.h"
 
 #ifdef ENABLE_EGL
diff --git a/xwayland/launcher.c b/xwayland/launcher.c
index bf1e17e..9416959 100644
--- a/xwayland/launcher.c
+++ b/xwayland/launcher.c
@@ -55,8 +55,6 @@ 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");
@@ -94,11 +92,6 @@ weston_xserver_handle_event(int listen_fd, uint32_t mask, void *data)
 			goto fail;
 		snprintf(wm_fd, sizeof wm_fd, "%d", fd);
 
-		section = weston_config_get_section(wxs->compositor->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
@@ -108,8 +101,8 @@ weston_xserver_handle_event(int listen_fd, uint32_t mask, void *data)
 		 * it's done with that. */
 		signal(SIGUSR1, SIG_IGN);
 
-		if (execl(xserver,
-			  xserver,
+		if (execl(wxs->xserver_path,
+			  wxs->xserver_path,
 			  display,
 			  "-rootless",
 			  "-listen", abstract_fd,
@@ -120,7 +113,7 @@ weston_xserver_handle_event(int listen_fd, uint32_t mask, void *data)
 			weston_log("exec of '%s %s -rootless "
                                    "-listen %s -listen %s -wm %s "
                                    "-terminate' failed: %m\n",
-                                   xserver, display,
+                                   wxs->xserver_path, display,
                                    abstract_fd, unix_fd, wm_fd);
 	fail:
 		_exit(EXIT_FAILURE);
@@ -339,28 +332,27 @@ weston_xserver_destroy(struct wl_listener *l, void *data)
 	if (wxs->loop)
 		weston_xserver_shutdown(wxs);
 
+	free(wxs->xserver_path);
 	free(wxs);
 }
 
-WL_EXPORT int
-module_init(struct weston_compositor *compositor,
-	    int *argc, char *argv[])
-
+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;
+		return NULL;
 	wxs->process.cleanup = weston_xserver_cleanup;
 	wxs->wl_display = display;
-	wxs->compositor = compositor;
+	wxs->compositor = c;
 
 	wxs->display = 0;
 
- retry:
+retry:
 	if (create_lockfile(wxs->display, lockfile, sizeof lockfile) < 0) {
 		if (errno == EAGAIN) {
 			goto retry;
@@ -369,7 +361,7 @@ module_init(struct weston_compositor *compositor,
 			goto retry;
 		} else {
 			free(wxs);
-			return -1;
+			return NULL;
 		}
 	}
 
@@ -385,13 +377,14 @@ 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->xserver_path = strdup(xserver);
 	wxs->loop = wl_display_get_event_loop(display);
 	wxs->abstract_source =
 		wl_event_loop_add_fd(wxs->loop, wxs->abstract_fd,
@@ -405,7 +398,7 @@ 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);
+	wl_signal_add(&c->destroy_signal, &wxs->destroy_listener);
 
-	return 0;
+	return wxs;
 }
diff --git a/xwayland/xwayland-module.c b/xwayland/xwayland-module.c
new file mode 100644
index 0000000..a22f076
--- /dev/null
+++ b/xwayland/xwayland-module.c
@@ -0,0 +1,26 @@
+
+#include "config.h"
+
+#include "xwayland.h"
+#include "weston.h"
+
+WL_EXPORT int
+module_init(struct weston_compositor *compositor,
+            int *argc, char *argv[], struct weston_config *config)
+
+{
+	struct weston_xserver *wxs;
+	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);
+
+	wxs = weston_xserver_create(compositor, xserver);
+	if (!wxs)
+		return -1;
+
+	return 0;
+}
\ No newline at end of file
diff --git a/xwayland/xwayland.h b/xwayland/xwayland.h
index 312c9b2..5ea8f9a 100644
--- a/xwayland/xwayland.h
+++ b/xwayland/xwayland.h
@@ -41,6 +41,7 @@ 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;
 	struct wl_resource *resource;
@@ -150,6 +151,9 @@ struct weston_wm {
 	} atom;
 };
 
+struct weston_xserver *
+weston_xserver_create(struct weston_compositor *c, const char *xserver);
+
 void
 dump_property(struct weston_wm *wm, xcb_atom_t property,
 	      xcb_get_property_reply_t *reply);
-- 
2.0.4



More information about the wayland-devel mailing list