[weston,v2,01/17] compositor: introduce struct weston_backend

Submitted by Giulio Camuffo on Dec. 4, 2014, 9:01 p.m.

Details

Message ID 1417726883-8305-2-git-send-email-giuliocamuffo@gmail.com
State Superseded
Headers show

Not browsing as part of any series.

Commit Message

Giulio Camuffo Dec. 4, 2014, 9:01 p.m.
This is a preliminary change for libweston, with no functional modifications.
Separate the backends and the core weston_compositor struct, by creating
the weston_compositor in the main(), and having the various backends extend
the weston_backend struct, an instance of which is returned by the backend
entry point.
---
 src/compositor-drm.c      | 648 +++++++++++++++++++++++-----------------------
 src/compositor-fbdev.c    | 164 ++++++------
 src/compositor-headless.c | 104 ++++----
 src/compositor-rdp.c      | 157 +++++------
 src/compositor-rpi.c      | 149 +++++------
 src/compositor-wayland.c  | 367 +++++++++++++-------------
 src/compositor-x11.c      | 546 +++++++++++++++++++-------------------
 src/compositor.c          |  29 ++-
 src/compositor.h          |  17 +-
 9 files changed, 1111 insertions(+), 1070 deletions(-)

Patch hide | download patch | download mbox

diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index 9b4d4dc..ea25bd5 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -78,8 +78,9 @@  enum output_config {
 	OUTPUT_CONFIG_MODELINE
 };
 
-struct drm_compositor {
-	struct weston_compositor base;
+struct drm_backend {
+	struct weston_backend base;
+	struct weston_compositor *compositor;
 
 	struct udev *udev;
 	struct wl_event_source *drm_source;
@@ -196,7 +197,7 @@  struct drm_sprite {
 
 	struct drm_fb *current, *next;
 	struct drm_output *output;
-	struct drm_compositor *compositor;
+	struct drm_backend *backend;
 
 	uint32_t possible_crtcs;
 	uint32_t plane_id;
@@ -228,12 +229,12 @@  static int
 drm_sprite_crtc_supported(struct weston_output *output_base, uint32_t supported)
 {
 	struct weston_compositor *ec = output_base->compositor;
-	struct drm_compositor *c =(struct drm_compositor *) ec;
+	struct drm_backend *b =(struct drm_backend *) ec->backend;
 	struct drm_output *output = (struct drm_output *) output_base;
 	int crtc;
 
-	for (crtc = 0; crtc < c->num_crtcs; crtc++) {
-		if (c->crtcs[crtc] != output->crtc_id)
+	for (crtc = 0; crtc < b->num_crtcs; crtc++) {
+		if (b->crtcs[crtc] != output->crtc_id)
 			continue;
 
 		if (supported & (1 << crtc))
@@ -258,7 +259,7 @@  drm_fb_destroy_callback(struct gbm_bo *bo, void *data)
 }
 
 static struct drm_fb *
-drm_fb_create_dumb(struct drm_compositor *ec, unsigned width, unsigned height)
+drm_fb_create_dumb(struct drm_backend *b, unsigned width, unsigned height)
 {
 	struct drm_fb *fb;
 	int ret;
@@ -276,16 +277,16 @@  drm_fb_create_dumb(struct drm_compositor *ec, unsigned width, unsigned height)
 	create_arg.width = width;
 	create_arg.height = height;
 
-	ret = drmIoctl(ec->drm.fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_arg);
+	ret = drmIoctl(b->drm.fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_arg);
 	if (ret)
 		goto err_fb;
 
 	fb->handle = create_arg.handle;
 	fb->stride = create_arg.pitch;
 	fb->size = create_arg.size;
-	fb->fd = ec->drm.fd;
+	fb->fd = b->drm.fd;
 
-	ret = drmModeAddFB(ec->drm.fd, width, height, 24, 32,
+	ret = drmModeAddFB(b->drm.fd, width, height, 24, 32,
 			   fb->stride, fb->handle, &fb->fb_id);
 	if (ret)
 		goto err_bo;
@@ -297,18 +298,18 @@  drm_fb_create_dumb(struct drm_compositor *ec, unsigned width, unsigned height)
 		goto err_add_fb;
 
 	fb->map = mmap(0, fb->size, PROT_WRITE,
-		       MAP_SHARED, ec->drm.fd, map_arg.offset);
+		       MAP_SHARED, b->drm.fd, map_arg.offset);
 	if (fb->map == MAP_FAILED)
 		goto err_add_fb;
 
 	return fb;
 
 err_add_fb:
-	drmModeRmFB(ec->drm.fd, fb->fb_id);
+	drmModeRmFB(b->drm.fd, fb->fb_id);
 err_bo:
 	memset(&destroy_arg, 0, sizeof(destroy_arg));
 	destroy_arg.handle = create_arg.handle;
-	drmIoctl(ec->drm.fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_arg);
+	drmIoctl(b->drm.fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_arg);
 err_fb:
 	free(fb);
 	return NULL;
@@ -338,7 +339,7 @@  drm_fb_destroy_dumb(struct drm_fb *fb)
 
 static struct drm_fb *
 drm_fb_get_from_bo(struct gbm_bo *bo,
-		   struct drm_compositor *compositor, uint32_t format)
+		   struct drm_backend *backend, uint32_t format)
 {
 	struct drm_fb *fb = gbm_bo_get_user_data(bo);
 	uint32_t width, height;
@@ -359,34 +360,34 @@  drm_fb_get_from_bo(struct gbm_bo *bo,
 	fb->stride = gbm_bo_get_stride(bo);
 	fb->handle = gbm_bo_get_handle(bo).u32;
 	fb->size = fb->stride * height;
-	fb->fd = compositor->drm.fd;
+	fb->fd = backend->drm.fd;
 
-	if (compositor->min_width > width || width > compositor->max_width ||
-	    compositor->min_height > height ||
-	    height > compositor->max_height) {
+	if (backend->min_width > width || width > backend->max_width ||
+	    backend->min_height > height ||
+	    height > backend->max_height) {
 		weston_log("bo geometry out of bounds\n");
 		goto err_free;
 	}
 
 	ret = -1;
 
-	if (format && !compositor->no_addfb2) {
+	if (format && !backend->no_addfb2) {
 		handles[0] = fb->handle;
 		pitches[0] = fb->stride;
 		offsets[0] = 0;
 
-		ret = drmModeAddFB2(compositor->drm.fd, width, height,
+		ret = drmModeAddFB2(backend->drm.fd, width, height,
 				    format, handles, pitches, offsets,
 				    &fb->fb_id, 0);
 		if (ret) {
 			weston_log("addfb2 failed: %m\n");
-			compositor->no_addfb2 = 1;
-			compositor->sprites_are_broken = 1;
+			backend->no_addfb2 = 1;
+			backend->sprites_are_broken = 1;
 		}
 	}
 
 	if (ret)
-		ret = drmModeAddFB(compositor->drm.fd, width, height, 24, 32,
+		ret = drmModeAddFB(backend->drm.fd, width, height, 24, 32,
 				   fb->stride, fb->handle, &fb->fb_id);
 
 	if (ret) {
@@ -466,8 +467,8 @@  drm_output_prepare_scanout_view(struct weston_output *_output,
 				struct weston_view *ev)
 {
 	struct drm_output *output = (struct drm_output *) _output;
-	struct drm_compositor *c =
-		(struct drm_compositor *) output->base.compositor;
+	struct drm_backend *b =
+		(struct drm_backend *) output->base.compositor->backend;
 	struct weston_buffer *buffer = ev->surface->buffer_ref.buffer;
 	struct weston_buffer_viewport *viewport = &ev->surface->buffer_viewport;
 	struct gbm_bo *bo;
@@ -475,14 +476,14 @@  drm_output_prepare_scanout_view(struct weston_output *_output,
 
 	if (ev->geometry.x != output->base.x ||
 	    ev->geometry.y != output->base.y ||
-	    buffer == NULL || c->gbm == NULL ||
+	    buffer == NULL || b->gbm == NULL ||
 	    buffer->width != output->base.current_mode->width ||
 	    buffer->height != output->base.current_mode->height ||
 	    output->base.transform != viewport->buffer.transform ||
 	    ev->transform.enabled)
 		return NULL;
 
-	bo = gbm_bo_import(c->gbm, GBM_BO_IMPORT_WL_BUFFER,
+	bo = gbm_bo_import(b->gbm, GBM_BO_IMPORT_WL_BUFFER,
 			   buffer->resource, GBM_BO_USE_SCANOUT);
 
 	/* Unable to use the buffer for scanout */
@@ -495,7 +496,7 @@  drm_output_prepare_scanout_view(struct weston_output *_output,
 		return NULL;
 	}
 
-	output->next = drm_fb_get_from_bo(bo, c, format);
+	output->next = drm_fb_get_from_bo(bo, b, format);
 	if (!output->next) {
 		gbm_bo_destroy(bo);
 		return NULL;
@@ -509,11 +510,12 @@  drm_output_prepare_scanout_view(struct weston_output *_output,
 static void
 drm_output_render_gl(struct drm_output *output, pixman_region32_t *damage)
 {
-	struct drm_compositor *c =
-		(struct drm_compositor *) output->base.compositor;
+	struct drm_backend *b =
+		(struct drm_backend *) output->base.compositor->backend;
 	struct gbm_bo *bo;
 
-	c->base.renderer->repaint_output(&output->base, damage);
+	output->base.compositor->renderer->repaint_output(&output->base,
+							  damage);
 
 	bo = gbm_surface_lock_front_buffer(output->surface);
 	if (!bo) {
@@ -521,7 +523,7 @@  drm_output_render_gl(struct drm_output *output, pixman_region32_t *damage)
 		return;
 	}
 
-	output->next = drm_fb_get_from_bo(bo, c, output->format);
+	output->next = drm_fb_get_from_bo(bo, b, output->format);
 	if (!output->next) {
 		weston_log("failed to get drm_fb for bo\n");
 		gbm_surface_release_buffer(output->surface, bo);
@@ -558,16 +560,16 @@  drm_output_render_pixman(struct drm_output *output, pixman_region32_t *damage)
 static void
 drm_output_render(struct drm_output *output, pixman_region32_t *damage)
 {
-	struct drm_compositor *c =
-		(struct drm_compositor *) output->base.compositor;
+	struct weston_compositor *c = output->base.compositor;
+	struct drm_backend *b = (struct drm_backend *) c->backend;
 
-	if (c->use_pixman)
+	if (b->use_pixman)
 		drm_output_render_pixman(output, damage);
 	else
 		drm_output_render_gl(output, damage);
 
-	pixman_region32_subtract(&c->base.primary_plane.damage,
-				 &c->base.primary_plane.damage, damage);
+	pixman_region32_subtract(&c->primary_plane.damage,
+				 &c->primary_plane.damage, damage);
 }
 
 static void
@@ -576,7 +578,8 @@  drm_output_set_gamma(struct weston_output *output_base,
 {
 	int rc;
 	struct drm_output *output = (struct drm_output *) output_base;
-	struct drm_compositor *compositor = (struct drm_compositor *) output->base.compositor;
+	struct drm_backend *backend =
+		(struct drm_backend *) output->base.compositor->backend;
 
 	/* check */
 	if (output_base->gamma_size != size)
@@ -584,7 +587,7 @@  drm_output_set_gamma(struct weston_output *output_base,
 	if (!output->original_crtc)
 		return;
 
-	rc = drmModeCrtcSetGamma(compositor->drm.fd,
+	rc = drmModeCrtcSetGamma(backend->drm.fd,
 				 output->crtc_id,
 				 size, r, g, b);
 	if (rc)
@@ -596,8 +599,8 @@  drm_output_repaint(struct weston_output *output_base,
 		   pixman_region32_t *damage)
 {
 	struct drm_output *output = (struct drm_output *) output_base;
-	struct drm_compositor *compositor =
-		(struct drm_compositor *) output->base.compositor;
+	struct drm_backend *backend =
+		(struct drm_backend *) output->base.compositor->backend;
 	struct drm_sprite *s;
 	struct drm_mode *mode;
 	int ret = 0;
@@ -613,7 +616,7 @@  drm_output_repaint(struct weston_output *output_base,
 	mode = container_of(output->base.current_mode, struct drm_mode, base);
 	if (!output->current ||
 	    output->current->stride != output->next->stride) {
-		ret = drmModeSetCrtc(compositor->drm.fd, output->crtc_id,
+		ret = drmModeSetCrtc(backend->drm.fd, output->crtc_id,
 				     output->next->fb_id, 0, 0,
 				     &output->connector_id, 1,
 				     &mode->mode_info);
@@ -624,7 +627,7 @@  drm_output_repaint(struct weston_output *output_base,
 		output_base->set_dpms(output_base, WESTON_DPMS_ON);
 	}
 
-	if (drmModePageFlip(compositor->drm.fd, output->crtc_id,
+	if (drmModePageFlip(backend->drm.fd, output->crtc_id,
 			    output->next->fb_id,
 			    DRM_MODE_PAGE_FLIP_EVENT, output) < 0) {
 		weston_log("queueing pageflip failed: %m\n");
@@ -638,7 +641,7 @@  drm_output_repaint(struct weston_output *output_base,
 	/*
 	 * Now, update all the sprite surfaces
 	 */
-	wl_list_for_each(s, &compositor->sprite_list, link) {
+	wl_list_for_each(s, &backend->sprite_list, link) {
 		uint32_t flags = 0, fb_id = 0;
 		drmVBlank vbl = {
 			.request.type = DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT,
@@ -649,10 +652,10 @@  drm_output_repaint(struct weston_output *output_base,
 		    !drm_sprite_crtc_supported(output_base, s->possible_crtcs))
 			continue;
 
-		if (s->next && !compositor->sprites_hidden)
+		if (s->next && !backend->sprites_hidden)
 			fb_id = s->next->fb_id;
 
-		ret = drmModeSetPlane(compositor->drm.fd, s->plane_id,
+		ret = drmModeSetPlane(backend->drm.fd, s->plane_id,
 				      output->crtc_id, fb_id, flags,
 				      s->dest_x, s->dest_y,
 				      s->dest_w, s->dest_h,
@@ -670,7 +673,7 @@  drm_output_repaint(struct weston_output *output_base,
 		 * becomes active on the display or has been replaced.
 		 */
 		vbl.request.signal = (unsigned long)s;
-		ret = drmWaitVBlank(compositor->drm.fd, &vbl);
+		ret = drmWaitVBlank(backend->drm.fd, &vbl);
 		if (ret) {
 			weston_log("vblank event request failed: %d: %s\n",
 				ret, strerror(errno));
@@ -696,8 +699,8 @@  static void
 drm_output_start_repaint_loop(struct weston_output *output_base)
 {
 	struct drm_output *output = (struct drm_output *) output_base;
-	struct drm_compositor *compositor = (struct drm_compositor *)
-		output_base->compositor;
+	struct drm_backend *backend = (struct drm_backend *)
+		output_base->compositor->backend;
 	uint32_t fb_id;
 	struct timespec ts;
 
@@ -711,7 +714,7 @@  drm_output_start_repaint_loop(struct weston_output *output_base)
 
 	fb_id = output->current->fb_id;
 
-	if (drmModePageFlip(compositor->drm.fd, output->crtc_id, fb_id,
+	if (drmModePageFlip(backend->drm.fd, output->crtc_id, fb_id,
 			    DRM_MODE_PAGE_FLIP_EVENT, output) < 0) {
 		weston_log("queueing pageflip failed: %m\n");
 		goto finish_frame;
@@ -721,7 +724,7 @@  drm_output_start_repaint_loop(struct weston_output *output_base)
 
 finish_frame:
 	/* if we cannot page-flip, immediately finish frame */
-	clock_gettime(compositor->base.presentation_clock, &ts);
+	clock_gettime(output_base->compositor->presentation_clock, &ts);
 	weston_output_finish_frame(output_base, &ts);
 }
 
@@ -836,7 +839,7 @@  drm_output_prepare_overlay_view(struct weston_output *output_base,
 				struct weston_view *ev)
 {
 	struct weston_compositor *ec = output_base->compositor;
-	struct drm_compositor *c =(struct drm_compositor *) ec;
+	struct drm_backend *b =(struct drm_backend *) ec->backend;
 	struct weston_buffer_viewport *viewport = &ev->surface->buffer_viewport;
 	struct drm_sprite *s;
 	int found = 0;
@@ -846,7 +849,7 @@  drm_output_prepare_overlay_view(struct weston_output *output_base,
 	uint32_t format;
 	wl_fixed_t sx1, sy1, sx2, sy2;
 
-	if (c->gbm == NULL)
+	if (b->gbm == NULL)
 		return NULL;
 
 	if (viewport->buffer.transform != output_base->transform)
@@ -855,7 +858,7 @@  drm_output_prepare_overlay_view(struct weston_output *output_base,
 	if (viewport->buffer.scale != output_base->current_scale)
 		return NULL;
 
-	if (c->sprites_are_broken)
+	if (b->sprites_are_broken)
 		return NULL;
 
 	if (ev->output_mask != (1u << output_base->id))
@@ -873,7 +876,7 @@  drm_output_prepare_overlay_view(struct weston_output *output_base,
 	if (!drm_view_transform_supported(ev))
 		return NULL;
 
-	wl_list_for_each(s, &c->sprite_list, link) {
+	wl_list_for_each(s, &b->sprite_list, link) {
 		if (!drm_sprite_crtc_supported(output_base, s->possible_crtcs))
 			continue;
 
@@ -887,7 +890,7 @@  drm_output_prepare_overlay_view(struct weston_output *output_base,
 	if (!found)
 		return NULL;
 
-	bo = gbm_bo_import(c->gbm, GBM_BO_IMPORT_WL_BUFFER,
+	bo = gbm_bo_import(b->gbm, GBM_BO_IMPORT_WL_BUFFER,
 			   ev->surface->buffer_ref.buffer->resource,
 			   GBM_BO_USE_SCANOUT);
 	if (!bo)
@@ -899,7 +902,7 @@  drm_output_prepare_overlay_view(struct weston_output *output_base,
 		return NULL;
 	}
 
-	s->next = drm_fb_get_from_bo(bo, c, format);
+	s->next = drm_fb_get_from_bo(bo, b, format);
 	if (!s->next) {
 		gbm_bo_destroy(bo);
 		return NULL;
@@ -979,12 +982,12 @@  static struct weston_plane *
 drm_output_prepare_cursor_view(struct weston_output *output_base,
 			       struct weston_view *ev)
 {
-	struct drm_compositor *c =
-		(struct drm_compositor *) output_base->compositor;
+	struct drm_backend *b =
+		(struct drm_backend *) output_base->compositor->backend;
 	struct weston_buffer_viewport *viewport = &ev->surface->buffer_viewport;
 	struct drm_output *output = (struct drm_output *) output_base;
 
-	if (c->gbm == NULL)
+	if (b->gbm == NULL)
 		return NULL;
 	if (output->base.transform != WL_OUTPUT_TRANSFORM_NORMAL)
 		return NULL;
@@ -994,7 +997,7 @@  drm_output_prepare_cursor_view(struct weston_output *output_base,
 		return NULL;
 	if (ev->output_mask != (1u << output_base->id))
 		return NULL;
-	if (c->cursors_are_broken)
+	if (b->cursors_are_broken)
 		return NULL;
 	if (ev->surface->buffer_ref.buffer == NULL ||
 	    !wl_shm_buffer_get(ev->surface->buffer_ref.buffer->resource) ||
@@ -1011,17 +1014,17 @@  drm_output_set_cursor(struct drm_output *output)
 {
 	struct weston_view *ev = output->cursor_view;
 	struct weston_buffer *buffer;
-	struct drm_compositor *c =
-		(struct drm_compositor *) output->base.compositor;
+	struct drm_backend *b =
+		(struct drm_backend *) output->base.compositor->backend;
 	EGLint handle, stride;
 	struct gbm_bo *bo;
-	uint32_t buf[c->cursor_width * c->cursor_height];
+	uint32_t buf[b->cursor_width * b->cursor_height];
 	unsigned char *s;
 	int i, x, y;
 
 	output->cursor_view = NULL;
 	if (ev == NULL) {
-		drmModeSetCursor(c->drm.fd, output->crtc_id, 0, 0, 0);
+		drmModeSetCursor(b->drm.fd, output->crtc_id, 0, 0, 0);
 		return;
 	}
 
@@ -1038,7 +1041,7 @@  drm_output_set_cursor(struct drm_output *output)
 		s = wl_shm_buffer_get_data(buffer->shm_buffer);
 		wl_shm_buffer_begin_access(buffer->shm_buffer);
 		for (i = 0; i < ev->surface->height; i++)
-			memcpy(buf + i * c->cursor_width, s + i * stride,
+			memcpy(buf + i * b->cursor_width, s + i * stride,
 			       ev->surface->width * 4);
 		wl_shm_buffer_end_access(buffer->shm_buffer);
 
@@ -1046,19 +1049,19 @@  drm_output_set_cursor(struct drm_output *output)
 			weston_log("failed update cursor: %m\n");
 
 		handle = gbm_bo_get_handle(bo).s32;
-		if (drmModeSetCursor(c->drm.fd, output->crtc_id, handle,
-				c->cursor_width, c->cursor_height)) {
+		if (drmModeSetCursor(b->drm.fd, output->crtc_id, handle,
+				b->cursor_width, b->cursor_height)) {
 			weston_log("failed to set cursor: %m\n");
-			c->cursors_are_broken = 1;
+			b->cursors_are_broken = 1;
 		}
 	}
 
 	x = (ev->geometry.x - output->base.x) * output->base.current_scale;
 	y = (ev->geometry.y - output->base.y) * output->base.current_scale;
 	if (output->cursor_plane.x != x || output->cursor_plane.y != y) {
-		if (drmModeMoveCursor(c->drm.fd, output->crtc_id, x, y)) {
+		if (drmModeMoveCursor(b->drm.fd, output->crtc_id, x, y)) {
 			weston_log("failed to move cursor: %m\n");
-			c->cursors_are_broken = 1;
+			b->cursors_are_broken = 1;
 		}
 
 		output->cursor_plane.x = x;
@@ -1069,8 +1072,8 @@  drm_output_set_cursor(struct drm_output *output)
 static void
 drm_assign_planes(struct weston_output *output)
 {
-	struct drm_compositor *c =
-		(struct drm_compositor *) output->compositor;
+	struct drm_backend *b =
+		(struct drm_backend *) output->compositor->backend;
 	struct weston_view *ev, *next;
 	pixman_region32_t overlap, surface_overlap;
 	struct weston_plane *primary, *next_plane;
@@ -1089,9 +1092,9 @@  drm_assign_planes(struct weston_output *output)
 	 * as we do for flipping full screen surfaces.
 	 */
 	pixman_region32_init(&overlap);
-	primary = &c->base.primary_plane;
+	primary = &output->compositor->primary_plane;
 
-	wl_list_for_each_safe(ev, next, &c->base.view_list, link) {
+	wl_list_for_each_safe(ev, next, &output->compositor->view_list, link) {
 		struct weston_surface *es = ev->surface;
 
 		/* Test whether this buffer can ever go into a plane:
@@ -1102,7 +1105,7 @@  drm_assign_planes(struct weston_output *output)
 		 * renderer and since the pixman renderer keeps a reference
 		 * to the buffer anyway, there is no side effects.
 		 */
-		if (c->use_pixman ||
+		if (b->use_pixman ||
 		    (es->buffer_ref.buffer &&
 		    (!wl_shm_buffer_get(es->buffer_ref.buffer->resource) ||
 		     (ev->surface->width <= 64 && ev->surface->height <= 64))))
@@ -1142,8 +1145,8 @@  static void
 drm_output_destroy(struct weston_output *output_base)
 {
 	struct drm_output *output = (struct drm_output *) output_base;
-	struct drm_compositor *c =
-		(struct drm_compositor *) output->base.compositor;
+	struct drm_backend *b =
+		(struct drm_backend *) output->base.compositor->backend;
 	drmModeCrtcPtr origcrtc = output->original_crtc;
 
 	if (output->page_flip_pending) {
@@ -1158,18 +1161,18 @@  drm_output_destroy(struct weston_output *output_base)
 	drmModeFreeProperty(output->dpms_prop);
 
 	/* Turn off hardware cursor */
-	drmModeSetCursor(c->drm.fd, output->crtc_id, 0, 0, 0);
+	drmModeSetCursor(b->drm.fd, output->crtc_id, 0, 0, 0);
 
 	/* Restore original CRTC state */
-	drmModeSetCrtc(c->drm.fd, origcrtc->crtc_id, origcrtc->buffer_id,
+	drmModeSetCrtc(b->drm.fd, origcrtc->crtc_id, origcrtc->buffer_id,
 		       origcrtc->x, origcrtc->y,
 		       &output->connector_id, 1, &origcrtc->mode);
 	drmModeFreeCrtc(origcrtc);
 
-	c->crtc_allocator &= ~(1 << output->crtc_id);
-	c->connector_allocator &= ~(1 << output->connector_id);
+	b->crtc_allocator &= ~(1 << output->crtc_id);
+	b->connector_allocator &= ~(1 << output->connector_id);
 
-	if (c->use_pixman) {
+	if (b->use_pixman) {
 		drm_output_fini_pixman(output);
 	} else {
 		gl_renderer->output_destroy(output_base);
@@ -1210,16 +1213,16 @@  choose_mode (struct drm_output *output, struct weston_mode *target_mode)
 }
 
 static int
-drm_output_init_egl(struct drm_output *output, struct drm_compositor *ec);
+drm_output_init_egl(struct drm_output *output, struct drm_backend *b);
 static int
-drm_output_init_pixman(struct drm_output *output, struct drm_compositor *c);
+drm_output_init_pixman(struct drm_output *output, struct drm_backend *b);
 
 static int
 drm_output_switch_mode(struct weston_output *output_base, struct weston_mode *mode)
 {
 	struct drm_output *output;
 	struct drm_mode *drm_mode;
-	struct drm_compositor *ec;
+	struct drm_backend *b;
 
 	if (output_base == NULL) {
 		weston_log("output is NULL.\n");
@@ -1231,7 +1234,7 @@  drm_output_switch_mode(struct weston_output *output_base, struct weston_mode *mo
 		return -1;
 	}
 
-	ec = (struct drm_compositor *)output_base->compositor;
+	b = (struct drm_backend *)output_base->compositor->backend;
 	output = (struct drm_output *)output_base;
 	drm_mode  = choose_mode (output, mode);
 
@@ -1254,9 +1257,9 @@  drm_output_switch_mode(struct weston_output *output_base, struct weston_mode *mo
 	drm_output_release_fb(output, output->next);
 	output->current = output->next = NULL;
 
-	if (ec->use_pixman) {
+	if (b->use_pixman) {
 		drm_output_fini_pixman(output);
-		if (drm_output_init_pixman(output, ec) < 0) {
+		if (drm_output_init_pixman(output, b) < 0) {
 			weston_log("failed to init output pixman state with "
 				   "new mode\n");
 			return -1;
@@ -1265,7 +1268,7 @@  drm_output_switch_mode(struct weston_output *output_base, struct weston_mode *mo
 		gl_renderer->output_destroy(&output->base);
 		gbm_surface_destroy(output->surface);
 
-		if (drm_output_init_egl(output, ec) < 0) {
+		if (drm_output_init_egl(output, b) < 0) {
 			weston_log("failed to init output egl state with "
 				   "new mode");
 			return -1;
@@ -1290,7 +1293,7 @@  on_drm_input(int fd, uint32_t mask, void *data)
 }
 
 static int
-init_drm(struct drm_compositor *ec, struct udev_device *device)
+init_drm(struct drm_backend *b, struct udev_device *device)
 {
 	const char *filename, *sysnum;
 	uint64_t cap;
@@ -1299,14 +1302,14 @@  init_drm(struct drm_compositor *ec, struct udev_device *device)
 
 	sysnum = udev_device_get_sysnum(device);
 	if (sysnum)
-		ec->drm.id = atoi(sysnum);
-	if (!sysnum || ec->drm.id < 0) {
+		b->drm.id = atoi(sysnum);
+	if (!sysnum || b->drm.id < 0) {
 		weston_log("cannot get device sysnum\n");
 		return -1;
 	}
 
 	filename = udev_device_get_devnode(device);
-	fd = weston_launcher_open(ec->base.launcher, filename, O_RDWR);
+	fd = weston_launcher_open(b->compositor->launcher, filename, O_RDWR);
 	if (fd < 0) {
 		/* Probably permissions error */
 		weston_log("couldn't open %s, skipping\n",
@@ -1316,8 +1319,8 @@  init_drm(struct drm_compositor *ec, struct udev_device *device)
 
 	weston_log("using %s\n", filename);
 
-	ec->drm.fd = fd;
-	ec->drm.filename = strdup(filename);
+	b->drm.fd = fd;
+	b->drm.filename = strdup(filename);
 
 	ret = drmGetCap(fd, DRM_CAP_TIMESTAMP_MONOTONIC, &cap);
 	if (ret == 0 && cap == 1)
@@ -1325,7 +1328,7 @@  init_drm(struct drm_compositor *ec, struct udev_device *device)
 	else
 		clk_id = CLOCK_REALTIME;
 
-	if (weston_compositor_set_presentation_clock(&ec->base, clk_id) < 0) {
+	if (weston_compositor_set_presentation_clock(b->compositor, clk_id) < 0) {
 		weston_log("Error: failed to set presentation clock %d.\n",
 			   clk_id);
 		return -1;
@@ -1333,15 +1336,15 @@  init_drm(struct drm_compositor *ec, struct udev_device *device)
 
 	ret = drmGetCap(fd, DRM_CAP_CURSOR_WIDTH, &cap);
 	if (ret == 0)
-		ec->cursor_width = cap;
+		b->cursor_width = cap;
 	else
-		ec->cursor_width = 64;
+		b->cursor_width = 64;
 
 	ret = drmGetCap(fd, DRM_CAP_CURSOR_HEIGHT, &cap);
 	if (ret == 0)
-		ec->cursor_height = cap;
+		b->cursor_height = cap;
 	else
-		ec->cursor_height = 64;
+		b->cursor_height = 64;
 
 	return 0;
 }
@@ -1369,12 +1372,12 @@  create_gbm_device(int fd)
 }
 
 static int
-drm_compositor_create_gl_renderer(struct drm_compositor *ec)
+drm_backend_create_gl_renderer(struct drm_backend *b)
 {
 	EGLint format;
 
-	format = ec->format;
-	if (gl_renderer->create(&ec->base, ec->gbm,
+	format = b->format;
+	if (gl_renderer->create(b->compositor, b->gbm,
 			       gl_renderer->opaque_attribs, &format) < 0) {
 		return -1;
 	}
@@ -1383,15 +1386,15 @@  drm_compositor_create_gl_renderer(struct drm_compositor *ec)
 }
 
 static int
-init_egl(struct drm_compositor *ec)
+init_egl(struct drm_backend *b)
 {
-	ec->gbm = create_gbm_device(ec->drm.fd);
+	b->gbm = create_gbm_device(b->drm.fd);
 
-	if (!ec->gbm)
+	if (!b->gbm)
 		return -1;
 
-	if (drm_compositor_create_gl_renderer(ec) < 0) {
-		gbm_device_destroy(ec->gbm);
+	if (drm_backend_create_gl_renderer(b) < 0) {
+		gbm_device_destroy(b->gbm);
 		return -1;
 	}
 
@@ -1399,9 +1402,9 @@  init_egl(struct drm_compositor *ec)
 }
 
 static int
-init_pixman(struct drm_compositor *ec)
+init_pixman(struct drm_backend *b)
 {
-	return pixman_renderer_init(&ec->base);
+	return pixman_renderer_init(b->compositor);
 }
 
 static struct drm_mode *
@@ -1521,12 +1524,12 @@  drm_set_dpms(struct weston_output *output_base, enum dpms_enum level)
 {
 	struct drm_output *output = (struct drm_output *) output_base;
 	struct weston_compositor *ec = output_base->compositor;
-	struct drm_compositor *c = (struct drm_compositor *) ec;
+	struct drm_backend *b = (struct drm_backend *) ec->backend;
 
 	if (!output->dpms_prop)
 		return;
 
-	drmModeConnectorSetProperty(c->drm.fd, output->connector_id,
+	drmModeConnectorSetProperty(b->drm.fd, output->connector_id,
 				    output->dpms_prop->prop_id, level);
 }
 
@@ -1549,7 +1552,7 @@  static const char *connector_type_names[] = {
 };
 
 static int
-find_crtc_for_connector(struct drm_compositor *ec,
+find_crtc_for_connector(struct drm_backend *b,
 			drmModeRes *resources, drmModeConnector *connector)
 {
 	drmModeEncoder *encoder;
@@ -1557,7 +1560,7 @@  find_crtc_for_connector(struct drm_compositor *ec,
 	int i, j;
 
 	for (j = 0; j < connector->count_encoders; j++) {
-		encoder = drmModeGetEncoder(ec->drm.fd, connector->encoders[j]);
+		encoder = drmModeGetEncoder(b->drm.fd, connector->encoders[j]);
 		if (encoder == NULL) {
 			weston_log("Failed to get encoder.\n");
 			return -1;
@@ -1567,7 +1570,7 @@  find_crtc_for_connector(struct drm_compositor *ec,
 
 		for (i = 0; i < resources->count_crtcs; i++) {
 			if (possible_crtcs & (1 << i) &&
-			    !(ec->crtc_allocator & (1 << resources->crtcs[i])))
+			    !(b->crtc_allocator & (1 << resources->crtcs[i])))
 				return i;
 		}
 	}
@@ -1577,12 +1580,12 @@  find_crtc_for_connector(struct drm_compositor *ec,
 
 /* Init output state that depends on gl or gbm */
 static int
-drm_output_init_egl(struct drm_output *output, struct drm_compositor *ec)
+drm_output_init_egl(struct drm_output *output, struct drm_backend *b)
 {
 	EGLint format = output->format;
 	int i, flags;
 
-	output->surface = gbm_surface_create(ec->gbm,
+	output->surface = gbm_surface_create(b->gbm,
 					     output->base.current_mode->width,
 					     output->base.current_mode->height,
 					     format,
@@ -1608,20 +1611,20 @@  drm_output_init_egl(struct drm_output *output, struct drm_compositor *ec)
 			continue;
 
 		output->cursor_bo[i] =
-			gbm_bo_create(ec->gbm, ec->cursor_width, ec->cursor_height,
+			gbm_bo_create(b->gbm, b->cursor_width, b->cursor_height,
 				GBM_FORMAT_ARGB8888, flags);
 	}
 
 	if (output->cursor_bo[0] == NULL || output->cursor_bo[1] == NULL) {
 		weston_log("cursor buffers unavailable, using gl cursors\n");
-		ec->cursors_are_broken = 1;
+		b->cursors_are_broken = 1;
 	}
 
 	return 0;
 }
 
 static int
-drm_output_init_pixman(struct drm_output *output, struct drm_compositor *c)
+drm_output_init_pixman(struct drm_output *output, struct drm_backend *b)
 {
 	int w = output->base.current_mode->width;
 	int h = output->base.current_mode->height;
@@ -1630,7 +1633,7 @@  drm_output_init_pixman(struct drm_output *output, struct drm_compositor *c)
 	/* FIXME error checking */
 
 	for (i = 0; i < ARRAY_LENGTH(output->dumb); i++) {
-		output->dumb[i] = drm_fb_create_dumb(c, w, h);
+		output->dumb[i] = drm_fb_create_dumb(b, w, h);
 		if (!output->dumb[i])
 			goto err;
 
@@ -1776,7 +1779,7 @@  edid_parse(struct drm_edid *edid, const uint8_t *data, size_t length)
 }
 
 static void
-find_and_parse_output_edid(struct drm_compositor *ec,
+find_and_parse_output_edid(struct drm_backend *b,
 			   struct drm_output *output,
 			   drmModeConnector *connector)
 {
@@ -1786,12 +1789,12 @@  find_and_parse_output_edid(struct drm_compositor *ec,
 	int rc;
 
 	for (i = 0; i < connector->count_props && !edid_blob; i++) {
-		property = drmModeGetProperty(ec->drm.fd, connector->props[i]);
+		property = drmModeGetProperty(b->drm.fd, connector->props[i]);
 		if (!property)
 			continue;
 		if ((property->flags & DRM_MODE_PROP_BLOB) &&
 		    !strcmp(property->name, "EDID")) {
-			edid_blob = drmModeGetPropertyBlob(ec->drm.fd,
+			edid_blob = drmModeGetPropertyBlob(b->drm.fd,
 							   connector->prop_values[i]);
 		}
 		drmModeFreeProperty(property);
@@ -1863,14 +1866,14 @@  parse_modeline(const char *s, drmModeModeInfo *mode)
 }
 
 static void
-setup_output_seat_constraint(struct drm_compositor *ec,
+setup_output_seat_constraint(struct drm_backend *b,
 			     struct weston_output *output,
 			     const char *s)
 {
 	if (strcmp(s, "") != 0) {
 		struct udev_seat *seat;
 
-		seat = udev_seat_get_named(&ec->input, s);
+		seat = udev_seat_get_named(&b->input, s);
 		if (seat)
 			seat->base.output = output;
 
@@ -1911,7 +1914,7 @@  get_gbm_format_from_section(struct weston_config_section *section,
 }
 
 static int
-create_output_for_connector(struct drm_compositor *ec,
+create_output_for_connector(struct drm_backend *b,
 			    drmModeRes *resources,
 			    drmModeConnector *connector,
 			    int x, int y, struct udev_device *drm_device)
@@ -1929,7 +1932,7 @@  create_output_for_connector(struct drm_compositor *ec,
 	enum output_config config;
 	uint32_t transform;
 
-	i = find_crtc_for_connector(ec, resources, connector);
+	i = find_crtc_for_connector(b, resources, connector);
 	if (i < 0) {
 		weston_log("No usable crtc/encoder pair for connector.\n");
 		return -1;
@@ -1952,7 +1955,7 @@  create_output_for_connector(struct drm_compositor *ec,
 	snprintf(name, 32, "%s%d", type_name, connector->connector_type_id);
 	output->base.name = strdup(name);
 
-	section = weston_config_get_section(ec->base.config, "output", "name",
+	section = weston_config_get_section(b->compositor->config, "output", "name",
 					    output->base.name);
 	weston_config_section_get_string(section, "mode", &s, "preferred");
 	if (strcmp(s, "off") == 0)
@@ -1981,29 +1984,29 @@  create_output_for_connector(struct drm_compositor *ec,
 	free(s);
 
 	if (get_gbm_format_from_section(section,
-					ec->format,
+					b->format,
 					&output->format) == -1)
-		output->format = ec->format;
+		output->format = b->format;
 
 	weston_config_section_get_string(section, "seat", &s, "");
-	setup_output_seat_constraint(ec, &output->base, s);
+	setup_output_seat_constraint(b, &output->base, s);
 	free(s);
 
 	output->crtc_id = resources->crtcs[i];
 	output->pipe = i;
-	ec->crtc_allocator |= (1 << output->crtc_id);
+	b->crtc_allocator |= (1 << output->crtc_id);
 	output->connector_id = connector->connector_id;
-	ec->connector_allocator |= (1 << output->connector_id);
+	b->connector_allocator |= (1 << output->connector_id);
 
-	output->original_crtc = drmModeGetCrtc(ec->drm.fd, output->crtc_id);
-	output->dpms_prop = drm_get_prop(ec->drm.fd, connector, "DPMS");
+	output->original_crtc = drmModeGetCrtc(b->drm.fd, output->crtc_id);
+	output->dpms_prop = drm_get_prop(b->drm.fd, connector, "DPMS");
 
 	/* Get the current mode on the crtc that's currently driving
 	 * this connector. */
-	encoder = drmModeGetEncoder(ec->drm.fd, connector->encoder_id);
+	encoder = drmModeGetEncoder(b->drm.fd, connector->encoder_id);
 	memset(&crtc_mode, 0, sizeof crtc_mode);
 	if (encoder != NULL) {
-		crtc = drmModeGetCrtc(ec->drm.fd, encoder->crtc_id);
+		crtc = drmModeGetCrtc(b->drm.fd, encoder->crtc_id);
 		drmModeFreeEncoder(encoder);
 		if (crtc == NULL)
 			goto err_free;
@@ -2020,7 +2023,7 @@  create_output_for_connector(struct drm_compositor *ec,
 
 	if (config == OUTPUT_CONFIG_OFF) {
 		weston_log("Disabling output %s\n", output->base.name);
-		drmModeSetCrtc(ec->drm.fd, output->crtc_id,
+		drmModeSetCrtc(b->drm.fd, output->crtc_id,
 			       0, 0, 0, 0, 0, NULL);
 		goto err_free;
 	}
@@ -2075,16 +2078,16 @@  create_output_for_connector(struct drm_compositor *ec,
 
 	output->base.current_mode->flags |= WL_OUTPUT_MODE_CURRENT;
 
-	weston_output_init(&output->base, &ec->base, x, y,
+	weston_output_init(&output->base, b->compositor, x, y,
 			   connector->mmWidth, connector->mmHeight,
 			   transform, scale);
 
-	if (ec->use_pixman) {
-		if (drm_output_init_pixman(output, ec) < 0) {
+	if (b->use_pixman) {
+		if (drm_output_init_pixman(output, b) < 0) {
 			weston_log("Failed to init output pixman state\n");
 			goto err_output;
 		}
-	} else if (drm_output_init_egl(output, ec) < 0) {
+	} else if (drm_output_init_egl(output, b) < 0) {
 		weston_log("Failed to init output gl state\n");
 		goto err_output;
 	}
@@ -2100,9 +2103,9 @@  create_output_for_connector(struct drm_compositor *ec,
 		weston_log("Failed to initialize backlight\n");
 	}
 
-	wl_list_insert(ec->base.output_list.prev, &output->base.link);
+	wl_list_insert(b->compositor->output_list.prev, &output->base.link);
 
-	find_and_parse_output_edid(ec, output, connector);
+	find_and_parse_output_edid(b, output, connector);
 	if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)
 		output->base.connection_internal = 1;
 
@@ -2116,12 +2119,12 @@  create_output_for_connector(struct drm_compositor *ec,
 	output->base.gamma_size = output->original_crtc->gamma_size;
 	output->base.set_gamma = drm_output_set_gamma;
 
-	weston_plane_init(&output->cursor_plane, &ec->base, 0, 0);
-	weston_plane_init(&output->fb_plane, &ec->base, 0, 0);
+	weston_plane_init(&output->cursor_plane, b->compositor, 0, 0);
+	weston_plane_init(&output->fb_plane, b->compositor, 0, 0);
 
-	weston_compositor_stack_plane(&ec->base, &output->cursor_plane, NULL);
-	weston_compositor_stack_plane(&ec->base, &output->fb_plane,
-				      &ec->base.primary_plane);
+	weston_compositor_stack_plane(b->compositor, &output->cursor_plane, NULL);
+	weston_compositor_stack_plane(b->compositor, &output->fb_plane,
+				      &b->compositor->primary_plane);
 
 	weston_log("Output %s, (connector %d, crtc %d)\n",
 		   output->base.name, output->connector_id, output->crtc_id);
@@ -2147,22 +2150,22 @@  err_free:
 	}
 
 	drmModeFreeCrtc(output->original_crtc);
-	ec->crtc_allocator &= ~(1 << output->crtc_id);
-	ec->connector_allocator &= ~(1 << output->connector_id);
+	b->crtc_allocator &= ~(1 << output->crtc_id);
+	b->connector_allocator &= ~(1 << output->connector_id);
 	free(output);
 
 	return -1;
 }
 
 static void
-create_sprites(struct drm_compositor *ec)
+create_sprites(struct drm_backend *b)
 {
 	struct drm_sprite *sprite;
 	drmModePlaneRes *plane_res;
 	drmModePlane *plane;
 	uint32_t i;
 
-	plane_res = drmModeGetPlaneResources(ec->drm.fd);
+	plane_res = drmModeGetPlaneResources(b->drm.fd);
 	if (!plane_res) {
 		weston_log("failed to get plane resources: %s\n",
 			strerror(errno));
@@ -2170,7 +2173,7 @@  create_sprites(struct drm_compositor *ec)
 	}
 
 	for (i = 0; i < plane_res->count_planes; i++) {
-		plane = drmModeGetPlane(ec->drm.fd, plane_res->planes[i]);
+		plane = drmModeGetPlane(b->drm.fd, plane_res->planes[i]);
 		if (!plane)
 			continue;
 
@@ -2187,32 +2190,32 @@  create_sprites(struct drm_compositor *ec)
 		sprite->plane_id = plane->plane_id;
 		sprite->current = NULL;
 		sprite->next = NULL;
-		sprite->compositor = ec;
+		sprite->backend = b;
 		sprite->count_formats = plane->count_formats;
 		memcpy(sprite->formats, plane->formats,
 		       plane->count_formats * sizeof(plane->formats[0]));
 		drmModeFreePlane(plane);
-		weston_plane_init(&sprite->plane, &ec->base, 0, 0);
-		weston_compositor_stack_plane(&ec->base, &sprite->plane,
-					      &ec->base.primary_plane);
+		weston_plane_init(&sprite->plane, b->compositor, 0, 0);
+		weston_compositor_stack_plane(b->compositor, &sprite->plane,
+					      &b->compositor->primary_plane);
 
-		wl_list_insert(&ec->sprite_list, &sprite->link);
+		wl_list_insert(&b->sprite_list, &sprite->link);
 	}
 
 	drmModeFreePlaneResources(plane_res);
 }
 
 static void
-destroy_sprites(struct drm_compositor *compositor)
+destroy_sprites(struct drm_backend *backend)
 {
 	struct drm_sprite *sprite, *next;
 	struct drm_output *output;
 
-	output = container_of(compositor->base.output_list.next,
+	output = container_of(backend->compositor->output_list.next,
 			      struct drm_output, base.link);
 
-	wl_list_for_each_safe(sprite, next, &compositor->sprite_list, link) {
-		drmModeSetPlane(compositor->drm.fd,
+	wl_list_for_each_safe(sprite, next, &backend->sprite_list, link) {
+		drmModeSetPlane(backend->drm.fd,
 				sprite->plane_id,
 				output->crtc_id, 0, 0,
 				0, 0, 0, 0, 0, 0, 0, 0);
@@ -2224,7 +2227,7 @@  destroy_sprites(struct drm_compositor *compositor)
 }
 
 static int
-create_outputs(struct drm_compositor *ec, uint32_t option_connector,
+create_outputs(struct drm_backend *b, uint32_t option_connector,
 	       struct udev_device *drm_device)
 {
 	drmModeConnector *connector;
@@ -2232,28 +2235,28 @@  create_outputs(struct drm_compositor *ec, uint32_t option_connector,
 	int i;
 	int x = 0, y = 0;
 
-	resources = drmModeGetResources(ec->drm.fd);
+	resources = drmModeGetResources(b->drm.fd);
 	if (!resources) {
 		weston_log("drmModeGetResources failed\n");
 		return -1;
 	}
 
-	ec->crtcs = calloc(resources->count_crtcs, sizeof(uint32_t));
-	if (!ec->crtcs) {
+	b->crtcs = calloc(resources->count_crtcs, sizeof(uint32_t));
+	if (!b->crtcs) {
 		drmModeFreeResources(resources);
 		return -1;
 	}
 
-	ec->min_width  = resources->min_width;
-	ec->max_width  = resources->max_width;
-	ec->min_height = resources->min_height;
-	ec->max_height = resources->max_height;
+	b->min_width  = resources->min_width;
+	b->max_width  = resources->max_width;
+	b->min_height = resources->min_height;
+	b->max_height = resources->max_height;
 
-	ec->num_crtcs = resources->count_crtcs;
-	memcpy(ec->crtcs, resources->crtcs, sizeof(uint32_t) * ec->num_crtcs);
+	b->num_crtcs = resources->count_crtcs;
+	memcpy(b->crtcs, resources->crtcs, sizeof(uint32_t) * b->num_crtcs);
 
 	for (i = 0; i < resources->count_connectors; i++) {
-		connector = drmModeGetConnector(ec->drm.fd,
+		connector = drmModeGetConnector(b->drm.fd,
 						resources->connectors[i]);
 		if (connector == NULL)
 			continue;
@@ -2261,14 +2264,14 @@  create_outputs(struct drm_compositor *ec, uint32_t option_connector,
 		if (connector->connection == DRM_MODE_CONNECTED &&
 		    (option_connector == 0 ||
 		     connector->connector_id == option_connector)) {
-			if (create_output_for_connector(ec, resources,
+			if (create_output_for_connector(b, resources,
 							connector, x, y,
 							drm_device) < 0) {
 				drmModeFreeConnector(connector);
 				continue;
 			}
 
-			x += container_of(ec->base.output_list.prev,
+			x += container_of(b->compositor->output_list.prev,
 					  struct weston_output,
 					  link)->width;
 		}
@@ -2276,7 +2279,7 @@  create_outputs(struct drm_compositor *ec, uint32_t option_connector,
 		drmModeFreeConnector(connector);
 	}
 
-	if (wl_list_empty(&ec->base.output_list)) {
+	if (wl_list_empty(&b->compositor->output_list)) {
 		weston_log("No currently active connector found.\n");
 		drmModeFreeResources(resources);
 		return -1;
@@ -2288,7 +2291,7 @@  create_outputs(struct drm_compositor *ec, uint32_t option_connector,
 }
 
 static void
-update_outputs(struct drm_compositor *ec, struct udev_device *drm_device)
+update_outputs(struct drm_backend *b, struct udev_device *drm_device)
 {
 	drmModeConnector *connector;
 	drmModeRes *resources;
@@ -2297,7 +2300,7 @@  update_outputs(struct drm_compositor *ec, struct udev_device *drm_device)
 	uint32_t connected = 0, disconnects = 0;
 	int i;
 
-	resources = drmModeGetResources(ec->drm.fd);
+	resources = drmModeGetResources(b->drm.fd);
 	if (!resources) {
 		weston_log("drmModeGetResources failed\n");
 		return;
@@ -2307,7 +2310,7 @@  update_outputs(struct drm_compositor *ec, struct udev_device *drm_device)
 	for (i = 0; i < resources->count_connectors; i++) {
 		int connector_id = resources->connectors[i];
 
-		connector = drmModeGetConnector(ec->drm.fd, connector_id);
+		connector = drmModeGetConnector(b->drm.fd, connector_id);
 		if (connector == NULL)
 			continue;
 
@@ -2318,18 +2321,18 @@  update_outputs(struct drm_compositor *ec, struct udev_device *drm_device)
 
 		connected |= (1 << connector_id);
 
-		if (!(ec->connector_allocator & (1 << connector_id))) {
+		if (!(b->connector_allocator & (1 << connector_id))) {
 			struct weston_output *last =
-				container_of(ec->base.output_list.prev,
+				container_of(b->compositor->output_list.prev,
 					     struct weston_output, link);
 
 			/* XXX: not yet needed, we die with 0 outputs */
-			if (!wl_list_empty(&ec->base.output_list))
+			if (!wl_list_empty(&b->compositor->output_list))
 				x = last->x + last->width;
 			else
 				x = 0;
 			y = 0;
-			create_output_for_connector(ec, resources,
+			create_output_for_connector(b, resources,
 						    connector, x, y,
 						    drm_device);
 			weston_log("connector %d connected\n", connector_id);
@@ -2339,9 +2342,9 @@  update_outputs(struct drm_compositor *ec, struct udev_device *drm_device)
 	}
 	drmModeFreeResources(resources);
 
-	disconnects = ec->connector_allocator & ~connected;
+	disconnects = b->connector_allocator & ~connected;
 	if (disconnects) {
-		wl_list_for_each_safe(output, next, &ec->base.output_list,
+		wl_list_for_each_safe(output, next, &b->compositor->output_list,
 				      base.link) {
 			if (disconnects & (1 << output->connector_id)) {
 				disconnects &= ~(1 << output->connector_id);
@@ -2353,18 +2356,18 @@  update_outputs(struct drm_compositor *ec, struct udev_device *drm_device)
 	}
 
 	/* FIXME: handle zero outputs, without terminating */	
-	if (ec->connector_allocator == 0)
-		wl_display_terminate(ec->base.wl_display);
+	if (b->connector_allocator == 0)
+		wl_display_terminate(b->compositor->wl_display);
 }
 
 static int
-udev_event_is_hotplug(struct drm_compositor *ec, struct udev_device *device)
+udev_event_is_hotplug(struct drm_backend *b, struct udev_device *device)
 {
 	const char *sysnum;
 	const char *val;
 
 	sysnum = udev_device_get_sysnum(device);
-	if (!sysnum || atoi(sysnum) != ec->drm.id)
+	if (!sysnum || atoi(sysnum) != b->drm.id)
 		return 0;
 
 	val = udev_device_get_property_value(device, "HOTPLUG");
@@ -2377,13 +2380,13 @@  udev_event_is_hotplug(struct drm_compositor *ec, struct udev_device *device)
 static int
 udev_drm_event(int fd, uint32_t mask, void *data)
 {
-	struct drm_compositor *ec = data;
+	struct drm_backend *b = data;
 	struct udev_device *event;
 
-	event = udev_monitor_receive_device(ec->udev_monitor);
+	event = udev_monitor_receive_device(b->udev_monitor);
 
-	if (udev_event_is_hotplug(ec, event))
-		update_outputs(ec, event);
+	if (udev_event_is_hotplug(b, event))
+		update_outputs(b, event);
 
 	udev_device_unref(event);
 
@@ -2399,35 +2402,35 @@  drm_restore(struct weston_compositor *ec)
 static void
 drm_destroy(struct weston_compositor *ec)
 {
-	struct drm_compositor *d = (struct drm_compositor *) ec;
+	struct drm_backend *b = (struct drm_backend *) ec->backend;
 
-	udev_input_destroy(&d->input);
+	udev_input_destroy(&b->input);
 
-	wl_event_source_remove(d->udev_drm_source);
-	wl_event_source_remove(d->drm_source);
+	wl_event_source_remove(b->udev_drm_source);
+	wl_event_source_remove(b->drm_source);
 
-	destroy_sprites(d);
+	destroy_sprites(b);
 
 	weston_compositor_shutdown(ec);
 
-	if (d->gbm)
-		gbm_device_destroy(d->gbm);
+	if (b->gbm)
+		gbm_device_destroy(b->gbm);
 
-	weston_launcher_destroy(d->base.launcher);
+	weston_launcher_destroy(ec->launcher);
 
-	close(d->drm.fd);
+	close(b->drm.fd);
 
-	free(d);
+	free(b);
 }
 
 static void
-drm_compositor_set_modes(struct drm_compositor *compositor)
+drm_backend_set_modes(struct drm_backend *backend)
 {
 	struct drm_output *output;
 	struct drm_mode *drm_mode;
 	int ret;
 
-	wl_list_for_each(output, &compositor->base.output_list, base.link) {
+	wl_list_for_each(output, &backend->compositor->output_list, base.link) {
 		if (!output->current) {
 			/* If something that would cause the output to
 			 * switch mode happened while in another vt, we
@@ -2439,7 +2442,7 @@  drm_compositor_set_modes(struct drm_compositor *compositor)
 		}
 
 		drm_mode = (struct drm_mode *) output->base.current_mode;
-		ret = drmModeSetCrtc(compositor->drm.fd, output->crtc_id,
+		ret = drmModeSetCrtc(backend->drm.fd, output->crtc_id,
 				     output->current->fb_id, 0, 0,
 				     &output->connector_id, 1,
 				     &drm_mode->mode_info);
@@ -2456,21 +2459,21 @@  static void
 session_notify(struct wl_listener *listener, void *data)
 {
 	struct weston_compositor *compositor = data;
-	struct drm_compositor *ec = data;
+	struct drm_backend *b = (struct drm_backend *)compositor->backend;
 	struct drm_sprite *sprite;
 	struct drm_output *output;
 
-	if (ec->base.session_active) {
+	if (compositor->session_active) {
 		weston_log("activating session\n");
-		compositor->state = ec->prev_state;
-		drm_compositor_set_modes(ec);
+		compositor->state = b->prev_state;
+		drm_backend_set_modes(b);
 		weston_compositor_damage_all(compositor);
-		udev_input_enable(&ec->input);
+		udev_input_enable(&b->input);
 	} else {
 		weston_log("deactivating session\n");
-		udev_input_disable(&ec->input);
+		udev_input_disable(&b->input);
 
-		ec->prev_state = compositor->state;
+		b->prev_state = compositor->state;
 		weston_compositor_offscreen(compositor);
 
 		/* If we have a repaint scheduled (either from a
@@ -2481,16 +2484,16 @@  session_notify(struct wl_listener *listener, void *data)
 		 * back, we schedule a repaint, which will process
 		 * pending frame callbacks. */
 
-		wl_list_for_each(output, &ec->base.output_list, base.link) {
+		wl_list_for_each(output, &compositor->output_list, base.link) {
 			output->base.repaint_needed = 0;
-			drmModeSetCursor(ec->drm.fd, output->crtc_id, 0, 0, 0);
+			drmModeSetCursor(b->drm.fd, output->crtc_id, 0, 0, 0);
 		}
 
-		output = container_of(ec->base.output_list.next,
+		output = container_of(compositor->output_list.next,
 				      struct drm_output, base.link);
 
-		wl_list_for_each(sprite, &ec->sprite_list, link)
-			drmModeSetPlane(ec->drm.fd,
+		wl_list_for_each(sprite, &b->sprite_list, link)
+			drmModeSetPlane(b->drm.fd,
 					sprite->plane_id,
 					output->crtc_id, 0, 0,
 					0, 0, 0, 0, 0, 0, 0, 0);
@@ -2513,14 +2516,14 @@  switch_vt_binding(struct weston_seat *seat, uint32_t time, uint32_t key, void *d
  * If no such device is found, the first DRM device reported by udev is used.
  */
 static struct udev_device*
-find_primary_gpu(struct drm_compositor *ec, const char *seat)
+find_primary_gpu(struct drm_backend *b, const char *seat)
 {
 	struct udev_enumerate *e;
 	struct udev_list_entry *entry;
 	const char *path, *device_seat, *id;
 	struct udev_device *device, *drm_device, *pci;
 
-	e = udev_enumerate_new(ec->udev);
+	e = udev_enumerate_new(b->udev);
 	udev_enumerate_add_match_subsystem(e, "drm");
 	udev_enumerate_add_match_sysname(e, "card[0-9]*");
 
@@ -2528,7 +2531,7 @@  find_primary_gpu(struct drm_compositor *ec, const char *seat)
 	drm_device = NULL;
 	udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(e)) {
 		path = udev_list_entry_get_name(entry);
-		device = udev_device_new_from_syspath(ec->udev, path);
+		device = udev_device_new_from_syspath(b->udev, path);
 		if (!device)
 			continue;
 		device_seat = udev_device_get_property_value(device, "ID_SEAT");
@@ -2564,17 +2567,17 @@  find_primary_gpu(struct drm_compositor *ec, const char *seat)
 static void
 planes_binding(struct weston_seat *seat, uint32_t time, uint32_t key, void *data)
 {
-	struct drm_compositor *c = data;
+	struct drm_backend *b = data;
 
 	switch (key) {
 	case KEY_C:
-		c->cursors_are_broken ^= 1;
+		b->cursors_are_broken ^= 1;
 		break;
 	case KEY_V:
-		c->sprites_are_broken ^= 1;
+		b->sprites_are_broken ^= 1;
 		break;
 	case KEY_O:
-		c->sprites_hidden ^= 1;
+		b->sprites_hidden ^= 1;
 		break;
 	default:
 		break;
@@ -2598,17 +2601,17 @@  static void
 recorder_frame_notify(struct wl_listener *listener, void *data)
 {
 	struct drm_output *output;
-	struct drm_compositor *c;
+	struct drm_backend *b;
 	int fd, ret;
 
 	output = container_of(listener, struct drm_output,
 			      recorder_frame_listener);
-	c = (struct drm_compositor *) output->base.compositor;
+	b = (struct drm_backend *) output->base.compositor->backend;
 
 	if (!output->recorder)
 		return;
 
-	ret = drmPrimeHandleToFD(c->drm.fd, output->current->handle,
+	ret = drmPrimeHandleToFD(b->drm.fd, output->current->handle,
 				 DRM_CLOEXEC, &fd);
 	if (ret) {
 		weston_log("[libva recorder] "
@@ -2625,18 +2628,18 @@  recorder_frame_notify(struct wl_listener *listener, void *data)
 }
 
 static void *
-create_recorder(struct drm_compositor *c, int width, int height,
+create_recorder(struct drm_backend *b, int width, int height,
 		const char *filename)
 {
 	int fd;
 	drm_magic_t magic;
 
-	fd = open(c->drm.filename, O_RDWR | O_CLOEXEC);
+	fd = open(b->drm.filename, O_RDWR | O_CLOEXEC);
 	if (fd < 0)
 		return NULL;
 
 	drmGetMagic(fd, &magic);
-	drmAuthMagic(c->drm.fd, magic);
+	drmAuthMagic(b->drm.fd, magic);
 
 	return vaapi_recorder_create(fd, width, height, filename);
 }
@@ -2645,11 +2648,11 @@  static void
 recorder_binding(struct weston_seat *seat, uint32_t time, uint32_t key,
 		 void *data)
 {
-	struct drm_compositor *c = data;
+	struct drm_backend *b = data;
 	struct drm_output *output;
 	int width, height;
 
-	output = container_of(c->base.output_list.next,
+	output = container_of(b->compositor->output_list.next,
 			      struct drm_output, base.link);
 
 	if (!output->recorder) {
@@ -2663,7 +2666,7 @@  recorder_binding(struct weston_seat *seat, uint32_t time, uint32_t key,
 		height = output->base.current_mode->height;
 
 		output->recorder =
-			create_recorder(c, width, height, "capture.h264");
+			create_recorder(b, width, height, "capture.h264");
 		if (!output->recorder) {
 			weston_log("failed to create vaapi recorder\n");
 			return;
@@ -2692,56 +2695,56 @@  recorder_binding(struct weston_seat *seat, uint32_t time, uint32_t key,
 #endif
 
 static void
-switch_to_gl_renderer(struct drm_compositor *c)
+switch_to_gl_renderer(struct drm_backend *b)
 {
 	struct drm_output *output;
 
-	if (!c->use_pixman)
+	if (!b->use_pixman)
 		return;
 
 	weston_log("Switching to GL renderer\n");
 
-	c->gbm = create_gbm_device(c->drm.fd);
-	if (!c->gbm) {
+	b->gbm = create_gbm_device(b->drm.fd);
+	if (!b->gbm) {
 		weston_log("Failed to create gbm device. "
 			   "Aborting renderer switch\n");
 		return;
 	}
 
-	wl_list_for_each(output, &c->base.output_list, base.link)
+	wl_list_for_each(output, &b->compositor->output_list, base.link)
 		pixman_renderer_output_destroy(&output->base);
 
-	c->base.renderer->destroy(&c->base);
+	b->compositor->renderer->destroy(b->compositor);
 
-	if (drm_compositor_create_gl_renderer(c) < 0) {
-		gbm_device_destroy(c->gbm);
+	if (drm_backend_create_gl_renderer(b) < 0) {
+		gbm_device_destroy(b->gbm);
 		weston_log("Failed to create GL renderer. Quitting.\n");
 		/* FIXME: we need a function to shutdown cleanly */
 		assert(0);
 	}
 
-	wl_list_for_each(output, &c->base.output_list, base.link)
-		drm_output_init_egl(output, c);
+	wl_list_for_each(output, &b->compositor->output_list, base.link)
+		drm_output_init_egl(output, b);
 
-	c->use_pixman = 0;
+	b->use_pixman = 0;
 }
 
 static void
 renderer_switch_binding(struct weston_seat *seat, uint32_t time, uint32_t key,
 			void *data)
 {
-	struct drm_compositor *c = (struct drm_compositor *) seat->compositor;
+	struct drm_backend *b = (struct drm_backend *) seat->compositor->backend;
 
-	switch_to_gl_renderer(c);
+	switch_to_gl_renderer(b);
 }
 
-static struct weston_compositor *
-drm_compositor_create(struct wl_display *display,
+static struct drm_backend *
+drm_backend_create(struct weston_compositor *compositor,
 		      struct drm_parameters *param,
 		      int *argc, char *argv[],
 		      struct weston_config *config)
 {
-	struct drm_compositor *ec;
+	struct drm_backend *b;
 	struct weston_config_section *section;
 	struct udev_device *drm_device;
 	struct wl_event_loop *loop;
@@ -2750,167 +2753,169 @@  drm_compositor_create(struct wl_display *display,
 
 	weston_log("initializing drm backend\n");
 
-	ec = zalloc(sizeof *ec);
-	if (ec == NULL)
+	b = zalloc(sizeof *b);
+	if (b == NULL)
 		return NULL;
 
 	/* KMS support for sprites is not complete yet, so disable the
 	 * functionality for now. */
-	ec->sprites_are_broken = 1;
+	b->sprites_are_broken = 1;
+	b->compositor = compositor;
 
 	section = weston_config_get_section(config, "core", NULL, NULL);
 	if (get_gbm_format_from_section(section,
 					GBM_FORMAT_XRGB8888,
-					&ec->format) == -1)
+					&b->format) == -1)
 		goto err_base;
 
-	ec->use_pixman = param->use_pixman;
+	b->use_pixman = param->use_pixman;
 
-	if (weston_compositor_init(&ec->base, display, argc, argv,
+	if (weston_compositor_init(compositor, argc, argv,
 				   config) < 0) {
 		weston_log("%s failed\n", __func__);
 		goto err_base;
 	}
 
 	/* Check if we run drm-backend using weston-launch */
-	ec->base.launcher = weston_launcher_connect(&ec->base, param->tty,
-						    param->seat_id);
-	if (ec->base.launcher == NULL) {
+	compositor->launcher = weston_launcher_connect(compositor, param->tty,
+						       param->seat_id);
+	if (compositor->launcher == NULL) {
 		weston_log("fatal: drm backend should be run "
 			   "using weston-launch binary or as root\n");
 		goto err_compositor;
 	}
 
-	ec->udev = udev_new();
-	if (ec->udev == NULL) {
+	b->udev = udev_new();
+	if (b->udev == NULL) {
 		weston_log("failed to initialize udev context\n");
 		goto err_launcher;
 	}
 
-	ec->base.wl_display = display;
-	ec->session_listener.notify = session_notify;
-	wl_signal_add(&ec->base.session_signal, &ec->session_listener);
+	b->session_listener.notify = session_notify;
+	wl_signal_add(&compositor->session_signal, &b->session_listener);
 
-	drm_device = find_primary_gpu(ec, param->seat_id);
+	drm_device = find_primary_gpu(b, param->seat_id);
 	if (drm_device == NULL) {
 		weston_log("no drm device found\n");
 		goto err_udev;
 	}
 	path = udev_device_get_syspath(drm_device);
 
-	if (init_drm(ec, drm_device) < 0) {
+	if (init_drm(b, drm_device) < 0) {
 		weston_log("failed to initialize kms\n");
 		goto err_udev_dev;
 	}
 
-	if (ec->use_pixman) {
-		if (init_pixman(ec) < 0) {
+	if (b->use_pixman) {
+		if (init_pixman(b) < 0) {
 			weston_log("failed to initialize pixman renderer\n");
 			goto err_udev_dev;
 		}
 	} else {
-		if (init_egl(ec) < 0) {
+		if (init_egl(b) < 0) {
 			weston_log("failed to initialize egl\n");
 			goto err_udev_dev;
 		}
 	}
 
-	ec->base.destroy = drm_destroy;
-	ec->base.restore = drm_restore;
+	b->base.destroy = drm_destroy;
+	b->base.restore = drm_restore;
 
-	ec->prev_state = WESTON_COMPOSITOR_ACTIVE;
+	b->prev_state = WESTON_COMPOSITOR_ACTIVE;
 
 	for (key = KEY_F1; key < KEY_F9; key++)
-		weston_compositor_add_key_binding(&ec->base, key,
+		weston_compositor_add_key_binding(compositor, key,
 						  MODIFIER_CTRL | MODIFIER_ALT,
-						  switch_vt_binding, ec);
+						  switch_vt_binding, b);
 
-	wl_list_init(&ec->sprite_list);
-	create_sprites(ec);
+	wl_list_init(&b->sprite_list);
+	create_sprites(b);
 
-	if (udev_input_init(&ec->input,
-			    &ec->base, ec->udev, param->seat_id) < 0) {
+	if (udev_input_init(&b->input,
+			    compositor, b->udev, param->seat_id) < 0) {
 		weston_log("failed to create input devices\n");
 		goto err_sprite;
 	}
 
-	if (create_outputs(ec, param->connector, drm_device) < 0) {
+	if (create_outputs(b, param->connector, drm_device) < 0) {
 		weston_log("failed to create output for %s\n", path);
 		goto err_udev_input;
 	}
 
 	/* A this point we have some idea of whether or not we have a working
 	 * cursor plane. */
-	if (!ec->cursors_are_broken)
-		ec->base.capabilities |= WESTON_CAP_CURSOR_PLANE;
+	if (!b->cursors_are_broken)
+		compositor->capabilities |= WESTON_CAP_CURSOR_PLANE;
 
 	path = NULL;
 
-	loop = wl_display_get_event_loop(ec->base.wl_display);
-	ec->drm_source =
-		wl_event_loop_add_fd(loop, ec->drm.fd,
-				     WL_EVENT_READABLE, on_drm_input, ec);
+	loop = wl_display_get_event_loop(compositor->wl_display);
+	b->drm_source =
+		wl_event_loop_add_fd(loop, b->drm.fd,
+				     WL_EVENT_READABLE, on_drm_input, b);
 
-	ec->udev_monitor = udev_monitor_new_from_netlink(ec->udev, "udev");
-	if (ec->udev_monitor == NULL) {
+	b->udev_monitor = udev_monitor_new_from_netlink(b->udev, "udev");
+	if (b->udev_monitor == NULL) {
 		weston_log("failed to intialize udev monitor\n");
 		goto err_drm_source;
 	}
-	udev_monitor_filter_add_match_subsystem_devtype(ec->udev_monitor,
+	udev_monitor_filter_add_match_subsystem_devtype(b->udev_monitor,
 							"drm", NULL);
-	ec->udev_drm_source =
+	b->udev_drm_source =
 		wl_event_loop_add_fd(loop,
-				     udev_monitor_get_fd(ec->udev_monitor),
-				     WL_EVENT_READABLE, udev_drm_event, ec);
+				     udev_monitor_get_fd(b->udev_monitor),
+				     WL_EVENT_READABLE, udev_drm_event, b);
 
-	if (udev_monitor_enable_receiving(ec->udev_monitor) < 0) {
+	if (udev_monitor_enable_receiving(b->udev_monitor) < 0) {
 		weston_log("failed to enable udev-monitor receiving\n");
 		goto err_udev_monitor;
 	}
 
 	udev_device_unref(drm_device);
 
-	weston_compositor_add_debug_binding(&ec->base, KEY_O,
-					    planes_binding, ec);
-	weston_compositor_add_debug_binding(&ec->base, KEY_C,
-					    planes_binding, ec);
-	weston_compositor_add_debug_binding(&ec->base, KEY_V,
-					    planes_binding, ec);
-	weston_compositor_add_debug_binding(&ec->base, KEY_Q,
-					    recorder_binding, ec);
-	weston_compositor_add_debug_binding(&ec->base, KEY_W,
-					    renderer_switch_binding, ec);
+	weston_compositor_add_debug_binding(compositor, KEY_O,
+					    planes_binding, b);
+	weston_compositor_add_debug_binding(compositor, KEY_C,
+					    planes_binding, b);
+	weston_compositor_add_debug_binding(compositor, KEY_V,
+					    planes_binding, b);
+	weston_compositor_add_debug_binding(compositor, KEY_Q,
+					    recorder_binding, b);
+	weston_compositor_add_debug_binding(compositor, KEY_W,
+					    renderer_switch_binding, b);
 
-	return &ec->base;
+	compositor->backend = &b->base;
+	return b;
 
 err_udev_monitor:
-	wl_event_source_remove(ec->udev_drm_source);
-	udev_monitor_unref(ec->udev_monitor);
+	wl_event_source_remove(b->udev_drm_source);
+	udev_monitor_unref(b->udev_monitor);
 err_drm_source:
-	wl_event_source_remove(ec->drm_source);
+	wl_event_source_remove(b->drm_source);
 err_udev_input:
-	udev_input_destroy(&ec->input);
+	udev_input_destroy(&b->input);
 err_sprite:
-	ec->base.renderer->destroy(&ec->base);
-	gbm_device_destroy(ec->gbm);
-	destroy_sprites(ec);
+	compositor->renderer->destroy(compositor);
+	gbm_device_destroy(b->gbm);
+	destroy_sprites(b);
 err_udev_dev:
 	udev_device_unref(drm_device);
 err_launcher:
-	weston_launcher_destroy(ec->base.launcher);
+	weston_launcher_destroy(compositor->launcher);
 err_udev:
-	udev_unref(ec->udev);
+	udev_unref(b->udev);
 err_compositor:
-	weston_compositor_shutdown(&ec->base);
+	weston_compositor_shutdown(compositor);
 err_base:
-	free(ec);
+	free(b);
 	return NULL;
 }
 
-WL_EXPORT struct weston_compositor *
-backend_init(struct wl_display *display, int *argc, char *argv[],
+WL_EXPORT int
+backend_init(struct weston_compositor *compositor, int *argc, char *argv[],
 	     struct weston_config *config)
 {
+	struct drm_backend *b;
 	struct drm_parameters param = { 0, };
 
 	const struct weston_option drm_options[] = {
@@ -2925,5 +2930,8 @@  backend_init(struct wl_display *display, int *argc, char *argv[],
 
 	parse_options(drm_options, ARRAY_LENGTH(drm_options), argc, argv);
 
-	return drm_compositor_create(display, &param, argc, argv, config);
+	b = drm_backend_create(compositor, &param, argc, argv, config);
+	if (b == NULL)
+		return -1;
+	return 0;
 }
diff --git a/src/compositor-fbdev.c b/src/compositor-fbdev.c
index 65bb035..fe5224d 100644
--- a/src/compositor-fbdev.c
+++ b/src/compositor-fbdev.c
@@ -45,8 +45,9 @@ 
 #include "libinput-seat.h"
 #include "gl-renderer.h"
 
-struct fbdev_compositor {
-	struct weston_compositor base;
+struct fbdev_backend {
+	struct weston_backend base;
+	struct weston_compositor *compositor;
 	uint32_t prev_state;
 
 	struct udev *udev;
@@ -71,7 +72,7 @@  struct fbdev_screeninfo {
 };
 
 struct fbdev_output {
-	struct fbdev_compositor *compositor;
+	struct fbdev_backend *backend;
 	struct weston_output base;
 
 	struct weston_mode mode;
@@ -105,10 +106,10 @@  to_fbdev_output(struct weston_output *base)
 	return container_of(base, struct fbdev_output, base);
 }
 
-static inline struct fbdev_compositor *
-to_fbdev_compositor(struct weston_compositor *base)
+static inline struct fbdev_backend *
+to_fbdev_backend(struct weston_compositor *base)
 {
-	return container_of(base, struct fbdev_compositor, base);
+	return container_of(base->backend, struct fbdev_backend, base);
 }
 
 static void
@@ -198,10 +199,10 @@  static int
 fbdev_output_repaint(struct weston_output *base, pixman_region32_t *damage)
 {
 	struct fbdev_output *output = to_fbdev_output(base);
-	struct fbdev_compositor *fbc = output->compositor;
-	struct weston_compositor *ec = & fbc->base;
+	struct fbdev_backend *fbb = output->backend;
+	struct weston_compositor *ec = fbb->compositor;
 
-	if (fbc->use_pixman) {
+	if (fbb->use_pixman) {
 		fbdev_output_repaint_pixman(base,damage);
 	} else {
 		ec->renderer->repaint_output(base, damage);
@@ -495,7 +496,7 @@  static void fbdev_output_destroy(struct weston_output *base);
 static void fbdev_output_disable(struct weston_output *base);
 
 static int
-fbdev_output_create(struct fbdev_compositor *compositor,
+fbdev_output_create(struct fbdev_backend *backend,
                     const char *device)
 {
 	struct fbdev_output *output;
@@ -512,7 +513,7 @@  fbdev_output_create(struct fbdev_compositor *compositor,
 	if (output == NULL)
 		return -1;
 
-	output->compositor = compositor;
+	output->backend = backend;
 	output->device = device;
 
 	/* Create the frame buffer. */
@@ -521,7 +522,7 @@  fbdev_output_create(struct fbdev_compositor *compositor,
 		weston_log("Creating frame buffer failed.\n");
 		goto out_free;
 	}
-	if (compositor->use_pixman) {
+	if (backend->use_pixman) {
 		if (fbdev_frame_buffer_map(output, fb_fd) < 0) {
 			weston_log("Mapping frame buffer failed.\n");
 			goto out_free;
@@ -548,7 +549,7 @@  fbdev_output_create(struct fbdev_compositor *compositor,
 	output->base.make = "unknown";
 	output->base.model = output->fb_info.id;
 
-	weston_output_init(&output->base, &compositor->base,
+	weston_output_init(&output->base, backend->compositor,
 	                   0, 0, output->fb_info.width_mm,
 	                   output->fb_info.height_mm,
 	                   WL_OUTPUT_TRANSFORM_NORMAL,
@@ -616,7 +617,7 @@  fbdev_output_create(struct fbdev_compositor *compositor,
 	if (output->base.transform != WL_OUTPUT_TRANSFORM_NORMAL)
 		pixman_image_set_transform(output->shadow_surface, &transform);
 
-	if (compositor->use_pixman) {
+	if (backend->use_pixman) {
 		if (pixman_renderer_output_create(&output->base) < 0)
 			goto out_shadow_surface;
 	} else {
@@ -631,11 +632,11 @@  fbdev_output_create(struct fbdev_compositor *compositor,
 	}
 
 
-	loop = wl_display_get_event_loop(compositor->base.wl_display);
+	loop = wl_display_get_event_loop(backend->compositor->wl_display);
 	output->finish_frame_timer =
 		wl_event_loop_add_timer(loop, finish_frame_handler, output);
 
-	wl_list_insert(compositor->base.output_list.prev, &output->base.link);
+	wl_list_insert(backend->compositor->output_list.prev, &output->base.link);
 
 	weston_log("fbdev output %d×%d px\n",
 	           output->mode.width, output->mode.height);
@@ -663,14 +664,14 @@  static void
 fbdev_output_destroy(struct weston_output *base)
 {
 	struct fbdev_output *output = to_fbdev_output(base);
-	struct fbdev_compositor *compositor = output->compositor;
+	struct fbdev_backend *backend = output->backend;
 
 	weston_log("Destroying fbdev output.\n");
 
 	/* Close the frame buffer. */
 	fbdev_output_disable(base);
 
-	if (compositor->use_pixman) {
+	if (backend->use_pixman) {
 		if (base->renderer_state != NULL)
 			pixman_renderer_output_destroy(base);
 
@@ -711,7 +712,7 @@  compare_screen_info (const struct fbdev_screeninfo *a,
 }
 
 static int
-fbdev_output_reenable(struct fbdev_compositor *compositor,
+fbdev_output_reenable(struct fbdev_backend *backend,
                       struct weston_output *base)
 {
 	struct fbdev_output *output = to_fbdev_output(base);
@@ -746,13 +747,13 @@  fbdev_output_reenable(struct fbdev_compositor *compositor,
 		 * are re-initialised. */
 		device = output->device;
 		fbdev_output_destroy(base);
-		fbdev_output_create(compositor, device);
+		fbdev_output_create(backend, device);
 
 		return 0;
 	}
 
 	/* Map the device if it has the same details as before. */
-	if (compositor->use_pixman) {
+	if (backend->use_pixman) {
 		if (fbdev_frame_buffer_map(output, fb_fd) < 0) {
 			weston_log("Mapping frame buffer failed.\n");
 			goto err;
@@ -772,11 +773,11 @@  static void
 fbdev_output_disable(struct weston_output *base)
 {
 	struct fbdev_output *output = to_fbdev_output(base);
-	struct fbdev_compositor *compositor = output->compositor;
+	struct fbdev_backend *backend = output->backend;
 
 	weston_log("Disabling fbdev output.\n");
 
-	if ( ! compositor->use_pixman) return;
+	if ( ! backend->use_pixman) return;
 
 	if (output->hw_surface != NULL) {
 		pixman_image_unref(output->hw_surface);
@@ -787,48 +788,49 @@  fbdev_output_disable(struct weston_output *base)
 }
 
 static void
-fbdev_compositor_destroy(struct weston_compositor *base)
+fbdev_backend_destroy(struct weston_compositor *base)
 {
-	struct fbdev_compositor *compositor = to_fbdev_compositor(base);
+	struct fbdev_backend *backend = to_fbdev_backend(base);
 
-	udev_input_destroy(&compositor->input);
+	udev_input_destroy(&backend->input);
 
 	/* Destroy the output. */
-	weston_compositor_shutdown(&compositor->base);
+	weston_compositor_shutdown(base);
 
 	/* Chain up. */
-	weston_launcher_destroy(compositor->base.launcher);
+	weston_launcher_destroy(base->launcher);
 
-	free(compositor);
+	free(backend);
 }
 
 static void
 session_notify(struct wl_listener *listener, void *data)
 {
-	struct fbdev_compositor *compositor = data;
+	struct fbdev_backend *backend = data;
+	struct weston_compositor *compositor = backend->compositor;
 	struct weston_output *output;
 
-	if (compositor->base.session_active) {
+	if (compositor->session_active) {
 		weston_log("entering VT\n");
-		compositor->base.state = compositor->prev_state;
+		compositor->state = backend->prev_state;
 
-		wl_list_for_each(output, &compositor->base.output_list, link) {
-			fbdev_output_reenable(compositor, output);
+		wl_list_for_each(output, &compositor->output_list, link) {
+			fbdev_output_reenable(backend, output);
 		}
 
-		weston_compositor_damage_all(&compositor->base);
+		weston_compositor_damage_all(compositor);
 
-		udev_input_enable(&compositor->input);
+		udev_input_enable(&backend->input);
 	} else {
 		weston_log("leaving VT\n");
-		udev_input_disable(&compositor->input);
+		udev_input_disable(&backend->input);
 
-		wl_list_for_each(output, &compositor->base.output_list, link) {
+		wl_list_for_each(output, &compositor->output_list, link) {
 			fbdev_output_disable(output);
 		}
 
-		compositor->prev_state = compositor->base.state;
-		weston_compositor_offscreen(&compositor->base);
+		backend->prev_state = compositor->state;
+		weston_compositor_offscreen(compositor);
 
 		/* If we have a repaint scheduled (from the idle handler), make
 		 * sure we cancel that so we don't try to pageflip when we're
@@ -838,7 +840,7 @@  session_notify(struct wl_listener *listener, void *data)
 		 * pending frame callbacks. */
 
 		wl_list_for_each(output,
-				 &compositor->base.output_list, link) {
+				 &compositor->output_list, link) {
 			output->repaint_needed = 0;
 		}
 	}
@@ -858,60 +860,61 @@  switch_vt_binding(struct weston_seat *seat, uint32_t time, uint32_t key, void *d
 	weston_launcher_activate_vt(compositor->launcher, key - KEY_F1 + 1);
 }
 
-static struct weston_compositor *
-fbdev_compositor_create(struct wl_display *display, int *argc, char *argv[],
-                        struct weston_config *config,
-			struct fbdev_parameters *param)
+static struct fbdev_backend *
+fbdev_backend_create(struct weston_compositor *compositor, int *argc, char *argv[],
+                     struct weston_config *config,
+                     struct fbdev_parameters *param)
 {
-	struct fbdev_compositor *compositor;
+	struct fbdev_backend *backend;
 	const char *seat_id = default_seat;
 	uint32_t key;
 
 	weston_log("initializing fbdev backend\n");
 
-	compositor = zalloc(sizeof *compositor);
-	if (compositor == NULL)
+	backend = zalloc(sizeof *backend);
+	if (backend == NULL)
 		return NULL;
 
-	if (weston_compositor_init(&compositor->base, display, argc, argv,
+	backend->compositor = compositor;
+	if (weston_compositor_init(compositor, argc, argv,
 	                           config) < 0)
 		goto out_free;
 
 	if (weston_compositor_set_presentation_clock_software(
-							&compositor->base) < 0)
+							compositor) < 0)
 		goto out_compositor;
 
-	compositor->udev = udev_new();
-	if (compositor->udev == NULL) {
+	backend->udev = udev_new();
+	if (backend->udev == NULL) {
 		weston_log("Failed to initialize udev context.\n");
 		goto out_compositor;
 	}
 
 	/* Set up the TTY. */
-	compositor->session_listener.notify = session_notify;
-	wl_signal_add(&compositor->base.session_signal,
-		      &compositor->session_listener);
-	compositor->base.launcher =
-		weston_launcher_connect(&compositor->base, param->tty, "seat0");
-	if (!compositor->base.launcher) {
+	backend->session_listener.notify = session_notify;
+	wl_signal_add(&compositor->session_signal,
+		      &backend->session_listener);
+	compositor->launcher =
+		weston_launcher_connect(compositor, param->tty, "seat0");
+	if (!compositor->launcher) {
 		weston_log("fatal: fbdev backend should be run "
 			   "using weston-launch binary or as root\n");
 		goto out_udev;
 	}
 
-	compositor->base.destroy = fbdev_compositor_destroy;
-	compositor->base.restore = fbdev_restore;
+	backend->base.destroy = fbdev_backend_destroy;
+	backend->base.restore = fbdev_restore;
 
-	compositor->prev_state = WESTON_COMPOSITOR_ACTIVE;
-	compositor->use_pixman = !param->use_gl;
+	backend->prev_state = WESTON_COMPOSITOR_ACTIVE;
+	backend->use_pixman = !param->use_gl;
 
 	for (key = KEY_F1; key < KEY_F9; key++)
-		weston_compositor_add_key_binding(&compositor->base, key,
+		weston_compositor_add_key_binding(compositor, key,
 		                                  MODIFIER_CTRL | MODIFIER_ALT,
 		                                  switch_vt_binding,
-		                                  compositor);
-	if (compositor->use_pixman) {
-		if (pixman_renderer_init(&compositor->base) < 0)
+		                                  backend);
+	if (backend->use_pixman) {
+		if (pixman_renderer_init(compositor) < 0)
 			goto out_launcher;
 	} else {
 		gl_renderer = weston_load_module("gl-renderer.so",
@@ -921,7 +924,7 @@  fbdev_compositor_create(struct wl_display *display, int *argc, char *argv[],
 			goto out_launcher;
 		}
 
-		if (gl_renderer->create(&compositor->base, EGL_DEFAULT_DISPLAY,
+		if (gl_renderer->create(compositor, EGL_DEFAULT_DISPLAY,
 					gl_renderer->opaque_attribs,
 					NULL) < 0) {
 			weston_log("gl_renderer_create failed.\n");
@@ -929,35 +932,37 @@  fbdev_compositor_create(struct wl_display *display, int *argc, char *argv[],
 		}
 	}
 
-	if (fbdev_output_create(compositor, param->device) < 0)
+	if (fbdev_output_create(backend, param->device) < 0)
 		goto out_pixman;
 
-	udev_input_init(&compositor->input, &compositor->base, compositor->udev, seat_id);
+	udev_input_init(&backend->input, compositor, backend->udev, seat_id);
 
-	return &compositor->base;
+	compositor->backend = &backend->base;
+	return backend;
 
 out_pixman:
-	compositor->base.renderer->destroy(&compositor->base);
+	compositor->renderer->destroy(compositor);
 
 out_launcher:
-	weston_launcher_destroy(compositor->base.launcher);
+	weston_launcher_destroy(compositor->launcher);
 
 out_udev:
-	udev_unref(compositor->udev);
+	udev_unref(backend->udev);
 
 out_compositor:
-	weston_compositor_shutdown(&compositor->base);
+	weston_compositor_shutdown(compositor);
 
 out_free:
-	free(compositor);
+	free(backend);
 
 	return NULL;
 }
 
-WL_EXPORT struct weston_compositor *
-backend_init(struct wl_display *display, int *argc, char *argv[],
+WL_EXPORT int
+backend_init(struct weston_compositor *compositor, int *argc, char *argv[],
 	     struct weston_config *config)
 {
+	struct fbdev_backend *b;
 	/* TODO: Ideally, available frame buffers should be enumerated using
 	 * udev, rather than passing a device node in as a parameter. */
 	struct fbdev_parameters param = {
@@ -974,5 +979,8 @@  backend_init(struct wl_display *display, int *argc, char *argv[],
 
 	parse_options(fbdev_options, ARRAY_LENGTH(fbdev_options), argc, argv);
 
-	return fbdev_compositor_create(display, argc, argv, config, &param);
+	b = fbdev_backend_create(compositor, argc, argv, config, &param);
+	if (b == NULL)
+		return -1;
+	return 0;
 }
diff --git a/src/compositor-headless.c b/src/compositor-headless.c
index 945c84b..e57144b 100644
--- a/src/compositor-headless.c
+++ b/src/compositor-headless.c
@@ -31,8 +31,9 @@ 
 #include "compositor.h"
 #include "pixman-renderer.h"
 
-struct headless_compositor {
-	struct weston_compositor base;
+struct headless_backend {
+	struct weston_backend base;
+	struct weston_compositor *compositor;
 	struct weston_seat fake_seat;
 	bool use_pixman;
 };
@@ -90,12 +91,12 @@  static void
 headless_output_destroy(struct weston_output *output_base)
 {
 	struct headless_output *output = (struct headless_output *) output_base;
-	struct headless_compositor *c =
-			(struct headless_compositor *) output->base.compositor;
+	struct headless_backend *b =
+			(struct headless_backend *) output->base.compositor->backend;
 
 	wl_event_source_remove(output->finish_frame_timer);
 
-	if (c->use_pixman) {
+	if (b->use_pixman) {
 		pixman_renderer_output_destroy(&output->base);
 		pixman_image_unref(output->image);
 		free(output->image_buf);
@@ -109,9 +110,10 @@  headless_output_destroy(struct weston_output *output_base)
 }
 
 static int
-headless_compositor_create_output(struct headless_compositor *c,
-				  struct headless_parameters *param)
+headless_backend_create_output(struct headless_backend *b,
+			       struct headless_parameters *param)
 {
+	struct weston_compositor *c = b->compositor;
 	struct headless_output *output;
 	struct wl_event_loop *loop;
 
@@ -128,13 +130,13 @@  headless_compositor_create_output(struct headless_compositor *c,
 	wl_list_insert(&output->base.mode_list, &output->mode.link);
 
 	output->base.current_mode = &output->mode;
-	weston_output_init(&output->base, &c->base, 0, 0, param->width,
+	weston_output_init(&output->base, c, 0, 0, param->width,
 			   param->height, param->transform, 1);
 
 	output->base.make = "weston";
 	output->base.model = "headless";
 
-	loop = wl_display_get_event_loop(c->base.wl_display);
+	loop = wl_display_get_event_loop(c->wl_display);
 	output->finish_frame_timer =
 		wl_event_loop_add_timer(loop, finish_frame_handler, output);
 
@@ -146,7 +148,7 @@  headless_compositor_create_output(struct headless_compositor *c,
 	output->base.set_dpms = NULL;
 	output->base.switch_mode = NULL;
 
-	if (c->use_pixman) {
+	if (b->use_pixman) {
 		output->image_buf = malloc(param->width * param->height * 4);
 		if (!output->image_buf)
 			return -1;
@@ -164,28 +166,28 @@  headless_compositor_create_output(struct headless_compositor *c,
 						  output->image);
 	}
 
-	wl_list_insert(c->base.output_list.prev, &output->base.link);
+	wl_list_insert(c->output_list.prev, &output->base.link);
 
 	return 0;
 }
 
 static int
-headless_input_create(struct headless_compositor *c)
+headless_input_create(struct headless_backend *b)
 {
-	weston_seat_init(&c->fake_seat, &c->base, "default");
+	weston_seat_init(&b->fake_seat, b->compositor, "default");
 
-	weston_seat_init_pointer(&c->fake_seat);
+	weston_seat_init_pointer(&b->fake_seat);
 
-	if (weston_seat_init_keyboard(&c->fake_seat, NULL) < 0)
+	if (weston_seat_init_keyboard(&b->fake_seat, NULL) < 0)
 		return -1;
 
 	return 0;
 }
 
 static void
-headless_input_destroy(struct headless_compositor *c)
+headless_input_destroy(struct headless_backend *b)
 {
-	weston_seat_release(&c->fake_seat);
+	weston_seat_release(&b->fake_seat);
 }
 
 static void
@@ -196,68 +198,66 @@  headless_restore(struct weston_compositor *ec)
 static void
 headless_destroy(struct weston_compositor *ec)
 {
-	struct headless_compositor *c = (struct headless_compositor *) ec;
+	struct headless_backend *b = (struct headless_backend *) ec->backend;
 
-	headless_input_destroy(c);
+	headless_input_destroy(b);
 	weston_compositor_shutdown(ec);
 
-	free(ec);
+	free(b);
 }
 
-static struct weston_compositor *
-headless_compositor_create(struct wl_display *display,
-			   struct headless_parameters *param,
-			   const char *display_name,
-			   int *argc, char *argv[],
-			   struct weston_config *config)
+static struct headless_backend *
+headless_backend_create(struct weston_compositor *compositor,
+			struct headless_parameters *param,
+			const char *display_name)
 {
-	struct headless_compositor *c;
+	struct headless_backend *b;
 
-	c = zalloc(sizeof *c);
-	if (c == NULL)
+	b = zalloc(sizeof *b);
+	if (b == NULL)
 		return NULL;
 
-	if (weston_compositor_init(&c->base, display, argc, argv, config) < 0)
-		goto err_free;
+	b->compositor = compositor;
 
-	if (weston_compositor_set_presentation_clock_software(&c->base) < 0)
-		goto err_compositor;
+	if (weston_compositor_set_presentation_clock_software(compositor) < 0)
+		goto err_free;
 
-	if (headless_input_create(c) < 0)
-		goto err_compositor;
+	if (headless_input_create(b) < 0)
+		goto err_free;
 
-	c->base.destroy = headless_destroy;
-	c->base.restore = headless_restore;
+	b->base.destroy = headless_destroy;
+	b->base.restore = headless_restore;
 
-	c->use_pixman = param->use_pixman;
-	if (c->use_pixman) {
-		pixman_renderer_init(&c->base);
+	b->use_pixman = param->use_pixman;
+	if (b->use_pixman) {
+		pixman_renderer_init(compositor);
 	}
-	if (headless_compositor_create_output(c, param) < 0)
+	if (headless_backend_create_output(b, param) < 0)
 		goto err_input;
 
-	if (!c->use_pixman && noop_renderer_init(&c->base) < 0)
+	if (!b->use_pixman && noop_renderer_init(compositor) < 0)
 		goto err_input;
 
-	return &c->base;
+	compositor->backend = &b->base;
+	return b;
 
 err_input:
-	headless_input_destroy(c);
-err_compositor:
-	weston_compositor_shutdown(&c->base);
+	headless_input_destroy(b);
 err_free:
-	free(c);
+	free(b);
 	return NULL;
 }
 
-WL_EXPORT struct weston_compositor *
-backend_init(struct wl_display *display, int *argc, char *argv[],
+WL_EXPORT int
+backend_init(struct weston_compositor *compositor,
+	     int *argc, char *argv[],
 	     struct weston_config *config)
 {
 	int width = 1024, height = 640;
 	char *display_name = NULL;
 	struct headless_parameters param = { 0, };
 	const char *transform = "normal";
+	struct headless_backend *b;
 
 	const struct weston_option headless_options[] = {
 		{ WESTON_OPTION_INTEGER, "width", 0, &width },
@@ -275,6 +275,8 @@  backend_init(struct wl_display *display, int *argc, char *argv[],
 	if (weston_parse_transform(transform, &param.transform) < 0)
 		weston_log("Invalid transform \"%s\"\n", transform);
 
-	return headless_compositor_create(display, &param, display_name,
-					  argc, argv, config);
+	b = headless_backend_create(compositor, &param, display_name);
+	if (b == NULL)
+		return -1;
+	return 0;
 }
diff --git a/src/compositor-rdp.c b/src/compositor-rdp.c
index 2048f8f..678c35e 100644
--- a/src/compositor-rdp.c
+++ b/src/compositor-rdp.c
@@ -52,7 +52,7 @@ 
 #define DEFAULT_AXIS_STEP_DISTANCE wl_fixed_from_int(10)
 #define RDP_MODE_FREQ 60 * 1000
 
-struct rdp_compositor_config {
+struct rdp_backend_config {
 	int width;
 	int height;
 	char *bind_address;
@@ -66,8 +66,9 @@  struct rdp_compositor_config {
 
 struct rdp_output;
 
-struct rdp_compositor {
-	struct weston_compositor base;
+struct rdp_backend {
+	struct weston_backend base;
+	struct weston_compositor *compositor;
 
 	freerdp_listener *listener;
 	struct wl_event_source *listener_events[MAX_FREERDP_FDS];
@@ -104,7 +105,7 @@  struct rdp_output {
 struct rdp_peer_context {
 	rdpContext _p;
 
-	struct rdp_compositor *rdpCompositor;
+	struct rdp_backend *rdpBackend;
 	struct wl_event_source *events[MAX_FREERDP_FDS];
 	RFX_CONTEXT *rfx_context;
 	wStream *encode_stream;
@@ -116,7 +117,7 @@  struct rdp_peer_context {
 typedef struct rdp_peer_context RdpPeerContext;
 
 static void
-rdp_compositor_config_init(struct rdp_compositor_config *config) {
+rdp_backend_config_init(struct rdp_backend_config *config) {
 	config->width = 640;
 	config->height = 480;
 	config->bind_address = NULL;
@@ -291,7 +292,7 @@  static void
 rdp_peer_refresh_region(pixman_region32_t *region, freerdp_peer *peer)
 {
 	RdpPeerContext *context = (RdpPeerContext *)peer->context;
-	struct rdp_output *output = context->rdpCompositor->output;
+	struct rdp_output *output = context->rdpBackend->output;
 	rdpSettings *settings = peer->settings;
 
 	if (settings->RemoteFxCodec)
@@ -431,7 +432,7 @@  rdp_switch_mode(struct weston_output *output, struct weston_mode *target_mode) {
 }
 
 static int
-rdp_compositor_create_output(struct rdp_compositor *c, int width, int height)
+rdp_backend_create_output(struct rdp_backend *b, int width, int height)
 {
 	struct rdp_output *output;
 	struct wl_event_loop *loop;
@@ -455,7 +456,7 @@  rdp_compositor_create_output(struct rdp_compositor *c, int width, int height)
 		goto out_free_output;
 
 	output->base.current_mode = output->base.native_mode = currentMode;
-	weston_output_init(&output->base, &c->base, 0, 0, width, height,
+	weston_output_init(&output->base, b->compositor, 0, 0, width, height,
 			   WL_OUTPUT_TRANSFORM_NORMAL, 1);
 
 	output->base.make = "weston";
@@ -472,7 +473,7 @@  rdp_compositor_create_output(struct rdp_compositor *c, int width, int height)
 	if (pixman_renderer_output_create(&output->base) < 0)
 		goto out_shadow_surface;
 
-	loop = wl_display_get_event_loop(c->base.wl_display);
+	loop = wl_display_get_event_loop(b->compositor->wl_display);
 	output->finish_frame_timer = wl_event_loop_add_timer(loop, finish_frame_handler, output);
 
 	output->base.start_repaint_loop = rdp_output_start_repaint_loop;
@@ -482,9 +483,9 @@  rdp_compositor_create_output(struct rdp_compositor *c, int width, int height)
 	output->base.set_backlight = NULL;
 	output->base.set_dpms = NULL;
 	output->base.switch_mode = rdp_switch_mode;
-	c->output = output;
+	b->output = output;
 
-	wl_list_insert(c->base.output_list.prev, &output->base.link);
+	wl_list_insert(b->compositor->output_list.prev, &output->base.link);
 	return 0;
 
 out_shadow_surface:
@@ -524,7 +525,7 @@  int rdp_listener_activity(int fd, uint32_t mask, void *data) {
 }
 
 static
-int rdp_implant_listener(struct rdp_compositor *c, freerdp_listener* instance) {
+int rdp_implant_listener(struct rdp_backend *b, freerdp_listener* instance) {
 	int i, fd;
 	int rcount = 0;
 	void* rfds[MAX_FREERDP_FDS];
@@ -535,15 +536,15 @@  int rdp_implant_listener(struct rdp_compositor *c, freerdp_listener* instance) {
 		return -1;
 	}
 
-	loop = wl_display_get_event_loop(c->base.wl_display);
+	loop = wl_display_get_event_loop(b->compositor->wl_display);
 	for (i = 0; i < rcount; i++) {
 		fd = (int)(long)(rfds[i]);
-		c->listener_events[i] = wl_event_loop_add_fd(loop, fd, WL_EVENT_READABLE,
+		b->listener_events[i] = wl_event_loop_add_fd(loop, fd, WL_EVENT_READABLE,
 				rdp_listener_activity, instance);
 	}
 
 	for( ; i < MAX_FREERDP_FDS; i++)
-		c->listener_events[i] = 0;
+		b->listener_events[i] = 0;
 	return 0;
 }
 
@@ -756,7 +757,7 @@  static BOOL
 xf_peer_post_connect(freerdp_peer* client)
 {
 	RdpPeerContext *peerCtx;
-	struct rdp_compositor *c;
+	struct rdp_backend *b;
 	struct rdp_output *output;
 	rdpSettings *settings;
 	rdpPointerUpdate *pointer;
@@ -769,8 +770,8 @@  xf_peer_post_connect(freerdp_peer* client)
 
 
 	peerCtx = (RdpPeerContext *)client->context;
-	c = peerCtx->rdpCompositor;
-	output = c->output;
+	b = peerCtx->rdpBackend;
+	output = b->output;
 	settings = client->settings;
 
 	if (!settings->SurfaceCommandsEnabled) {
@@ -781,7 +782,7 @@  xf_peer_post_connect(freerdp_peer* client)
 	if (output->base.width != (int)settings->DesktopWidth ||
 			output->base.height != (int)settings->DesktopHeight)
 	{
-		if (c->no_clients_resize) {
+		if (b->no_clients_resize) {
 			/* RDP peers don't dictate their resolution to weston */
 			if (!settings->DesktopResize) {
 				/* peer does not support desktop resize */
@@ -876,7 +877,7 @@  xf_mouseEvent(rdpInput *input, UINT16 flags, UINT16 x, UINT16 y) {
 	uint32_t button = 0;
 
 	if (flags & PTR_FLAGS_MOVE) {
-		output = peerContext->rdpCompositor->output;
+		output = peerContext->rdpBackend->output;
 		if (x < output->base.width && y < output->base.height) {
 			wl_x = wl_fixed_from_int((int)x);
 			wl_y = wl_fixed_from_int((int)y);
@@ -921,7 +922,7 @@  xf_extendedMouseEvent(rdpInput *input, UINT16 flags, UINT16 x, UINT16 y) {
 	RdpPeerContext *peerContext = (RdpPeerContext *)input->context;
 	struct rdp_output *output;
 
-	output = peerContext->rdpCompositor->output;
+	output = peerContext->rdpBackend->output;
 	if (x < output->base.width && y < output->base.height) {
 		wl_x = wl_fixed_from_int((int)x);
 		wl_y = wl_fixed_from_int((int)y);
@@ -936,7 +937,7 @@  xf_input_synchronize_event(rdpInput *input, UINT32 flags)
 {
 	freerdp_peer *client = input->context->peer;
 	RdpPeerContext *peerCtx = (RdpPeerContext *)input->context;
-	struct rdp_output *output = peerCtx->rdpCompositor->output;
+	struct rdp_output *output = peerCtx->rdpBackend->output;
 	pixman_box32_t box;
 	pixman_region32_t damage;
 
@@ -1004,7 +1005,7 @@  xf_suppress_output(rdpContext *context, BYTE allow, RECTANGLE_16 *area) {
 }
 
 static int
-rdp_peer_init(freerdp_peer *client, struct rdp_compositor *c)
+rdp_peer_init(freerdp_peer *client, struct rdp_backend *b)
 {
 	int rcount = 0;
 	void *rfds[MAX_FREERDP_FDS];
@@ -1021,13 +1022,13 @@  rdp_peer_init(freerdp_peer *client, struct rdp_compositor *c)
 	freerdp_peer_context_new(client);
 
 	peerCtx = (RdpPeerContext *) client->context;
-	peerCtx->rdpCompositor = c;
+	peerCtx->rdpBackend = b;
 
 	settings = client->settings;
-	settings->RdpKeyFile = c->rdp_key;
-	if (c->tls_enabled) {
-		settings->CertificateFile = c->server_cert;
-		settings->PrivateKeyFile = c->server_key;
+	settings->RdpKeyFile = b->rdp_key;
+	if (b->tls_enabled) {
+		settings->CertificateFile = b->server_cert;
+		settings->PrivateKeyFile = b->server_key;
 	} else {
 		settings->TlsSecurity = FALSE;
 	}
@@ -1050,7 +1051,7 @@  rdp_peer_init(freerdp_peer *client, struct rdp_compositor *c)
 	if (snprintf(seat_name, 32, "rdp:%d:%s", client->sockfd, client->hostname) >= 32)
 		seat_name[31] = '\0';
 
-	weston_seat_init(&peerCtx->item.seat, &c->base, seat_name);
+	weston_seat_init(&peerCtx->item.seat, b->compositor, seat_name);
 
 	client->Initialize(client);
 
@@ -1059,7 +1060,7 @@  rdp_peer_init(freerdp_peer *client, struct rdp_compositor *c)
 		return -1;
 	}
 
-	loop = wl_display_get_event_loop(c->base.wl_display);
+	loop = wl_display_get_event_loop(b->compositor->wl_display);
 	for(i = 0; i < rcount; i++) {
 		fd = (int)(long)(rfds[i]);
 
@@ -1069,7 +1070,7 @@  rdp_peer_init(freerdp_peer *client, struct rdp_compositor *c)
 	for ( ; i < MAX_FREERDP_FDS; i++)
 		peerCtx->events[i] = 0;
 
-	wl_list_insert(&c->output->peers, &peerCtx->item.link);
+	wl_list_insert(&b->output->peers, &peerCtx->item.link);
 	return 0;
 }
 
@@ -1077,63 +1078,64 @@  rdp_peer_init(freerdp_peer *client, struct rdp_compositor *c)
 static void
 rdp_incoming_peer(freerdp_listener *instance, freerdp_peer *client)
 {
-	struct rdp_compositor *c = (struct rdp_compositor *)instance->param4;
-	if (rdp_peer_init(client, c) < 0)
+	struct rdp_backend *b = (struct rdp_backend *)instance->param4;
+	if (rdp_peer_init(client, b) < 0)
 		return;
 }
 
-static struct weston_compositor *
-rdp_compositor_create(struct wl_display *display,
-		struct rdp_compositor_config *config,
-		int *argc, char *argv[], struct weston_config *wconfig)
+static struct rdp_backend *
+rdp_backend_create(struct weston_compositor *compositor,
+		   struct rdp_backend_config *config,
+		   int *argc, char *argv[], struct weston_config *wconfig)
 {
-	struct rdp_compositor *c;
+	struct rdp_backend *b;
 	char *fd_str;
 	int fd;
 
-	c = zalloc(sizeof *c);
-	if (c == NULL)
+	b = zalloc(sizeof *b);
+	if (b == NULL)
 		return NULL;
 
-	if (weston_compositor_init(&c->base, display, argc, argv, wconfig) < 0)
+	b->compositor = compositor;
+	if (weston_compositor_init(compositor, argc, argv, wconfig) < 0)
 		goto err_free;
 
-	c->base.destroy = rdp_destroy;
-	c->base.restore = rdp_restore;
-	c->rdp_key = config->rdp_key ? strdup(config->rdp_key) : NULL;
-	c->no_clients_resize = config->no_clients_resize;
+	b->base.destroy = rdp_destroy;
+	b->base.restore = rdp_restore;
+	b->rdp_key = config->rdp_key ? strdup(config->rdp_key) : NULL;
+	b->no_clients_resize = config->no_clients_resize;
 
 	/* activate TLS only if certificate/key are available */
 	if (config->server_cert && config->server_key) {
 		weston_log("TLS support activated\n");
-		c->server_cert = strdup(config->server_cert);
-		c->server_key = strdup(config->server_key);
-		if (!c->server_cert || !c->server_key)
+		b->server_cert = strdup(config->server_cert);
+		b->server_key = strdup(config->server_key);
+		if (!b->server_cert || !b->server_key)
 			goto err_free_strings;
-		c->tls_enabled = 1;
+		b->tls_enabled = 1;
 	}
 
-	if (weston_compositor_set_presentation_clock_software(&c->base) < 0)
+	if (weston_compositor_set_presentation_clock_software(compositor) < 0)
 		goto err_compositor;
 
-	if (pixman_renderer_init(&c->base) < 0)
+	if (pixman_renderer_init(compositor) < 0)
 		goto err_compositor;
 
-	if (rdp_compositor_create_output(c, config->width, config->height) < 0)
+	if (rdp_backend_create_output(b, config->width, config->height) < 0)
 		goto err_compositor;
 
-	c->base.capabilities |= WESTON_CAP_ARBITRARY_MODES;
+	compositor->capabilities |= WESTON_CAP_ARBITRARY_MODES;
 
 	if(!config->env_socket) {
-		c->listener = freerdp_listener_new();
-		c->listener->PeerAccepted = rdp_incoming_peer;
-		c->listener->param4 = c;
-		if (!c->listener->Open(c->listener, config->bind_address, config->port)) {
+		b->listener = freerdp_listener_new();
+		b->listener->PeerAccepted = rdp_incoming_peer;
+		b->listener->param4 = b;
+		if (!b->listener->Open(b->listener, config->bind_address, config->port)) {
 			weston_log("unable to bind rdp socket\n");
 			goto err_listener;
 		}
 
-		if (rdp_implant_listener(c, c->listener) < 0)
+		if (rdp_implant_listener(b, b->listener) < 0)
 			goto err_compositor;
 	} else {
 		/* get the socket from RDP_FD var */
@@ -1144,36 +1146,38 @@  rdp_compositor_create(struct wl_display *display,
 		}
 
 		fd = strtoul(fd_str, NULL, 10);
-		if (rdp_peer_init(freerdp_peer_new(fd), c))
+		if (rdp_peer_init(freerdp_peer_new(fd), b))
 			goto err_output;
 	}
 
-	return &c->base;
+	compositor->backend = &b->base;
+	return b;
 
 err_listener:
-	freerdp_listener_free(c->listener);
+	freerdp_listener_free(b->listener);
 err_output:
-	weston_output_destroy(&c->output->base);
+	weston_output_destroy(&b->output->base);
 err_compositor:
-	weston_compositor_shutdown(&c->base);
+	weston_compositor_shutdown(compositor);
 err_free_strings:
-	if (c->rdp_key)
-		free(c->rdp_key);
-	if (c->server_cert)
-		free(c->server_cert);
-	if (c->server_key)
-		free(c->server_key);
+	if (b->rdp_key)
+		free(b->rdp_key);
+	if (b->server_cert)
+		free(b->server_cert);
+	if (b->server_key)
+		free(b->server_key);
 err_free:
-	free(c);
+	free(b);
 	return NULL;
 }
 
-WL_EXPORT struct weston_compositor *
-backend_init(struct wl_display *display, int *argc, char *argv[],
+WL_EXPORT int
+backend_init(struct weston_compositor *compositor, int *argc, char *argv[],
 	     struct weston_config *wconfig)
 {
-	struct rdp_compositor_config config;
-	rdp_compositor_config_init(&config);
+	struct rdp_backend *b;
+	struct rdp_backend_config config;
+	rdp_backend_config_init(&config);
 	int major, minor, revision;
 
 	freerdp_get_version(&major, &minor, &revision);
@@ -1192,5 +1196,8 @@  backend_init(struct wl_display *display, int *argc, char *argv[],
 	};
 
 	parse_options(rdp_options, ARRAY_LENGTH(rdp_options), argc, argv);
-	return rdp_compositor_create(display, &config, argc, argv, wconfig);
+	b = rdp_backend_create(compositor, &config, argc, argv, wconfig);
+	if (b == NULL)
+		return -1;
+	return 0;
 }
diff --git a/src/compositor-rpi.c b/src/compositor-rpi.c
index 150e9e1..2c2db10 100644
--- a/src/compositor-rpi.c
+++ b/src/compositor-rpi.c
@@ -55,7 +55,7 @@ 
 #define DBG(...) do {} while (0)
 #endif
 
-struct rpi_compositor;
+struct rpi_backend;
 struct rpi_output;
 
 struct rpi_flippipe {
@@ -66,7 +66,7 @@  struct rpi_flippipe {
 };
 
 struct rpi_output {
-	struct rpi_compositor *compositor;
+	struct rpi_backend *backend;
 	struct weston_output base;
 	int single_buffer;
 
@@ -85,8 +85,9 @@  struct rpi_seat {
 	char *seat_id;
 };
 
-struct rpi_compositor {
-	struct weston_compositor base;
+struct rpi_backend {
+	struct weston_backend base;
+	struct weston_compositor *compositor;
 	uint32_t prev_state;
 
 	struct udev *udev;
@@ -108,10 +109,10 @@  to_rpi_seat(struct weston_seat *base)
 	return container_of(base, struct rpi_seat, base);
 }
 
-static inline struct rpi_compositor *
-to_rpi_compositor(struct weston_compositor *base)
+static inline struct rpi_backend *
+to_rpi_backend(struct weston_compositor *c)
 {
-	return container_of(base, struct rpi_compositor, base);
+	return container_of(c->backend, struct rpi_backend, base);
 }
 
 static void
@@ -186,9 +187,9 @@  rpi_flippipe_init(struct rpi_flippipe *flippipe, struct rpi_output *output)
 
 	flippipe->readfd = fd[0];
 	flippipe->writefd = fd[1];
-	flippipe->clk_id = output->compositor->base.presentation_clock;
+	flippipe->clk_id = output->base.compositor->presentation_clock;
 
-	loop = wl_display_get_event_loop(output->compositor->base.wl_display);
+	loop = wl_display_get_event_loop(output->base.compositor->wl_display);
 	flippipe->source = wl_event_loop_add_fd(loop, flippipe->readfd,
 						WL_EVENT_READABLE,
 						rpi_flippipe_handler, output);
@@ -223,8 +224,8 @@  static int
 rpi_output_repaint(struct weston_output *base, pixman_region32_t *damage)
 {
 	struct rpi_output *output = to_rpi_output(base);
-	struct rpi_compositor *compositor = output->compositor;
-	struct weston_plane *primary_plane = &compositor->base.primary_plane;
+	struct weston_compositor *compositor = output->backend->compositor;
+	struct weston_plane *primary_plane = &compositor->primary_plane;
 	DISPMANX_UPDATE_HANDLE_T update;
 
 	DBG("frame update start\n");
@@ -235,7 +236,7 @@  rpi_output_repaint(struct weston_output *base, pixman_region32_t *damage)
 	update = vc_dispmanx_update_start(1);
 
 	rpi_renderer_set_update_handle(&output->base, update);
-	compositor->base.renderer->repaint_output(&output->base, damage);
+	compositor->renderer->repaint_output(&output->base, damage);
 
 	pixman_region32_subtract(&primary_plane->damage,
 				 &primary_plane->damage, damage);
@@ -282,7 +283,7 @@  rpi_output_destroy(struct weston_output *base)
 }
 
 static int
-rpi_output_create(struct rpi_compositor *compositor, uint32_t transform)
+rpi_output_create(struct rpi_backend *backend, uint32_t transform)
 {
 	struct rpi_output *output;
 	DISPMANX_MODEINFO_T modeinfo;
@@ -293,8 +294,8 @@  rpi_output_create(struct rpi_compositor *compositor, uint32_t transform)
 	if (output == NULL)
 		return -1;
 
-	output->compositor = compositor;
-	output->single_buffer = compositor->single_buffer;
+	output->backend = backend;
+	output->single_buffer = backend->single_buffer;
 
 	if (rpi_flippipe_init(&output->flippipe, output) < 0) {
 		weston_log("Creating message pipe failed.\n");
@@ -344,14 +345,14 @@  rpi_output_create(struct rpi_compositor *compositor, uint32_t transform)
 	mm_width  = modeinfo.width * (25.4f / 96.0f);
 	mm_height = modeinfo.height * (25.4f / 96.0f);
 
-	weston_output_init(&output->base, &compositor->base,
+	weston_output_init(&output->base, backend->compositor,
 			   0, 0, round(mm_width), round(mm_height),
 			   transform, 1);
 
 	if (rpi_renderer_output_create(&output->base, output->display) < 0)
 		goto out_output;
 
-	wl_list_insert(compositor->base.output_list.prev, &output->base.link);
+	wl_list_insert(backend->compositor->output_list.prev, &output->base.link);
 
 	weston_log("Raspberry Pi HDMI output %dx%d px\n",
 		   output->mode.width, output->mode.height);
@@ -381,38 +382,39 @@  out_free:
 }
 
 static void
-rpi_compositor_destroy(struct weston_compositor *base)
+rpi_backend_destroy(struct weston_compositor *base)
 {
-	struct rpi_compositor *compositor = to_rpi_compositor(base);
+	struct rpi_backend *backend = to_rpi_backend(base);
 
-	udev_input_destroy(&compositor->input);
+	udev_input_destroy(&backend->input);
 
 	/* destroys outputs, too */
-	weston_compositor_shutdown(&compositor->base);
+	weston_compositor_shutdown(base);
 
-	weston_launcher_destroy(compositor->base.launcher);
+	weston_launcher_destroy(base->launcher);
 
 	bcm_host_deinit();
-	free(compositor);
+	free(backend);
 }
 
 static void
 session_notify(struct wl_listener *listener, void *data)
 {
-	struct rpi_compositor *compositor = data;
+	struct weston_compositor *compositor = data;
+	struct rpi_backend *backend = to_rpi_backend(compositor);
 	struct weston_output *output;
 
-	if (compositor->base.session_active) {
+	if (compositor->session_active) {
 		weston_log("activating session\n");
-		compositor->base.state = compositor->prev_state;
-		weston_compositor_damage_all(&compositor->base);
-		udev_input_enable(&compositor->input);
+		compositor->state = backend->prev_state;
+		weston_compositor_damage_all(compositor);
+		udev_input_enable(&backend->input);
 	} else {
 		weston_log("deactivating session\n");
-		udev_input_disable(&compositor->input);
+		udev_input_disable(&backend->input);
 
-		compositor->prev_state = compositor->base.state;
-		weston_compositor_offscreen(&compositor->base);
+		backend->prev_state = compositor->state;
+		weston_compositor_offscreen(compositor);
 
 		/* If we have a repaint scheduled (either from a
 		 * pending pageflip or the idle handler), make sure we
@@ -423,7 +425,7 @@  session_notify(struct wl_listener *listener, void *data)
 		 * pending frame callbacks. */
 
 		wl_list_for_each(output,
-				 &compositor->base.output_list, link) {
+				 &compositor->output_list, link) {
 			output->repaint_needed = 0;
 		}
 	};
@@ -449,57 +451,52 @@  struct rpi_parameters {
 	uint32_t output_transform;
 };
 
-static struct weston_compositor *
-rpi_compositor_create(struct wl_display *display, int *argc, char *argv[],
-		      struct weston_config *config,
-		      struct rpi_parameters *param)
+static struct rpi_backend *
+rpi_backend_create(struct weston_compositor *compositor,
+		   struct rpi_parameters *param)
 {
-	struct rpi_compositor *compositor;
+	struct rpi_backend *backend;
 	uint32_t key;
 
 	weston_log("initializing Raspberry Pi backend\n");
 
-	compositor = zalloc(sizeof *compositor);
-	if (compositor == NULL)
+	backend = zalloc(sizeof *backend);
+	if (backend == NULL)
 		return NULL;
 
-	if (weston_compositor_init(&compositor->base, display, argc, argv,
-				   config) < 0)
-		goto out_free;
-
 	if (weston_compositor_set_presentation_clock_software(
-							&compositor->base) < 0)
+							compositor) < 0)
 		goto out_compositor;
 
-	compositor->udev = udev_new();
-	if (compositor->udev == NULL) {
+	backend->udev = udev_new();
+	if (backend->udev == NULL) {
 		weston_log("Failed to initialize udev context.\n");
 		goto out_compositor;
 	}
 
-	compositor->session_listener.notify = session_notify;
-	wl_signal_add(&compositor->base.session_signal,
-		      &compositor ->session_listener);
-	compositor->base.launcher =
-		weston_launcher_connect(&compositor->base, param->tty, "seat0");
-	if (!compositor->base.launcher) {
+	backend->session_listener.notify = session_notify;
+	wl_signal_add(&compositor->session_signal,
+		      &backend->session_listener);
+	compositor->launcher =
+		weston_launcher_connect(compositor, param->tty, "seat0");
+	if (!compositor->launcher) {
 		weston_log("Failed to initialize tty.\n");
 		goto out_udev;
 	}
 
-	compositor->base.destroy = rpi_compositor_destroy;
-	compositor->base.restore = rpi_restore;
+	backend->base.destroy = rpi_backend_destroy;
+	backend->base.restore = rpi_restore;
 
-	compositor->prev_state = WESTON_COMPOSITOR_ACTIVE;
-	compositor->single_buffer = param->renderer.single_buffer;
+	backend->prev_state = WESTON_COMPOSITOR_ACTIVE;
+	backend->single_buffer = param->renderer.single_buffer;
 
 	weston_log("Dispmanx planes are %s buffered.\n",
-		   compositor->single_buffer ? "single" : "double");
+		   backend->single_buffer ? "single" : "double");
 
 	for (key = KEY_F1; key < KEY_F9; key++)
-		weston_compositor_add_key_binding(&compositor->base, key,
+		weston_compositor_add_key_binding(compositor, key,
 						  MODIFIER_CTRL | MODIFIER_ALT,
-						  switch_vt_binding, compositor);
+						  switch_vt_binding, backend);
 
 	/*
 	 * bcm_host_init() creates threads.
@@ -510,45 +507,46 @@  rpi_compositor_create(struct wl_display *display, int *argc, char *argv[],
 	 */
 	bcm_host_init();
 
-	if (rpi_renderer_create(&compositor->base, &param->renderer) < 0)
+	if (rpi_renderer_create(compositor, &param->renderer) < 0)
 		goto out_launcher;
 
-	if (rpi_output_create(compositor, param->output_transform) < 0)
+	if (rpi_output_create(backend, param->output_transform) < 0)
 		goto out_renderer;
 
-	if (udev_input_init(&compositor->input,
-			    &compositor->base,
-			    compositor->udev, "seat0") != 0) {
+	if (udev_input_init(&backend->input,
+			    compositor,
+			    backend->udev, "seat0") != 0) {
 		weston_log("Failed to initialize udev input.\n");
 		goto out_renderer;
 	}
 
-	return &compositor->base;
+	return backend;
 
 out_renderer:
-	compositor->base.renderer->destroy(&compositor->base);
+	compositor->renderer->destroy(compositor);
 
 out_launcher:
-	weston_launcher_destroy(compositor->base.launcher);
+	weston_launcher_destroy(compositor->launcher);
 
 out_udev:
-	udev_unref(compositor->udev);
+	udev_unref(backend->udev);
 
 out_compositor:
-	weston_compositor_shutdown(&compositor->base);
+	weston_compositor_shutdown(compositor);
 
-out_free:
 	bcm_host_deinit();
-	free(compositor);
+	free(backend);
 
 	return NULL;
 }
 
-WL_EXPORT struct weston_compositor *
-backend_init(struct wl_display *display, int *argc, char *argv[],
+WL_EXPORT int
+backend_init(struct weston_compositor *compositor,
+	     int *argc, char *argv[],
 	     struct weston_config *config)
 {
 	const char *transform = "normal";
+	struct rpi_backend *b;
 
 	struct rpi_parameters param = {
 		.tty = 0, /* default to current tty */
@@ -571,5 +569,8 @@  backend_init(struct wl_display *display, int *argc, char *argv[],
 	if (weston_parse_transform(transform, &param.output_transform) < 0)
 		weston_log("invalid transform \"%s\"\n", transform);
 
-	return rpi_compositor_create(display, argc, argv, config, &param);
+	b = rpi_backend_create(compositor, &param);
+	if (b == NULL)
+		return -1;
+	return 0;
 }
diff --git a/src/compositor-wayland.c b/src/compositor-wayland.c
index 65bce39..6265d9c 100644
--- a/src/compositor-wayland.c
+++ b/src/compositor-wayland.c
@@ -46,8 +46,9 @@ 
 
 #define WINDOW_TITLE "Weston Compositor"
 
-struct wayland_compositor {
-	struct weston_compositor base;
+struct wayland_backend {
+	struct weston_backend base;
+	struct weston_compositor *compositor;
 
 	struct {
 		struct wl_display *wl_display;
@@ -152,7 +153,7 @@  struct wayland_shm_buffer {
 
 struct wayland_input {
 	struct weston_seat base;
-	struct wayland_compositor *compositor;
+	struct wayland_backend *backend;
 	struct wl_list link;
 
 	struct {
@@ -212,9 +213,9 @@  static const struct wl_buffer_listener buffer_listener = {
 static struct wayland_shm_buffer *
 wayland_output_get_shm_buffer(struct wayland_output *output)
 {
-	struct wayland_compositor *c =
-		(struct wayland_compositor *) output->base.compositor;
-	struct wl_shm *shm = c->parent.shm;
+	struct wayland_backend *b =
+		(struct wayland_backend *) output->base.compositor->backend;
+	struct wl_shm *shm = b->parent.shm;
 	struct wayland_shm_buffer *sb;
 
 	struct wl_shm_pool *pool;
@@ -412,8 +413,8 @@  static void
 wayland_output_start_repaint_loop(struct weston_output *output_base)
 {
 	struct wayland_output *output = (struct wayland_output *) output_base;
-	struct wayland_compositor *wc =
-		(struct wayland_compositor *)output->base.compositor;
+	struct wayland_backend *wb =
+		(struct wayland_backend *)output->base.compositor->backend;
 	struct wl_callback *callback;
 
 	/* If this is the initial frame, we need to attach a buffer so that
@@ -430,7 +431,7 @@  wayland_output_start_repaint_loop(struct weston_output *output_base)
 	callback = wl_surface_frame(output->parent.surface);
 	wl_callback_add_listener(callback, &frame_listener, output);
 	wl_surface_commit(output->parent.surface);
-	wl_display_flush(wc->parent.wl_display);
+	wl_display_flush(wb->parent.wl_display);
 }
 
 static int
@@ -545,8 +546,8 @@  wayland_output_repaint_pixman(struct weston_output *output_base,
 			      pixman_region32_t *damage)
 {
 	struct wayland_output *output = (struct wayland_output *) output_base;
-	struct wayland_compositor *c =
-		(struct wayland_compositor *)output->base.compositor;
+	struct wayland_backend *b =
+		(struct wayland_backend *)output->base.compositor->backend;
 	struct wl_callback *callback;
 	struct wayland_shm_buffer *sb;
 
@@ -563,21 +564,21 @@  wayland_output_repaint_pixman(struct weston_output *output_base,
 
 	wayland_output_update_shm_border(sb);
 	pixman_renderer_output_set_buffer(output_base, sb->pm_image);
-	c->base.renderer->repaint_output(output_base, &sb->damage);
+	b->compositor->renderer->repaint_output(output_base, &sb->damage);
 
 	wayland_shm_buffer_attach(sb);
 
 	callback = wl_surface_frame(output->parent.surface);
 	wl_callback_add_listener(callback, &frame_listener, output);
 	wl_surface_commit(output->parent.surface);
-	wl_display_flush(c->parent.wl_display);
+	wl_display_flush(b->parent.wl_display);
 
 	pixman_region32_fini(&sb->damage);
 	pixman_region32_init(&sb->damage);
 	sb->frame_damaged = 0;
 
-	pixman_region32_subtract(&c->base.primary_plane.damage,
-				 &c->base.primary_plane.damage, damage);
+	pixman_region32_subtract(&b->compositor->primary_plane.damage,
+				 &b->compositor->primary_plane.damage, damage);
 	return 0;
 }
 
@@ -585,10 +586,10 @@  static void
 wayland_output_destroy(struct weston_output *output_base)
 {
 	struct wayland_output *output = (struct wayland_output *) output_base;
-	struct wayland_compositor *c =
-		(struct wayland_compositor *) output->base.compositor;
+	struct wayland_backend *b =
+		(struct wayland_backend *) output->base.compositor->backend;
 
-	if (c->use_pixman) {
+	if (b->use_pixman) {
 		pixman_renderer_output_destroy(output_base);
 	} else {
 		gl_renderer->output_destroy(output_base);
@@ -658,8 +659,8 @@  wayland_output_init_pixman_renderer(struct wayland_output *output)
 static void
 wayland_output_resize_surface(struct wayland_output *output)
 {
-	struct wayland_compositor *c =
-		(struct wayland_compositor *)output->base.compositor;
+	struct wayland_backend *b =
+		(struct wayland_backend *)output->base.compositor->backend;
 	struct wayland_shm_buffer *buffer, *next;
 	int32_t ix, iy, iwidth, iheight;
 	int32_t width, height;
@@ -672,13 +673,13 @@  wayland_output_resize_surface(struct wayland_output *output)
 		frame_resize_inside(output->frame, width, height);
 
 		frame_input_rect(output->frame, &ix, &iy, &iwidth, &iheight);
-		region = wl_compositor_create_region(c->parent.compositor);
+		region = wl_compositor_create_region(b->parent.compositor);
 		wl_region_add(region, ix, iy, iwidth, iheight);
 		wl_surface_set_input_region(output->parent.surface, region);
 		wl_region_destroy(region);
 
 		frame_opaque_rect(output->frame, &ix, &iy, &iwidth, &iheight);
-		region = wl_compositor_create_region(c->parent.compositor);
+		region = wl_compositor_create_region(b->parent.compositor);
 		wl_region_add(region, ix, iy, iwidth, iheight);
 		wl_surface_set_opaque_region(output->parent.surface, region);
 		wl_region_destroy(region);
@@ -686,12 +687,12 @@  wayland_output_resize_surface(struct wayland_output *output)
 		width = frame_width(output->frame);
 		height = frame_height(output->frame);
 	} else {
-		region = wl_compositor_create_region(c->parent.compositor);
+		region = wl_compositor_create_region(b->parent.compositor);
 		wl_region_add(region, 0, 0, width, height);
 		wl_surface_set_input_region(output->parent.surface, region);
 		wl_region_destroy(region);
 
-		region = wl_compositor_create_region(c->parent.compositor);
+		region = wl_compositor_create_region(b->parent.compositor);
 		wl_region_add(region, 0, 0, width, height);
 		wl_surface_set_opaque_region(output->parent.surface, region);
 		wl_region_destroy(region);
@@ -735,8 +736,8 @@  wayland_output_resize_surface(struct wayland_output *output)
 static int
 wayland_output_set_windowed(struct wayland_output *output)
 {
-	struct wayland_compositor *c =
-		(struct wayland_compositor *)output->base.compositor;
+	struct wayland_backend *b =
+		(struct wayland_backend *)output->base.compositor->backend;
 	int tlen;
 	char *title;
 
@@ -754,14 +755,14 @@  wayland_output_set_windowed(struct wayland_output *output)
 		title = strdup(WINDOW_TITLE);
 	}
 
-	if (!c->theme) {
-		c->theme = theme_create();
-		if (!c->theme) {
+	if (!b->theme) {
+		b->theme = theme_create();
+		if (!b->theme) {
 			free(title);
 			return -1;
 		}
 	}
-	output->frame = frame_create(c->theme, 100, 100,
+	output->frame = frame_create(b->theme, 100, 100,
 				     FRAME_BUTTON_CLOSE, title);
 	free(title);
 	if (!output->frame)
@@ -782,8 +783,8 @@  wayland_output_set_fullscreen(struct wayland_output *output,
 			      enum wl_shell_surface_fullscreen_method method,
 			      uint32_t framerate, struct wl_output *target)
 {
-	struct wayland_compositor *c =
-		(struct wayland_compositor *)output->base.compositor;
+	struct wayland_backend *b =
+		(struct wayland_backend *)output->base.compositor->backend;
 
 	if (output->frame) {
 		frame_destroy(output->frame);
@@ -795,8 +796,8 @@  wayland_output_set_fullscreen(struct wayland_output *output,
 	if (output->parent.shell_surface) {
 		wl_shell_surface_set_fullscreen(output->parent.shell_surface,
 						method, framerate, target);
-	} else if (c->parent.fshell) {
-		_wl_fullscreen_shell_present_surface(c->parent.fshell,
+	} else if (b->parent.fshell) {
+		_wl_fullscreen_shell_present_surface(b->parent.fshell,
 						     output->parent.surface,
 						     method, target);
 	}
@@ -874,7 +875,7 @@  wayland_output_switch_mode(struct weston_output *output_base,
 			   struct weston_mode *mode)
 {
 	struct wayland_output *output = (struct wayland_output *) output_base;
-	struct wayland_compositor *c;
+	struct wayland_backend *b;
 	struct wl_surface *old_surface;
 	struct weston_mode *old_mode;
 	struct _wl_fullscreen_shell_mode_feedback *mode_feedback;
@@ -891,9 +892,9 @@  wayland_output_switch_mode(struct weston_output *output_base,
 		return -1;
 	}
 
-	c = (struct wayland_compositor *)output_base->compositor;
+	b = (struct wayland_backend *)output_base->compositor->backend;
 
-	if (output->parent.shell_surface || !c->parent.fshell)
+	if (output->parent.shell_surface || !b->parent.fshell)
 		return -1;
 
 	mode = wayland_output_choose_mode(output, mode);
@@ -907,14 +908,14 @@  wayland_output_switch_mode(struct weston_output *output_base,
 	old_surface = output->parent.surface;
 	output->base.current_mode = mode;
 	output->parent.surface =
-		wl_compositor_create_surface(c->parent.compositor);
+		wl_compositor_create_surface(b->parent.compositor);
 	wl_surface_set_user_data(output->parent.surface, output);
 
 	/* Blow the old buffers because we changed size/surfaces */
 	wayland_output_resize_surface(output);
 
 	mode_feedback =
-		_wl_fullscreen_shell_present_surface_for_mode(c->parent.fshell,
+		_wl_fullscreen_shell_present_surface_for_mode(b->parent.fshell,
 							      output->parent.surface,
 							      output->parent.output,
 							      mode->refresh);
@@ -928,7 +929,7 @@  wayland_output_switch_mode(struct weston_output *output_base,
 
 	mode_status = MODE_STATUS_UNKNOWN;
 	while (mode_status == MODE_STATUS_UNKNOWN && ret >= 0)
-		ret = wl_display_dispatch(c->parent.wl_display);
+		ret = wl_display_dispatch(b->parent.wl_display);
 
 	_wl_fullscreen_shell_mode_feedback_destroy(mode_feedback);
 
@@ -944,7 +945,7 @@  wayland_output_switch_mode(struct weston_output *output_base,
 	old_mode->flags &= ~WL_OUTPUT_MODE_CURRENT;
 	output->base.current_mode->flags |= WL_OUTPUT_MODE_CURRENT;
 
-	if (c->use_pixman) {
+	if (b->use_pixman) {
 		pixman_renderer_output_destroy(output_base);
 		if (wayland_output_init_pixman_renderer(output) < 0)
 			goto err_output;
@@ -966,7 +967,7 @@  err_output:
 }
 
 static struct wayland_output *
-wayland_output_create(struct wayland_compositor *c, int x, int y,
+wayland_output_create(struct wayland_backend *b, int x, int y,
 		      int width, int height, const char *name, int fullscreen,
 		      uint32_t transform, int32_t scale)
 {
@@ -988,16 +989,16 @@  wayland_output_create(struct wayland_compositor *c, int x, int y,
 	output_height = height * scale;
 
 	output->parent.surface =
-		wl_compositor_create_surface(c->parent.compositor);
+		wl_compositor_create_surface(b->parent.compositor);
 	if (!output->parent.surface)
 		goto err_name;
 	wl_surface_set_user_data(output->parent.surface, output);
 
 	output->parent.draw_initial_frame = 1;
 
-	if (c->parent.shell) {
+	if (b->parent.shell) {
 		output->parent.shell_surface =
-			wl_shell_get_shell_surface(c->parent.shell,
+			wl_shell_get_shell_surface(b->parent.shell,
 						   output->parent.surface);
 		if (!output->parent.shell_surface)
 			goto err_surface;
@@ -1005,10 +1006,10 @@  wayland_output_create(struct wayland_compositor *c, int x, int y,
 					      &shell_surface_listener, output);
 	}
 
-	if (fullscreen && c->parent.shell) {
+	if (fullscreen && b->parent.shell) {
 		wl_shell_surface_set_fullscreen(output->parent.shell_surface,
 						0, 0, NULL);
-		wl_display_roundtrip(c->parent.wl_display);
+		wl_display_roundtrip(b->parent.wl_display);
 		if (!width)
 			output_width = output->parent.configure_width;
 		if (!height)
@@ -1028,10 +1029,10 @@  wayland_output_create(struct wayland_compositor *c, int x, int y,
 	wl_list_init(&output->shm.buffers);
 	wl_list_init(&output->shm.free_buffers);
 
-	weston_output_init(&output->base, &c->base, x, y, width, height,
+	weston_output_init(&output->base, b->compositor, x, y, width, height,
 			   transform, scale);
 
-	if (c->use_pixman) {
+	if (b->use_pixman) {
 		if (wayland_output_init_pixman_renderer(output) < 0)
 			goto err_output;
 		output->base.repaint = wayland_output_repaint_pixman;
@@ -1048,7 +1049,7 @@  wayland_output_create(struct wayland_compositor *c, int x, int y,
 	output->base.set_dpms = NULL;
 	output->base.switch_mode = wayland_output_switch_mode;
 
-	wl_list_insert(c->base.output_list.prev, &output->base.link);
+	wl_list_insert(b->compositor->output_list.prev, &output->base.link);
 
 	return output;
 
@@ -1068,7 +1069,7 @@  err_name:
 }
 
 static struct wayland_output *
-wayland_output_create_for_config(struct wayland_compositor *c,
+wayland_output_create_for_config(struct wayland_backend *b,
 				 struct weston_config_section *config_section,
 				 int option_width, int option_height,
 				 int option_scale, int32_t x, int32_t y)
@@ -1119,7 +1120,7 @@  wayland_output_create_for_config(struct wayland_compositor *c,
 			   t, name);
 	free(t);
 
-	output = wayland_output_create(c, x, y, width, height, name, 0,
+	output = wayland_output_create(b, x, y, width, height, name, 0,
 				       transform, scale);
 	free(name);
 
@@ -1127,7 +1128,7 @@  wayland_output_create_for_config(struct wayland_compositor *c,
 }
 
 static struct wayland_output *
-wayland_output_create_for_parent_output(struct wayland_compositor *c,
+wayland_output_create_for_parent_output(struct wayland_backend *b,
 					struct wayland_parent_output *poutput)
 {
 	struct wayland_output *output;
@@ -1146,15 +1147,15 @@  wayland_output_create_for_parent_output(struct wayland_compositor *c,
 		return NULL;
 	}
 
-	if (!wl_list_empty(&c->base.output_list)) {
-		output = container_of(c->base.output_list.prev,
+	if (!wl_list_empty(&b->compositor->output_list)) {
+		output = container_of(b->compositor->output_list.prev,
 				      struct wayland_output, base.link);
 		x = output->base.x + output->base.current_mode->width;
 	} else {
 		x = 0;
 	}
 
-	output = wayland_output_create(c, x, 0, mode->width, mode->height,
+	output = wayland_output_create(b, x, 0, mode->width, mode->height,
 				       NULL, 0,
 				       WL_OUTPUT_TRANSFORM_NORMAL, 1);
 	if (!output)
@@ -1176,13 +1177,13 @@  wayland_output_create_for_parent_output(struct wayland_compositor *c,
 		wl_shell_surface_set_fullscreen(output->parent.shell_surface,
 						WL_SHELL_SURFACE_FULLSCREEN_METHOD_DRIVER,
 						mode->refresh, poutput->global);
-	} else if (c->parent.fshell) {
-		_wl_fullscreen_shell_present_surface(c->parent.fshell,
+	} else if (b->parent.fshell) {
+		_wl_fullscreen_shell_present_surface(b->parent.fshell,
 						     output->parent.surface,
 						     _WL_FULLSCREEN_SHELL_PRESENT_METHOD_CENTER,
 						     poutput->global);
 		_wl_fullscreen_shell_mode_feedback_destroy(
-			_wl_fullscreen_shell_present_surface_for_mode(c->parent.fshell,
+			_wl_fullscreen_shell_present_surface_for_mode(b->parent.fshell,
 								      output->parent.surface,
 								      poutput->global,
 								      mode->refresh));
@@ -1231,10 +1232,10 @@  input_set_cursor(struct wayland_input *input)
 	struct wl_buffer *buffer;
 	struct wl_cursor_image *image;
 
-	if (!input->compositor->cursor)
+	if (!input->backend->cursor)
 		return; /* Couldn't load the cursor. Can't set it */
 
-	image = input->compositor->cursor->images[0];
+	image = input->backend->cursor->images[0];
 	buffer = wl_cursor_image_get_buffer(image);
 	if (!buffer)
 		return;
@@ -1375,7 +1376,7 @@  input_handle_button(void *data, struct wl_pointer *pointer,
 		}
 
 		if (frame_status(input->output->frame) & FRAME_STATUS_CLOSE)
-			wl_display_terminate(input->compositor->base.wl_display);
+			wl_display_terminate(input->backend->compositor->wl_display);
 
 		if (frame_status(input->output->frame) & FRAME_STATUS_REPAINT)
 			weston_output_schedule_repaint(&input->output->base);
@@ -1424,7 +1425,7 @@  input_handle_keymap(void *data, struct wl_keyboard *keyboard, uint32_t format,
 			goto error;
 		}
 
-		keymap = xkb_keymap_new_from_string(input->compositor->base.xkb_context,
+		keymap = xkb_keymap_new_from_string(input->backend->compositor->xkb_context,
 						    map_str,
 						    XKB_KEYMAP_FORMAT_TEXT_V1,
 						    0);
@@ -1543,16 +1544,16 @@  input_handle_modifiers(void *data, struct wl_keyboard *keyboard,
 		       uint32_t group)
 {
 	struct wayland_input *input = data;
-	struct wayland_compositor *c = input->compositor;
+	struct wayland_backend *b = input->backend;
 	uint32_t serial_out;
 
 	/* If we get a key event followed by a modifier event with the
 	 * same serial number, then we try to preserve those semantics by
 	 * reusing the same serial number on the way out too. */
 	if (serial_in == input->key_serial)
-		serial_out = wl_display_get_serial(c->base.wl_display);
+		serial_out = wl_display_get_serial(b->compositor->wl_display);
 	else
-		serial_out = wl_display_next_serial(c->base.wl_display);
+		serial_out = wl_display_next_serial(b->compositor->wl_display);
 
 	xkb_state_update_mask(input->base.keyboard->xkb_state.state,
 			      mods_depressed, mods_latched,
@@ -1565,10 +1566,10 @@  input_handle_repeat_info(void *data, struct wl_keyboard *keyboard,
 			 int32_t rate, int32_t delay)
 {
 	struct wayland_input *input = data;
-	struct wayland_compositor *c = input->compositor;
+	struct wayland_backend *b = input->backend;
 
-	c->base.kb_repeat_rate = rate;
-	c->base.kb_repeat_delay = delay;
+	b->compositor->kb_repeat_rate = rate;
+	b->compositor->kb_repeat_delay = delay;
 }
 
 static const struct wl_keyboard_listener keyboard_listener = {
@@ -1620,7 +1621,7 @@  static const struct wl_seat_listener seat_listener = {
 };
 
 static void
-display_add_seat(struct wayland_compositor *c, uint32_t id, uint32_t version)
+display_add_seat(struct wayland_backend *b, uint32_t id, uint32_t version)
 {
 	struct wayland_input *input;
 
@@ -1628,17 +1629,17 @@  display_add_seat(struct wayland_compositor *c, uint32_t id, uint32_t version)
 	if (input == NULL)
 		return;
 
-	weston_seat_init(&input->base, &c->base, "default");
-	input->compositor = c;
-	input->parent.seat = wl_registry_bind(c->parent.registry, id,
+	weston_seat_init(&input->base, b->compositor, "default");
+	input->backend = b;
+	input->parent.seat = wl_registry_bind(b->parent.registry, id,
 					      &wl_seat_interface, MIN(version, 4));
-	wl_list_insert(c->input_list.prev, &input->link);
+	wl_list_insert(b->input_list.prev, &input->link);
 
 	wl_seat_add_listener(input->parent.seat, &seat_listener, input);
 	wl_seat_set_user_data(input->parent.seat, input);
 
 	input->parent.cursor.surface =
-		wl_compositor_create_surface(c->parent.compositor);
+		wl_compositor_create_surface(b->parent.compositor);
 }
 
 static void
@@ -1720,7 +1721,7 @@  static const struct wl_output_listener output_listener = {
 };
 
 static void
-wayland_compositor_register_output(struct wayland_compositor *c, uint32_t id)
+wayland_backend_register_output(struct wayland_backend *b, uint32_t id)
 {
 	struct wayland_parent_output *output;
 
@@ -1729,7 +1730,7 @@  wayland_compositor_register_output(struct wayland_compositor *c, uint32_t id)
 		return;
 
 	output->id = id;
-	output->global = wl_registry_bind(c->parent.registry, id,
+	output->global = wl_registry_bind(b->parent.registry, id,
 					  &wl_output_interface, 1);
 	if (!output->global) {
 		free(output);
@@ -1742,11 +1743,11 @@  wayland_compositor_register_output(struct wayland_compositor *c, uint32_t id)
 	output->transform = WL_OUTPUT_TRANSFORM_NORMAL;
 	output->physical.subpixel = WL_OUTPUT_SUBPIXEL_UNKNOWN;
 	wl_list_init(&output->mode_list);
-	wl_list_insert(&c->parent.output_list, &output->link);
+	wl_list_insert(&b->parent.output_list, &output->link);
 
-	if (c->sprawl_across_outputs) {
-		wl_display_roundtrip(c->parent.wl_display);
-		wayland_output_create_for_parent_output(c, output);
+	if (b->sprawl_across_outputs) {
+		wl_display_roundtrip(b->parent.wl_display);
+		wayland_output_create_for_parent_output(b, output);
 	}
 }
 
@@ -1772,26 +1773,26 @@  static void
 registry_handle_global(void *data, struct wl_registry *registry, uint32_t name,
 		       const char *interface, uint32_t version)
 {
-	struct wayland_compositor *c = data;
+	struct wayland_backend *b = data;
 
 	if (strcmp(interface, "wl_compositor") == 0) {
-		c->parent.compositor =
+		b->parent.compositor =
 			wl_registry_bind(registry, name,
 					 &wl_compositor_interface, 1);
 	} else if (strcmp(interface, "wl_shell") == 0) {
-		c->parent.shell =
+		b->parent.shell =
 			wl_registry_bind(registry, name,
 					 &wl_shell_interface, 1);
 	} else if (strcmp(interface, "_wl_fullscreen_shell") == 0) {
-		c->parent.fshell =
+		b->parent.fshell =
 			wl_registry_bind(registry, name,
 					 &_wl_fullscreen_shell_interface, 1);
 	} else if (strcmp(interface, "wl_seat") == 0) {
-		display_add_seat(c, name, version);
+		display_add_seat(b, name, version);
 	} else if (strcmp(interface, "wl_output") == 0) {
-		wayland_compositor_register_output(c, name);
+		wayland_backend_register_output(b, name);
 	} else if (strcmp(interface, "wl_shm") == 0) {
-		c->parent.shm =
+		b->parent.shm =
 			wl_registry_bind(registry, name, &wl_shm_interface, 1);
 	}
 }
@@ -1800,10 +1801,10 @@  static void
 registry_handle_global_remove(void *data, struct wl_registry *registry,
 			      uint32_t name)
 {
-	struct wayland_compositor *c = data;
+	struct wayland_backend *b = data;
 	struct wayland_parent_output *output;
 
-	wl_list_for_each(output, &c->parent.output_list, link)
+	wl_list_for_each(output, &b->parent.output_list, link)
 		if (output->id == name)
 			wayland_parent_output_destroy(output);
 }
@@ -1814,24 +1815,24 @@  static const struct wl_registry_listener registry_listener = {
 };
 
 static int
-wayland_compositor_handle_event(int fd, uint32_t mask, void *data)
+wayland_backend_handle_event(int fd, uint32_t mask, void *data)
 {
-	struct wayland_compositor *c = data;
+	struct wayland_backend *b = data;
 	int count = 0;
 
 	if ((mask & WL_EVENT_HANGUP) || (mask & WL_EVENT_ERROR)) {
-		wl_display_terminate(c->base.wl_display);
+		wl_display_terminate(b->compositor->wl_display);
 		return 0;
 	}
 
 	if (mask & WL_EVENT_READABLE)
-		count = wl_display_dispatch(c->parent.wl_display);
+		count = wl_display_dispatch(b->parent.wl_display);
 	if (mask & WL_EVENT_WRITABLE)
-		wl_display_flush(c->parent.wl_display);
+		wl_display_flush(b->parent.wl_display);
 
 	if (mask == 0) {
-		count = wl_display_dispatch_pending(c->parent.wl_display);
-		wl_display_flush(c->parent.wl_display);
+		count = wl_display_dispatch_pending(b->parent.wl_display);
+		wl_display_flush(b->parent.wl_display);
 	}
 
 	return count;
@@ -1845,14 +1846,14 @@  wayland_restore(struct weston_compositor *ec)
 static void
 wayland_destroy(struct weston_compositor *ec)
 {
-	struct wayland_compositor *c = (struct wayland_compositor *) ec;
+	struct wayland_backend *b = (struct wayland_backend *) ec->backend;
 
 	weston_compositor_shutdown(ec);
 
-	if (c->parent.shm)
-		wl_shm_destroy(c->parent.shm);
+	if (b->parent.shm)
+		wl_shm_destroy(b->parent.shm);
 
-	free(ec);
+	free(b);
 }
 
 static const char *left_ptrs[] = {
@@ -1863,7 +1864,7 @@  static const char *left_ptrs[] = {
 };
 
 static void
-create_cursor(struct wayland_compositor *c, struct weston_config *config)
+create_cursor(struct wayland_backend *b, struct weston_config *config)
 {
 	struct weston_config_section *s;
 	int size;
@@ -1874,19 +1875,19 @@  create_cursor(struct wayland_compositor *c, struct weston_config *config)
 	weston_config_section_get_string(s, "cursor-theme", &theme, NULL);
 	weston_config_section_get_int(s, "cursor-size", &size, 32);
 
-	c->cursor_theme = wl_cursor_theme_load(theme, size, c->parent.shm);
-	if (!c->cursor_theme) {
+	b->cursor_theme = wl_cursor_theme_load(theme, size, b->parent.shm);
+	if (!b->cursor_theme) {
 		fprintf(stderr, "could not load cursor theme\n");
 		return;
 	}
 
 	free(theme);
 
-	c->cursor = NULL;
-	for (i = 0; !c->cursor && i < ARRAY_LENGTH(left_ptrs); ++i)
-		c->cursor = wl_cursor_theme_get_cursor(c->cursor_theme,
+	b->cursor = NULL;
+	for (i = 0; !b->cursor && i < ARRAY_LENGTH(left_ptrs); ++i)
+		b->cursor = wl_cursor_theme_get_cursor(b->cursor_theme,
 						       left_ptrs[i]);
-	if (!c->cursor) {
+	if (!b->cursor) {
 		fprintf(stderr, "could not load left cursor\n");
 		return;
 	}
@@ -1896,10 +1897,10 @@  static void
 fullscreen_binding(struct weston_seat *seat_base, uint32_t time, uint32_t key,
 		   void *data)
 {
-	struct wayland_compositor *c = data;
+	struct wayland_backend *b = data;
 	struct wayland_input *input = NULL;
 
-	wl_list_for_each(input, &c->input_list, link)
+	wl_list_for_each(input, &b->input_list, link)
 		if (&input->base == seat_base)
 			break;
 
@@ -1914,120 +1915,120 @@  fullscreen_binding(struct weston_seat *seat_base, uint32_t time, uint32_t key,
 	weston_output_schedule_repaint(&input->output->base);
 }
 
-static struct wayland_compositor *
-wayland_compositor_create(struct wl_display *display, int use_pixman,
-			  const char *display_name, int *argc, char *argv[],
-			  struct weston_config *config)
+static struct wayland_backend *
+wayland_backend_create(struct weston_compositor *compositor, int use_pixman,
+		       const char *display_name, int *argc, char *argv[],
+		       struct weston_config *config)
 {
-	struct wayland_compositor *c;
+	struct wayland_backend *b;
 	struct wl_event_loop *loop;
 	int fd;
 
-	c = zalloc(sizeof *c);
-	if (c == NULL)
+	b = zalloc(sizeof *b);
+	if (b == NULL)
 		return NULL;
 
-	if (weston_compositor_init(&c->base, display, argc, argv,
+	b->compositor = compositor;
+	if (weston_compositor_init(compositor, argc, argv,
 				   config) < 0)
 		goto err_free;
 
-	if (weston_compositor_set_presentation_clock_software(&c->base) < 0)
+	if (weston_compositor_set_presentation_clock_software(compositor) < 0)
 		goto err_compositor;
 
-	c->parent.wl_display = wl_display_connect(display_name);
-	if (c->parent.wl_display == NULL) {
+	b->parent.wl_display = wl_display_connect(display_name);
+	if (b->parent.wl_display == NULL) {
 		weston_log("failed to create display: %m\n");
 		goto err_compositor;
 	}
 
-	wl_list_init(&c->parent.output_list);
-	wl_list_init(&c->input_list);
-	c->parent.registry = wl_display_get_registry(c->parent.wl_display);
-	wl_registry_add_listener(c->parent.registry, &registry_listener, c);
-	wl_display_roundtrip(c->parent.wl_display);
+	wl_list_init(&b->parent.output_list);
+	wl_list_init(&b->input_list);
+	b->parent.registry = wl_display_get_registry(b->parent.wl_display);
+	wl_registry_add_listener(b->parent.registry, &registry_listener, b);
+	wl_display_roundtrip(b->parent.wl_display);
 
-	create_cursor(c, config);
+	create_cursor(b, config);
 
-	c->base.wl_display = display;
+	b->use_pixman = use_pixman;
 
-	c->use_pixman = use_pixman;
-
-	if (!c->use_pixman) {
+	if (!b->use_pixman) {
 		gl_renderer = weston_load_module("gl-renderer.so",
 						 "gl_renderer_interface");
 		if (!gl_renderer)
-			c->use_pixman = 1;
+			b->use_pixman = 1;
 	}
 
-	if (!c->use_pixman) {
-		if (gl_renderer->create(&c->base, c->parent.wl_display,
+	if (!b->use_pixman) {
+		if (gl_renderer->create(compositor, b->parent.wl_display,
 				gl_renderer->alpha_attribs,
 				NULL) < 0) {
 			weston_log("Failed to initialize the GL renderer; "
 				   "falling back to pixman.\n");
-			c->use_pixman = 1;
+			b->use_pixman = 1;
 		}
 	}
 
-	if (c->use_pixman) {
-		if (pixman_renderer_init(&c->base) < 0) {
+	if (b->use_pixman) {
+		if (pixman_renderer_init(compositor) < 0) {
 			weston_log("Failed to initialize pixman renderer\n");
 			goto err_display;
 		}
 	}
 
-	c->base.destroy = wayland_destroy;
-	c->base.restore = wayland_restore;
+	b->base.destroy = wayland_destroy;
+	b->base.restore = wayland_restore;
 
-	loop = wl_display_get_event_loop(c->base.wl_display);
+	loop = wl_display_get_event_loop(compositor->wl_display);
 
-	fd = wl_display_get_fd(c->parent.wl_display);
-	c->parent.wl_source =
+	fd = wl_display_get_fd(b->parent.wl_display);
+	b->parent.wl_source =
 		wl_event_loop_add_fd(loop, fd, WL_EVENT_READABLE,
-				     wayland_compositor_handle_event, c);
-	if (c->parent.wl_source == NULL)
+				     wayland_backend_handle_event, b);
+	if (b->parent.wl_source == NULL)
 		goto err_renderer;
 
-	wl_event_source_check(c->parent.wl_source);
+	wl_event_source_check(b->parent.wl_source);
 
-	return c;
+	compositor->backend = &b->base;
+	return b;
 err_renderer:
-	c->base.renderer->destroy(&c->base);
+	compositor->renderer->destroy(compositor);
 err_display:
-	wl_display_disconnect(c->parent.wl_display);
+	wl_display_disconnect(b->parent.wl_display);
 err_compositor:
-	weston_compositor_shutdown(&c->base);
+	weston_compositor_shutdown(compositor);
 err_free:
-	free(c);
+	free(b);
 	return NULL;
 }
 
 static void
-wayland_compositor_destroy(struct wayland_compositor *c)
+wayland_backend_destroy(struct wayland_backend *b)
 {
 	struct weston_output *output, *next;
 
-	wl_list_for_each_safe(output, next, &c->base.output_list, link)
+	wl_list_for_each_safe(output, next, &b->compositor->output_list, link)
 		wayland_output_destroy(output);
 
-	c->base.renderer->destroy(&c->base);
-	wl_display_disconnect(c->parent.wl_display);
+	b->compositor->renderer->destroy(b->compositor);
+	wl_display_disconnect(b->parent.wl_display);
 
-	if (c->theme)
-		theme_destroy(c->theme);
-	if (c->frame_device)
-		cairo_device_destroy(c->frame_device);
-	wl_cursor_theme_destroy(c->cursor_theme);
+	if (b->theme)
+		theme_destroy(b->theme);
+	if (b->frame_device)
+		cairo_device_destroy(b->frame_device);
+	wl_cursor_theme_destroy(b->cursor_theme);
 
-	weston_compositor_shutdown(&c->base);
-	free(c);
+	weston_compositor_shutdown(b->compositor);
+	free(b);
 }
 
-WL_EXPORT struct weston_compositor *
-backend_init(struct wl_display *display, int *argc, char *argv[],
+WL_EXPORT int
+backend_init(struct weston_compositor *compositor, int *argc, char *argv[],
 	     struct weston_config *config)
 {
-	struct wayland_compositor *c;
+	struct wayland_backend *b;
 	struct wayland_output *output;
 	struct wayland_parent_output *poutput;
 	struct weston_config_section *section;
@@ -2057,29 +2058,29 @@  backend_init(struct wl_display *display, int *argc, char *argv[],
 	parse_options(wayland_options,
 		      ARRAY_LENGTH(wayland_options), argc, argv);
 
-	c = wayland_compositor_create(display, use_pixman, display_name,
-				      argc, argv, config);
-	if (!c)
-		return NULL;
+	b = wayland_backend_create(compositor, use_pixman, display_name,
+				   argc, argv, config);
+	if (!b)
+		return -1;
 
-	if (sprawl || c->parent.fshell) {
-		c->sprawl_across_outputs = 1;
-		wl_display_roundtrip(c->parent.wl_display);
+	if (sprawl || b->parent.fshell) {
+		b->sprawl_across_outputs = 1;
+		wl_display_roundtrip(b->parent.wl_display);
 
-		wl_list_for_each(poutput, &c->parent.output_list, link)
-			wayland_output_create_for_parent_output(c, poutput);
+		wl_list_for_each(poutput, &b->parent.output_list, link)
+			wayland_output_create_for_parent_output(b, poutput);
 
-		return &c->base;
+		return 0;
 	}
 
 	if (fullscreen) {
-		output = wayland_output_create(c, 0, 0, width, height,
+		output = wayland_output_create(b, 0, 0, width, height,
 					       NULL, 1, 0, 1);
 		if (!output)
 			goto err_outputs;
 
 		wayland_output_set_fullscreen(output, 0, 0, NULL);
-		return &c->base;
+		return 0;
 	}
 
 	section = NULL;
@@ -2097,7 +2098,7 @@  backend_init(struct wl_display *display, int *argc, char *argv[],
 		}
 		free(name);
 
-		output = wayland_output_create_for_config(c, section, width,
+		output = wayland_output_create_for_config(b, section, width,
 							  height, scale, x, 0);
 		if (!output)
 			goto err_outputs;
@@ -2115,7 +2116,7 @@  backend_init(struct wl_display *display, int *argc, char *argv[],
 	if (!scale)
 		scale = 1;
 	while (count > 0) {
-		output = wayland_output_create(c, x, 0, width, height,
+		output = wayland_output_create(b, x, 0, width, height,
 					       NULL, 0, 0, scale);
 		if (!output)
 			goto err_outputs;
@@ -2126,13 +2127,13 @@  backend_init(struct wl_display *display, int *argc, char *argv[],
 		--count;
 	}
 
-	weston_compositor_add_key_binding(&c->base, KEY_F,
+	weston_compositor_add_key_binding(compositor, KEY_F,
 				          MODIFIER_CTRL | MODIFIER_ALT,
-				          fullscreen_binding, c);
+				          fullscreen_binding, b);
 
-	return &c->base;
+	return 0;
 
 err_outputs:
-	wayland_compositor_destroy(c);
-	return NULL;
+	wayland_backend_destroy(b);
+	return -1;
 }
diff --git a/src/compositor-x11.c b/src/compositor-x11.c
index a760f33..10c9543 100644
--- a/src/compositor-x11.c
+++ b/src/compositor-x11.c
@@ -59,8 +59,9 @@  static int option_height;
 static int option_scale;
 static int option_count;
 
-struct x11_compositor {
-	struct weston_compositor	 base;
+struct x11_backend {
+	struct weston_backend	 base;
+	struct weston_compositor *compositor;
 
 	Display			*dpy;
 	xcb_connection_t	*conn;
@@ -119,7 +120,7 @@  struct x11_output {
 struct gl_renderer_interface *gl_renderer;
 
 static struct xkb_keymap *
-x11_compositor_get_keymap(struct x11_compositor *c)
+x11_backend_get_keymap(struct x11_backend *b)
 {
 	xcb_get_property_cookie_t cookie;
 	xcb_get_property_reply_t *reply;
@@ -130,9 +131,9 @@  x11_compositor_get_keymap(struct x11_compositor *c)
 
 	memset(&names, 0, sizeof(names));
 
-	cookie = xcb_get_property(c->conn, 0, c->screen->root,
-				  c->atom.xkb_names, c->atom.string, 0, 1024);
-	reply = xcb_get_property_reply(c->conn, cookie, NULL);
+	cookie = xcb_get_property(b->conn, 0, b->screen->root,
+				  b->atom.xkb_names, b->atom.string, 0, 1024);
+	reply = xcb_get_property_reply(b->conn, cookie, NULL);
 	if (reply == NULL)
 		return NULL;
 
@@ -154,16 +155,16 @@  x11_compositor_get_keymap(struct x11_compositor *c)
 	copy_prop_value(options);
 #undef copy_prop_value
 
-	ret = xkb_keymap_new_from_names(c->base.xkb_context, &names, 0);
+	ret = xkb_keymap_new_from_names(b->compositor->xkb_context, &names, 0);
 
 	free(reply);
 	return ret;
 }
 
 static uint32_t
-get_xkb_mod_mask(struct x11_compositor *c, uint32_t in)
+get_xkb_mod_mask(struct x11_backend *b, uint32_t in)
 {
-	struct weston_xkb_info *info = c->core_seat.keyboard->xkb_info;
+	struct weston_xkb_info *info = b->core_seat.keyboard->xkb_info;
 	uint32_t ret = 0;
 
 	if ((in & ShiftMask) && info->shift_mod != XKB_MOD_INVALID)
@@ -187,12 +188,12 @@  get_xkb_mod_mask(struct x11_compositor *c, uint32_t in)
 }
 
 static void
-x11_compositor_setup_xkb(struct x11_compositor *c)
+x11_backend_setup_xkb(struct x11_backend *b)
 {
 #ifndef HAVE_XCB_XKB
 	weston_log("XCB-XKB not available during build\n");
-	c->has_xkb = 0;
-	c->xkb_event_base = 0;
+	b->has_xkb = 0;
+	b->xkb_event_base = 0;
 	return;
 #else
 	const xcb_query_extension_reply_t *ext;
@@ -206,17 +207,17 @@  x11_compositor_setup_xkb(struct x11_compositor *c)
 	xcb_xkb_get_state_reply_t *state_reply;
 	uint32_t values[1] = { XCB_EVENT_MASK_PROPERTY_CHANGE };
 
-	c->has_xkb = 0;
-	c->xkb_event_base = 0;
+	b->has_xkb = 0;
+	b->xkb_event_base = 0;
 
-	ext = xcb_get_extension_data(c->conn, &xcb_xkb_id);
+	ext = xcb_get_extension_data(b->conn, &xcb_xkb_id);
 	if (!ext) {
 		weston_log("XKB extension not available on host X11 server\n");
 		return;
 	}
-	c->xkb_event_base = ext->first_event;
+	b->xkb_event_base = ext->first_event;
 
-	select = xcb_xkb_select_events_checked(c->conn,
+	select = xcb_xkb_select_events_checked(b->conn,
 					       XCB_XKB_ID_USE_CORE_KBD,
 					       XCB_XKB_EVENT_TYPE_STATE_NOTIFY,
 					       0,
@@ -224,17 +225,17 @@  x11_compositor_setup_xkb(struct x11_compositor *c)
 					       0,
 					       0,
 					       NULL);
-	error = xcb_request_check(c->conn, select);
+	error = xcb_request_check(b->conn, select);
 	if (error) {
 		weston_log("error: failed to select for XKB state events\n");
 		free(error);
 		return;
 	}
 
-	use_ext = xcb_xkb_use_extension(c->conn,
+	use_ext = xcb_xkb_use_extension(b->conn,
 					XCB_XKB_MAJOR_VERSION,
 					XCB_XKB_MINOR_VERSION);
-	use_ext_reply = xcb_xkb_use_extension_reply(c->conn, use_ext, NULL);
+	use_ext_reply = xcb_xkb_use_extension_reply(b->conn, use_ext, NULL);
 	if (!use_ext_reply) {
 		weston_log("couldn't start using XKB extension\n");
 		return;
@@ -250,14 +251,14 @@  x11_compositor_setup_xkb(struct x11_compositor *c)
 	}
 	free(use_ext_reply);
 
-	pcf = xcb_xkb_per_client_flags(c->conn,
+	pcf = xcb_xkb_per_client_flags(b->conn,
 				       XCB_XKB_ID_USE_CORE_KBD,
 				       XCB_XKB_PER_CLIENT_FLAG_DETECTABLE_AUTO_REPEAT,
 				       XCB_XKB_PER_CLIENT_FLAG_DETECTABLE_AUTO_REPEAT,
 				       0,
 				       0,
 				       0);
-	pcf_reply = xcb_xkb_per_client_flags_reply(c->conn, pcf, NULL);
+	pcf_reply = xcb_xkb_per_client_flags_reply(b->conn, pcf, NULL);
 	if (!pcf_reply ||
 	    !(pcf_reply->value & XCB_XKB_PER_CLIENT_FLAG_DETECTABLE_AUTO_REPEAT)) {
 		weston_log("failed to set XKB per-client flags, not using "
@@ -267,72 +268,72 @@  x11_compositor_setup_xkb(struct x11_compositor *c)
 	}
 	free(pcf_reply);
 
-	state = xcb_xkb_get_state(c->conn, XCB_XKB_ID_USE_CORE_KBD);
-	state_reply = xcb_xkb_get_state_reply(c->conn, state, NULL);
+	state = xcb_xkb_get_state(b->conn, XCB_XKB_ID_USE_CORE_KBD);
+	state_reply = xcb_xkb_get_state_reply(b->conn, state, NULL);
 	if (!state_reply) {
 		weston_log("failed to get initial XKB state\n");
 		return;
 	}
 
-	xkb_state_update_mask(c->core_seat.keyboard->xkb_state.state,
-			      get_xkb_mod_mask(c, state_reply->baseMods),
-			      get_xkb_mod_mask(c, state_reply->latchedMods),
-			      get_xkb_mod_mask(c, state_reply->lockedMods),
+	xkb_state_update_mask(b->core_seat.keyboard->xkb_state.state,
+			      get_xkb_mod_mask(b, state_reply->baseMods),
+			      get_xkb_mod_mask(b, state_reply->latchedMods),
+			      get_xkb_mod_mask(b, state_reply->lockedMods),
 			      0,
 			      0,
 			      state_reply->group);
 
 	free(state_reply);
 
-	xcb_change_window_attributes(c->conn, c->screen->root,
+	xcb_change_window_attributes(b->conn, b->screen->root,
 				     XCB_CW_EVENT_MASK, values);
 
-	c->has_xkb = 1;
+	b->has_xkb = 1;
 #endif
 }
 
 #ifdef HAVE_XCB_XKB
 static void
-update_xkb_keymap(struct x11_compositor *c)
+update_xkb_keymap(struct x11_backend *b)
 {
 	struct xkb_keymap *keymap;
 
-	keymap = x11_compositor_get_keymap(c);
+	keymap = x11_backend_get_keymap(b);
 	if (!keymap) {
 		weston_log("failed to get XKB keymap\n");
 		return;
 	}
-	weston_seat_update_keymap(&c->core_seat, keymap);
+	weston_seat_update_keymap(&b->core_seat, keymap);
 	xkb_keymap_unref(keymap);
 }
 #endif
 
 static int
-x11_input_create(struct x11_compositor *c, int no_input)
+x11_input_create(struct x11_backend *b, int no_input)
 {
 	struct xkb_keymap *keymap;
 
-	weston_seat_init(&c->core_seat, &c->base, "default");
+	weston_seat_init(&b->core_seat, b->compositor, "default");
 
 	if (no_input)
 		return 0;
 
-	weston_seat_init_pointer(&c->core_seat);
+	weston_seat_init_pointer(&b->core_seat);
 
-	keymap = x11_compositor_get_keymap(c);
-	if (weston_seat_init_keyboard(&c->core_seat, keymap) < 0)
+	keymap = x11_backend_get_keymap(b);
+	if (weston_seat_init_keyboard(&b->core_seat, keymap) < 0)
 		return -1;
 	xkb_keymap_unref(keymap);
 
-	x11_compositor_setup_xkb(c);
+	x11_backend_setup_xkb(b);
 
 	return 0;
 }
 
 static void
-x11_input_destroy(struct x11_compositor *compositor)
+x11_input_destroy(struct x11_backend *b)
 {
-	weston_seat_release(&compositor->core_seat);
+	weston_seat_release(&b->core_seat);
 }
 
 static void
@@ -365,7 +366,7 @@  set_clip_for_output(struct weston_output *output_base, pixman_region32_t *region
 {
 	struct x11_output *output = (struct x11_output *)output_base;
 	struct weston_compositor *ec = output->base.compositor;
-	struct x11_compositor *c = (struct x11_compositor *)ec;
+	struct x11_backend *b = (struct x11_backend *)ec->backend;
 	pixman_region32_t transformed_region;
 	pixman_box32_t *rects;
 	xcb_rectangle_t *output_rects;
@@ -399,11 +400,11 @@  set_clip_for_output(struct weston_output *output_base, pixman_region32_t *region
 
 	pixman_region32_fini(&transformed_region);
 
-	cookie = xcb_set_clip_rectangles_checked(c->conn, XCB_CLIP_ORDERING_UNSORTED,
+	cookie = xcb_set_clip_rectangles_checked(b->conn, XCB_CLIP_ORDERING_UNSORTED,
 					output->gc,
 					0, 0, nrects,
 					output_rects);
-	err = xcb_request_check(c->conn, cookie);
+	err = xcb_request_check(b->conn, cookie);
 	if (err != NULL) {
 		weston_log("Failed to set clip rects, err: %d\n", err->error_code);
 		free(err);
@@ -418,7 +419,7 @@  x11_output_repaint_shm(struct weston_output *output_base,
 {
 	struct x11_output *output = (struct x11_output *)output_base;
 	struct weston_compositor *ec = output->base.compositor;
-	struct x11_compositor *c = (struct x11_compositor *)ec;
+	struct x11_backend *b = (struct x11_backend *)ec->backend;
 	xcb_void_cookie_t cookie;
 	xcb_generic_error_t *err;
 
@@ -428,7 +429,7 @@  x11_output_repaint_shm(struct weston_output *output_base,
 	pixman_region32_subtract(&ec->primary_plane.damage,
 				 &ec->primary_plane.damage, damage);
 	set_clip_for_output(output_base, damage);
-	cookie = xcb_shm_put_image_checked(c->conn, output->window, output->gc,
+	cookie = xcb_shm_put_image_checked(b->conn, output->window, output->gc,
 					pixman_image_get_width(output->hw_surface),
 					pixman_image_get_height(output->hw_surface),
 					0, 0,
@@ -436,7 +437,7 @@  x11_output_repaint_shm(struct weston_output *output_base,
 					pixman_image_get_height(output->hw_surface),
 					0, 0, output->depth, XCB_IMAGE_FORMAT_Z_PIXMAP,
 					0, output->segment, 0);
-	err = xcb_request_check(c->conn, cookie);
+	err = xcb_request_check(b->conn, cookie);
 	if (err != NULL) {
 		weston_log("Failed to put shm image, err: %d\n", err->error_code);
 		free(err);
@@ -457,16 +458,16 @@  finish_frame_handler(void *data)
 }
 
 static void
-x11_output_deinit_shm(struct x11_compositor *c, struct x11_output *output)
+x11_output_deinit_shm(struct x11_backend *b, struct x11_output *output)
 {
 	xcb_void_cookie_t cookie;
 	xcb_generic_error_t *err;
-	xcb_free_gc(c->conn, output->gc);
+	xcb_free_gc(b->conn, output->gc);
 
 	pixman_image_unref(output->hw_surface);
 	output->hw_surface = NULL;
-	cookie = xcb_shm_detach_checked(c->conn, output->segment);
-	err = xcb_request_check(c->conn, cookie);
+	cookie = xcb_shm_detach_checked(b->conn, output->segment);
+	err = xcb_request_check(b->conn, cookie);
 	if (err) {
 		weston_log("xcb_shm_detach failed, error %d\n", err->error_code);
 		free(err);
@@ -478,18 +479,18 @@  static void
 x11_output_destroy(struct weston_output *output_base)
 {
 	struct x11_output *output = (struct x11_output *)output_base;
-	struct x11_compositor *compositor =
-		(struct x11_compositor *)output->base.compositor;
+	struct x11_backend *backend =
+		(struct x11_backend *)output->base.compositor->backend;
 
 	wl_event_source_remove(output->finish_frame_timer);
 
-	if (compositor->use_pixman) {
+	if (backend->use_pixman) {
 		pixman_renderer_output_destroy(output_base);
-		x11_output_deinit_shm(compositor, output);
+		x11_output_deinit_shm(backend, output);
 	} else
 		gl_renderer->output_destroy(output_base);
 
-	xcb_destroy_window(compositor->conn, output->window);
+	xcb_destroy_window(backend->conn, output->window);
 
 	weston_output_destroy(&output->base);
 
@@ -497,16 +498,16 @@  x11_output_destroy(struct weston_output *output_base)
 }
 
 static void
-x11_output_set_wm_protocols(struct x11_compositor *c,
+x11_output_set_wm_protocols(struct x11_backend *b,
 			    struct x11_output *output)
 {
 	xcb_atom_t list[1];
 
-	list[0] = c->atom.wm_delete_window;
-	xcb_change_property (c->conn, 
+	list[0] = b->atom.wm_delete_window;
+	xcb_change_property (b->conn,
 			     XCB_PROP_MODE_REPLACE,
 			     output->window,
-			     c->atom.wm_protocols,
+			     b->atom.wm_protocols,
 			     XCB_ATOM_ATOM,
 			     32,
 			     ARRAY_LENGTH(list),
@@ -529,7 +530,7 @@  struct wm_normal_hints {
 #define WM_NORMAL_HINTS_MAX_SIZE	32
 
 static void
-x11_output_set_icon(struct x11_compositor *c,
+x11_output_set_icon(struct x11_backend *b,
 		    struct x11_output *output, const char *filename)
 {
 	uint32_t *icon;
@@ -550,15 +551,15 @@  x11_output_set_icon(struct x11_compositor *c,
 	icon[0] = width;
 	icon[1] = height;
 	memcpy(icon + 2, pixman_image_get_data(image), width * height * 4);
-	xcb_change_property(c->conn, XCB_PROP_MODE_REPLACE, output->window,
-			    c->atom.net_wm_icon, c->atom.cardinal, 32,
+	xcb_change_property(b->conn, XCB_PROP_MODE_REPLACE, output->window,
+			    b->atom.net_wm_icon, b->atom.cardinal, 32,
 			    width * height + 2, icon);
 	free(icon);
 	pixman_image_unref(image);
 }
 
 static void
-x11_output_wait_for_map(struct x11_compositor *c, struct x11_output *output)
+x11_output_wait_for_map(struct x11_backend *b, struct x11_output *output)
 {
 	xcb_map_notify_event_t *map_notify;
 	xcb_configure_notify_event_t *configure_notify;
@@ -579,10 +580,10 @@  x11_output_wait_for_map(struct x11_compositor *c, struct x11_output *output)
 	 * configure_notify before map_notify, we just wait for the
 	 * first one and hope that's our size. */
 
-	xcb_flush(c->conn);
+	xcb_flush(b->conn);
 
 	while (!mapped || !configured) {
-		event = xcb_wait_for_event(c->conn);
+		event = xcb_wait_for_event(b->conn);
 		response_type = event->response_type & ~0x80;
 
 		switch (response_type) {
@@ -647,7 +648,7 @@  get_depth_of_visual(xcb_screen_t *screen,
 }
 
 static int
-x11_output_init_shm(struct x11_compositor *c, struct x11_output *output,
+x11_output_init_shm(struct x11_backend *b, struct x11_output *output,
 	int width, int height)
 {
 	xcb_screen_iterator_t iter;
@@ -660,7 +661,7 @@  x11_output_init_shm(struct x11_compositor *c, struct x11_output *output,
 	pixman_format_code_t pixman_format;
 
 	/* Check if SHM is available */
-	ext = xcb_get_extension_data(c->conn, &xcb_shm_id);
+	ext = xcb_get_extension_data(b->conn, &xcb_shm_id);
 	if (ext == NULL || !ext->present) {
 		/* SHM is missing */
 		weston_log("SHM extension is not available\n");
@@ -668,7 +669,7 @@  x11_output_init_shm(struct x11_compositor *c, struct x11_output *output,
 		return -1;
 	}
 
-	iter = xcb_setup_roots_iterator(xcb_get_setup(c->conn));
+	iter = xcb_setup_roots_iterator(xcb_get_setup(b->conn));
 	visual_type = find_visual_by_id(iter.data, iter.data->root_visual);
 	if (!visual_type) {
 		weston_log("Failed to lookup visual for root window\n");
@@ -683,7 +684,7 @@  x11_output_init_shm(struct x11_compositor *c, struct x11_output *output,
 	output->depth = get_depth_of_visual(iter.data, iter.data->root_visual);
 	weston_log("Visual depth is %d\n", output->depth);
 
-	for (fmt = xcb_setup_pixmap_formats_iterator(xcb_get_setup(c->conn));
+	for (fmt = xcb_setup_pixmap_formats_iterator(xcb_get_setup(b->conn));
 	     fmt.rem;
 	     xcb_format_next(&fmt)) {
 		if (fmt.data->depth == output->depth) {
@@ -724,9 +725,9 @@  x11_output_init_shm(struct x11_compositor *c, struct x11_output *output,
 		weston_log("x11shm: failed to attach SHM segment\n");
 		return -1;
 	}
-	output->segment = xcb_generate_id(c->conn);
-	cookie = xcb_shm_attach_checked(c->conn, output->segment, output->shm_id, 1);
-	err = xcb_request_check(c->conn, cookie);
+	output->segment = xcb_generate_id(b->conn);
+	cookie = xcb_shm_attach_checked(b->conn, output->segment, output->shm_id, 1);
+	err = xcb_request_check(b->conn, cookie);
 	if (err) {
 		weston_log("x11shm: xcb_shm_attach error %d\n", err->error_code);
 		free(err);
@@ -739,14 +740,14 @@  x11_output_init_shm(struct x11_compositor *c, struct x11_output *output,
 	output->hw_surface = pixman_image_create_bits(pixman_format, width, height, output->buf,
 		width * (bitsperpixel / 8));
 
-	output->gc = xcb_generate_id(c->conn);
-	xcb_create_gc(c->conn, output->gc, output->window, 0, NULL);
+	output->gc = xcb_generate_id(b->conn);
+	xcb_create_gc(b->conn, output->gc, output->window, 0, NULL);
 
 	return 0;
 }
 
 static struct x11_output *
-x11_compositor_create_output(struct x11_compositor *c, int x, int y,
+x11_backend_create_output(struct x11_backend *b, int x, int y,
 			     int width, int height, int fullscreen,
 			     int no_input, char *configured_name,
 			     uint32_t transform, int32_t scale)
@@ -802,10 +803,10 @@  x11_compositor_create_output(struct x11_compositor *c, int x, int y,
 	wl_list_init(&output->base.mode_list);
 	wl_list_insert(&output->base.mode_list, &output->mode.link);
 
-	values[1] = c->null_cursor;
-	output->window = xcb_generate_id(c->conn);
-	iter = xcb_setup_roots_iterator(xcb_get_setup(c->conn));
-	xcb_create_window(c->conn,
+	values[1] = b->null_cursor;
+	output->window = xcb_generate_id(b->conn);
+	iter = xcb_setup_roots_iterator(xcb_get_setup(b->conn));
+	xcb_create_window(b->conn,
 			  XCB_COPY_FROM_PARENT,
 			  output->window,
 			  iter.data->root,
@@ -817,10 +818,10 @@  x11_compositor_create_output(struct x11_compositor *c, int x, int y,
 			  mask, values);
 
 	if (fullscreen) {
-		atom_list[0] = c->atom.net_wm_state_fullscreen;
-		xcb_change_property(c->conn, XCB_PROP_MODE_REPLACE,
+		atom_list[0] = b->atom.net_wm_state_fullscreen;
+		xcb_change_property(b->conn, XCB_PROP_MODE_REPLACE,
 				    output->window,
-				    c->atom.net_wm_state,
+				    b->atom.net_wm_state,
 				    XCB_ATOM_ATOM, 32,
 				    ARRAY_LENGTH(atom_list), atom_list);
 	} else {
@@ -832,32 +833,32 @@  x11_compositor_create_output(struct x11_compositor *c, int x, int y,
 		normal_hints.min_height = output_height;
 		normal_hints.max_width = output_width;
 		normal_hints.max_height = output_height;
-		xcb_change_property(c->conn, XCB_PROP_MODE_REPLACE, output->window,
-				    c->atom.wm_normal_hints,
-				    c->atom.wm_size_hints, 32,
+		xcb_change_property(b->conn, XCB_PROP_MODE_REPLACE, output->window,
+				    b->atom.wm_normal_hints,
+				    b->atom.wm_size_hints, 32,
 				    sizeof normal_hints / 4,
 				    (uint8_t *) &normal_hints);
 	}
 
 	/* Set window name.  Don't bother with non-EWMH WMs. */
-	xcb_change_property(c->conn, XCB_PROP_MODE_REPLACE, output->window,
-			    c->atom.net_wm_name, c->atom.utf8_string, 8,
+	xcb_change_property(b->conn, XCB_PROP_MODE_REPLACE, output->window,
+			    b->atom.net_wm_name, b->atom.utf8_string, 8,
 			    strlen(title), title);
-	xcb_change_property(c->conn, XCB_PROP_MODE_REPLACE, output->window,
-			    c->atom.wm_class, c->atom.string, 8,
+	xcb_change_property(b->conn, XCB_PROP_MODE_REPLACE, output->window,
+			    b->atom.wm_class, b->atom.string, 8,
 			    sizeof class, class);
 
-	x11_output_set_icon(c, output, DATADIR "/weston/wayland.png");
+	x11_output_set_icon(b, output, DATADIR "/weston/wayland.png");
 
-	x11_output_set_wm_protocols(c, output);
+	x11_output_set_wm_protocols(b, output);
 
-	xcb_map_window(c->conn, output->window);
+	xcb_map_window(b->conn, output->window);
 
 	if (fullscreen)
-		x11_output_wait_for_map(c, output);
+		x11_output_wait_for_map(b, output);
 
 	output->base.start_repaint_loop = x11_output_start_repaint_loop;
-	if (c->use_pixman)
+	if (b->use_pixman)
 		output->base.repaint = x11_output_repaint_shm;
 	else
 		output->base.repaint = x11_output_repaint_gl;
@@ -873,20 +874,20 @@  x11_compositor_create_output(struct x11_compositor *c, int x, int y,
 	if (configured_name)
 		output->base.name = strdup(configured_name);
 
-	width_mm = width * c->screen->width_in_millimeters /
-		c->screen->width_in_pixels;
-	height_mm = height * c->screen->height_in_millimeters /
-		c->screen->height_in_pixels;
-	weston_output_init(&output->base, &c->base,
+	width_mm = width * b->screen->width_in_millimeters /
+		b->screen->width_in_pixels;
+	height_mm = height * b->screen->height_in_millimeters /
+		b->screen->height_in_pixels;
+	weston_output_init(&output->base, b->compositor,
 			   x, y, width_mm, height_mm, transform, scale);
 
-	if (c->use_pixman) {
-		if (x11_output_init_shm(c, output,
+	if (b->use_pixman) {
+		if (x11_output_init_shm(b, output,
 					output->mode.width,
 					output->mode.height) < 0)
 			return NULL;
 		if (pixman_renderer_output_create(&output->base) < 0) {
-			x11_output_deinit_shm(c, output);
+			x11_output_deinit_shm(b, output);
 			return NULL;
 		}
 	} else {
@@ -898,11 +899,11 @@  x11_compositor_create_output(struct x11_compositor *c, int x, int y,
 			return NULL;
 	}
 
-	loop = wl_display_get_event_loop(c->base.wl_display);
+	loop = wl_display_get_event_loop(b->compositor->wl_display);
 	output->finish_frame_timer =
 		wl_event_loop_add_timer(loop, finish_frame_handler, output);
 
-	wl_list_insert(c->base.output_list.prev, &output->base.link);
+	wl_list_insert(b->compositor->output_list.prev, &output->base.link);
 
 	weston_log("x11 output %dx%d, window id %d\n",
 		   width, height, output->window);
@@ -911,11 +912,11 @@  x11_compositor_create_output(struct x11_compositor *c, int x, int y,
 }
 
 static struct x11_output *
-x11_compositor_find_output(struct x11_compositor *c, xcb_window_t window)
+x11_backend_find_output(struct x11_backend *b, xcb_window_t window)
 {
 	struct x11_output *output;
 
-	wl_list_for_each(output, &c->base.output_list, base.link) {
+	wl_list_for_each(output, &b->compositor->output_list, base.link) {
 		if (output->window == window)
 			return output;
 	}
@@ -924,33 +925,33 @@  x11_compositor_find_output(struct x11_compositor *c, xcb_window_t window)
 }
 
 static void
-x11_compositor_delete_window(struct x11_compositor *c, xcb_window_t window)
+x11_backend_delete_window(struct x11_backend *b, xcb_window_t window)
 {
 	struct x11_output *output;
 
-	output = x11_compositor_find_output(c, window);
+	output = x11_backend_find_output(b, window);
 	x11_output_destroy(&output->base);
 
-	xcb_flush(c->conn);
+	xcb_flush(b->conn);
 
-	if (wl_list_empty(&c->base.output_list))
-		wl_display_terminate(c->base.wl_display);
+	if (wl_list_empty(&b->compositor->output_list))
+		wl_display_terminate(b->compositor->wl_display);
 }
 
 #ifdef HAVE_XCB_XKB
 static void
-update_xkb_state(struct x11_compositor *c, xcb_xkb_state_notify_event_t *state)
+update_xkb_state(struct x11_backend *b, xcb_xkb_state_notify_event_t *state)
 {
-	xkb_state_update_mask(c->core_seat.keyboard->xkb_state.state,
-			      get_xkb_mod_mask(c, state->baseMods),
-			      get_xkb_mod_mask(c, state->latchedMods),
-			      get_xkb_mod_mask(c, state->lockedMods),
+	xkb_state_update_mask(b->core_seat.keyboard->xkb_state.state,
+			      get_xkb_mod_mask(b, state->baseMods),
+			      get_xkb_mod_mask(b, state->latchedMods),
+			      get_xkb_mod_mask(b, state->lockedMods),
 			      0,
 			      0,
 			      state->group);
 
-	notify_modifiers(&c->core_seat,
-			 wl_display_next_serial(c->base.wl_display));
+	notify_modifiers(&b->core_seat,
+			 wl_display_next_serial(b->compositor->wl_display));
 }
 #endif
 
@@ -966,35 +967,35 @@  update_xkb_state(struct x11_compositor *c, xcb_xkb_state_notify_event_t *state)
  * modifiers.
  */
 static void
-update_xkb_state_from_core(struct x11_compositor *c, uint16_t x11_mask)
+update_xkb_state_from_core(struct x11_backend *b, uint16_t x11_mask)
 {
-	uint32_t mask = get_xkb_mod_mask(c, x11_mask);
-	struct weston_keyboard *keyboard = c->core_seat.keyboard;
+	uint32_t mask = get_xkb_mod_mask(b, x11_mask);
+	struct weston_keyboard *keyboard = b->core_seat.keyboard;
 
-	xkb_state_update_mask(c->core_seat.keyboard->xkb_state.state,
+	xkb_state_update_mask(b->core_seat.keyboard->xkb_state.state,
 			      keyboard->modifiers.mods_depressed & mask,
 			      keyboard->modifiers.mods_latched & mask,
 			      keyboard->modifiers.mods_locked & mask,
 			      0,
 			      0,
 			      (x11_mask >> 13) & 3);
-	notify_modifiers(&c->core_seat,
-			 wl_display_next_serial(c->base.wl_display));
+	notify_modifiers(&b->core_seat,
+			 wl_display_next_serial(b->compositor->wl_display));
 }
 
 static void
-x11_compositor_deliver_button_event(struct x11_compositor *c,
-				    xcb_generic_event_t *event, int state)
+x11_backend_deliver_button_event(struct x11_backend *b,
+				 xcb_generic_event_t *event, int state)
 {
 	xcb_button_press_event_t *button_event =
 		(xcb_button_press_event_t *) event;
 	uint32_t button;
 	struct x11_output *output;
 
-	output = x11_compositor_find_output(c, button_event->event);
+	output = x11_backend_find_output(b, button_event->event);
 
 	if (state)
-		xcb_grab_pointer(c->conn, 0, output->window,
+		xcb_grab_pointer(b->conn, 0, output->window,
 				 XCB_EVENT_MASK_BUTTON_PRESS |
 				 XCB_EVENT_MASK_BUTTON_RELEASE |
 				 XCB_EVENT_MASK_POINTER_MOTION |
@@ -1005,10 +1006,10 @@  x11_compositor_deliver_button_event(struct x11_compositor *c,
 				 output->window, XCB_CURSOR_NONE,
 				 button_event->time);
 	else
-		xcb_ungrab_pointer(c->conn, button_event->time);
+		xcb_ungrab_pointer(b->conn, button_event->time);
 
-	if (!c->has_xkb)
-		update_xkb_state_from_core(c, button_event->state);
+	if (!b->has_xkb)
+		update_xkb_state_from_core(b, button_event->state);
 
 	switch (button_event->detail) {
 	default:
@@ -1024,67 +1025,67 @@  x11_compositor_deliver_button_event(struct x11_compositor *c,
 		/* Axis are measured in pixels, but the xcb events are discrete
 		 * steps. Therefore move the axis by some pixels every step. */
 		if (state)
-			notify_axis(&c->core_seat,
+			notify_axis(&b->core_seat,
 				    weston_compositor_get_time(),
 				    WL_POINTER_AXIS_VERTICAL_SCROLL,
 				    -DEFAULT_AXIS_STEP_DISTANCE);
 		return;
 	case 5:
 		if (state)
-			notify_axis(&c->core_seat,
+			notify_axis(&b->core_seat,
 				    weston_compositor_get_time(),
 				    WL_POINTER_AXIS_VERTICAL_SCROLL,
 				    DEFAULT_AXIS_STEP_DISTANCE);
 		return;
 	case 6:
 		if (state)
-			notify_axis(&c->core_seat,
+			notify_axis(&b->core_seat,
 				    weston_compositor_get_time(),
 				    WL_POINTER_AXIS_HORIZONTAL_SCROLL,
 				    -DEFAULT_AXIS_STEP_DISTANCE);
 		return;
 	case 7:
 		if (state)
-			notify_axis(&c->core_seat,
+			notify_axis(&b->core_seat,
 				    weston_compositor_get_time(),
 				    WL_POINTER_AXIS_HORIZONTAL_SCROLL,
 				    DEFAULT_AXIS_STEP_DISTANCE);
 		return;
 	}
 
-	notify_button(&c->core_seat,
+	notify_button(&b->core_seat,
 		      weston_compositor_get_time(), button,
 		      state ? WL_POINTER_BUTTON_STATE_PRESSED :
 			      WL_POINTER_BUTTON_STATE_RELEASED);
 }
 
 static void
-x11_compositor_deliver_motion_event(struct x11_compositor *c,
-					xcb_generic_event_t *event)
+x11_backend_deliver_motion_event(struct x11_backend *b,
+				 xcb_generic_event_t *event)
 {
 	struct x11_output *output;
 	wl_fixed_t x, y;
 	xcb_motion_notify_event_t *motion_notify =
 			(xcb_motion_notify_event_t *) event;
 
-	if (!c->has_xkb)
-		update_xkb_state_from_core(c, motion_notify->state);
-	output = x11_compositor_find_output(c, motion_notify->event);
+	if (!b->has_xkb)
+		update_xkb_state_from_core(b, motion_notify->state);
+	output = x11_backend_find_output(b, motion_notify->event);
 	weston_output_transform_coordinate(&output->base,
 					   wl_fixed_from_int(motion_notify->event_x),
 					   wl_fixed_from_int(motion_notify->event_y),
 					   &x, &y);
 
-	notify_motion(&c->core_seat, weston_compositor_get_time(),
-		      x - c->prev_x, y - c->prev_y);
+	notify_motion(&b->core_seat, weston_compositor_get_time(),
+		      x - b->prev_x, y - b->prev_y);
 
-	c->prev_x = x;
-	c->prev_y = y;
+	b->prev_x = x;
+	b->prev_y = y;
 }
 
 static void
-x11_compositor_deliver_enter_event(struct x11_compositor *c,
-					xcb_generic_event_t *event)
+x11_backend_deliver_enter_event(struct x11_backend *b,
+				xcb_generic_event_t *event)
 {
 	struct x11_output *output;
 	wl_fixed_t x, y;
@@ -1093,30 +1094,30 @@  x11_compositor_deliver_enter_event(struct x11_compositor *c,
 			(xcb_enter_notify_event_t *) event;
 	if (enter_notify->state >= Button1Mask)
 		return;
-	if (!c->has_xkb)
-		update_xkb_state_from_core(c, enter_notify->state);
-	output = x11_compositor_find_output(c, enter_notify->event);
+	if (!b->has_xkb)
+		update_xkb_state_from_core(b, enter_notify->state);
+	output = x11_backend_find_output(b, enter_notify->event);
 	weston_output_transform_coordinate(&output->base,
 					   wl_fixed_from_int(enter_notify->event_x),
 					   wl_fixed_from_int(enter_notify->event_y), &x, &y);
 
-	notify_pointer_focus(&c->core_seat, &output->base, x, y);
+	notify_pointer_focus(&b->core_seat, &output->base, x, y);
 
-	c->prev_x = x;
-	c->prev_y = y;
+	b->prev_x = x;
+	b->prev_y = y;
 }
 
 static int
-x11_compositor_next_event(struct x11_compositor *c,
-			  xcb_generic_event_t **event, uint32_t mask)
+x11_backend_next_event(struct x11_backend *b,
+		       xcb_generic_event_t **event, uint32_t mask)
 {
 	if (mask & WL_EVENT_READABLE) {
-		*event = xcb_poll_for_event(c->conn);
+		*event = xcb_poll_for_event(b->conn);
 	} else {
 #ifdef HAVE_XCB_POLL_FOR_QUEUED_EVENT
-		*event = xcb_poll_for_queued_event(c->conn);
+		*event = xcb_poll_for_queued_event(b->conn);
 #else
-		*event = xcb_poll_for_event(c->conn);
+		*event = xcb_poll_for_event(b->conn);
 #endif
 	}
 
@@ -1124,9 +1125,9 @@  x11_compositor_next_event(struct x11_compositor *c,
 }
 
 static int
-x11_compositor_handle_event(int fd, uint32_t mask, void *data)
+x11_backend_handle_event(int fd, uint32_t mask, void *data)
 {
-	struct x11_compositor *c = data;
+	struct x11_backend *b = data;
 	struct x11_output *output;
 	xcb_generic_event_t *event, *prev;
 	xcb_client_message_event_t *client_message;
@@ -1144,7 +1145,7 @@  x11_compositor_handle_event(int fd, uint32_t mask, void *data)
 
 	prev = NULL;
 	count = 0;
-	while (x11_compositor_next_event(c, &event, mask)) {
+	while (x11_backend_next_event(b, &event, mask)) {
 		response_type = event->response_type & ~0x80;
 
 		switch (prev ? prev->response_type & ~0x80 : 0x80) {
@@ -1166,8 +1167,8 @@  x11_compositor_handle_event(int fd, uint32_t mask, void *data)
 				/* Deliver the held key release now
 				 * and fall through and handle the new
 				 * event below. */
-				update_xkb_state_from_core(c, key_release->state);
-				notify_key(&c->core_seat,
+				update_xkb_state_from_core(b, key_release->state);
+				notify_key(&b->core_seat,
 					   weston_compositor_get_time(),
 					   key_release->detail - 8,
 					   WL_KEYBOARD_KEY_STATE_RELEASED,
@@ -1180,12 +1181,12 @@  x11_compositor_handle_event(int fd, uint32_t mask, void *data)
 		case XCB_FOCUS_IN:
 			assert(response_type == XCB_KEYMAP_NOTIFY);
 			keymap_notify = (xcb_keymap_notify_event_t *) event;
-			c->keys.size = 0;
+			b->keys.size = 0;
 			for (i = 0; i < ARRAY_LENGTH(keymap_notify->keys) * 8; i++) {
 				set = keymap_notify->keys[i >> 3] &
 					(1 << (i & 7));
 				if (set) {
-					k = wl_array_add(&c->keys, sizeof *k);
+					k = wl_array_add(&b->keys, sizeof *k);
 					*k = i;
 				}
 			}
@@ -1194,7 +1195,7 @@  x11_compositor_handle_event(int fd, uint32_t mask, void *data)
 			 * event, rather than with the focus event.  I'm not
 			 * sure of the exact semantics around it and whether
 			 * we can ensure that we get both? */
-			notify_keyboard_focus_in(&c->core_seat, &c->keys,
+			notify_keyboard_focus_in(&b->core_seat, &b->keys,
 						 STATE_UPDATE_AUTOMATIC);
 
 			free(prev);
@@ -1209,65 +1210,65 @@  x11_compositor_handle_event(int fd, uint32_t mask, void *data)
 		switch (response_type) {
 		case XCB_KEY_PRESS:
 			key_press = (xcb_key_press_event_t *) event;
-			if (!c->has_xkb)
-				update_xkb_state_from_core(c, key_press->state);
-			notify_key(&c->core_seat,
+			if (!b->has_xkb)
+				update_xkb_state_from_core(b, key_press->state);
+			notify_key(&b->core_seat,
 				   weston_compositor_get_time(),
 				   key_press->detail - 8,
 				   WL_KEYBOARD_KEY_STATE_PRESSED,
-				   c->has_xkb ? STATE_UPDATE_NONE :
+				   b->has_xkb ? STATE_UPDATE_NONE :
 						STATE_UPDATE_AUTOMATIC);
 			break;
 		case XCB_KEY_RELEASE:
 			/* If we don't have XKB, we need to use the lame
 			 * autorepeat detection above. */
-			if (!c->has_xkb) {
+			if (!b->has_xkb) {
 				prev = event;
 				break;
 			}
 			key_release = (xcb_key_press_event_t *) event;
-			notify_key(&c->core_seat,
+			notify_key(&b->core_seat,
 				   weston_compositor_get_time(),
 				   key_release->detail - 8,
 				   WL_KEYBOARD_KEY_STATE_RELEASED,
 				   STATE_UPDATE_NONE);
 			break;
 		case XCB_BUTTON_PRESS:
-			x11_compositor_deliver_button_event(c, event, 1);
+			x11_backend_deliver_button_event(b, event, 1);
 			break;
 		case XCB_BUTTON_RELEASE:
-			x11_compositor_deliver_button_event(c, event, 0);
+			x11_backend_deliver_button_event(b, event, 0);
 			break;
 		case XCB_MOTION_NOTIFY:
-			x11_compositor_deliver_motion_event(c, event);
+			x11_backend_deliver_motion_event(b, event);
 			break;
 
 		case XCB_EXPOSE:
 			expose = (xcb_expose_event_t *) event;
-			output = x11_compositor_find_output(c, expose->window);
+			output = x11_backend_find_output(b, expose->window);
 			weston_output_damage(&output->base);
 			weston_output_schedule_repaint(&output->base);
 			break;
 
 		case XCB_ENTER_NOTIFY:
-			x11_compositor_deliver_enter_event(c, event);
+			x11_backend_deliver_enter_event(b, event);
 			break;
 
 		case XCB_LEAVE_NOTIFY:
 			enter_notify = (xcb_enter_notify_event_t *) event;
 			if (enter_notify->state >= Button1Mask)
 				break;
-			if (!c->has_xkb)
-				update_xkb_state_from_core(c, enter_notify->state);
-			notify_pointer_focus(&c->core_seat, NULL, 0, 0);
+			if (!b->has_xkb)
+				update_xkb_state_from_core(b, enter_notify->state);
+			notify_pointer_focus(&b->core_seat, NULL, 0, 0);
 			break;
 
 		case XCB_CLIENT_MESSAGE:
 			client_message = (xcb_client_message_event_t *) event;
 			atom = client_message->data.data32[0];
 			window = client_message->window;
-			if (atom == c->atom.wm_delete_window)
-				x11_compositor_delete_window(c, window);
+			if (atom == b->atom.wm_delete_window)
+				x11_backend_delete_window(b, window);
 			break;
 
 		case XCB_FOCUS_IN:
@@ -1283,7 +1284,7 @@  x11_compositor_handle_event(int fd, uint32_t mask, void *data)
 			if (focus_in->mode == XCB_NOTIFY_MODE_WHILE_GRABBED ||
 			    focus_in->mode == XCB_NOTIFY_MODE_UNGRAB)
 				break;
-			notify_keyboard_focus_out(&c->core_seat);
+			notify_keyboard_focus_out(&b->core_seat);
 			break;
 
 		default:
@@ -1291,19 +1292,19 @@  x11_compositor_handle_event(int fd, uint32_t mask, void *data)
 		}
 
 #ifdef HAVE_XCB_XKB
-		if (c->has_xkb) {
-			if (response_type == c->xkb_event_base) {
+		if (b->has_xkb) {
+			if (response_type == b->xkb_event_base) {
 				xcb_xkb_state_notify_event_t *state =
 					(xcb_xkb_state_notify_event_t *) event;
 				if (state->xkbType == XCB_XKB_STATE_NOTIFY)
-					update_xkb_state(c, state);
+					update_xkb_state(b, state);
 			} else if (response_type == XCB_PROPERTY_NOTIFY) {
 				xcb_property_notify_event_t *prop_notify =
 					(xcb_property_notify_event_t *) event;
-				if (prop_notify->window == c->screen->root &&
-				    prop_notify->atom == c->atom.xkb_names &&
+				if (prop_notify->window == b->screen->root &&
+				    prop_notify->atom == b->atom.xkb_names &&
 				    prop_notify->state == XCB_PROPERTY_NEW_VALUE)
-					update_xkb_keymap(c);
+					update_xkb_keymap(b);
 			}
 		}
 #endif
@@ -1316,8 +1317,8 @@  x11_compositor_handle_event(int fd, uint32_t mask, void *data)
 	switch (prev ? prev->response_type & ~0x80 : 0x80) {
 	case XCB_KEY_RELEASE:
 		key_release = (xcb_key_press_event_t *) prev;
-		update_xkb_state_from_core(c, key_release->state);
-		notify_key(&c->core_seat,
+		update_xkb_state_from_core(b, key_release->state);
+		notify_key(&b->core_seat,
 			   weston_compositor_get_time(),
 			   key_release->detail - 8,
 			   WL_KEYBOARD_KEY_STATE_RELEASED,
@@ -1332,10 +1333,10 @@  x11_compositor_handle_event(int fd, uint32_t mask, void *data)
 	return count;
 }
 
-#define F(field) offsetof(struct x11_compositor, field)
+#define F(field) offsetof(struct x11_backend, field)
 
 static void
-x11_compositor_get_resources(struct x11_compositor *c)
+x11_backend_get_resources(struct x11_backend *b)
 {
 	static const struct { const char *name; int offset; } atoms[] = {
 		{ "WM_PROTOCOLS",	F(atom.wm_protocols) },
@@ -1364,31 +1365,31 @@  x11_compositor_get_resources(struct x11_compositor *c)
 	uint8_t data[] = { 0, 0, 0, 0 };
 
 	for (i = 0; i < ARRAY_LENGTH(atoms); i++)
-		cookies[i] = xcb_intern_atom (c->conn, 0,
+		cookies[i] = xcb_intern_atom (b->conn, 0,
 					      strlen(atoms[i].name),
 					      atoms[i].name);
 
 	for (i = 0; i < ARRAY_LENGTH(atoms); i++) {
-		reply = xcb_intern_atom_reply (c->conn, cookies[i], NULL);
-		*(xcb_atom_t *) ((char *) c + atoms[i].offset) = reply->atom;
+		reply = xcb_intern_atom_reply (b->conn, cookies[i], NULL);
+		*(xcb_atom_t *) ((char *) b + atoms[i].offset) = reply->atom;
 		free(reply);
 	}
 
-	pixmap = xcb_generate_id(c->conn);
-	gc = xcb_generate_id(c->conn);
-	xcb_create_pixmap(c->conn, 1, pixmap, c->screen->root, 1, 1);
-	xcb_create_gc(c->conn, gc, pixmap, 0, NULL);
-	xcb_put_image(c->conn, XCB_IMAGE_FORMAT_XY_PIXMAP,
+	pixmap = xcb_generate_id(b->conn);
+	gc = xcb_generate_id(b->conn);
+	xcb_create_pixmap(b->conn, 1, pixmap, b->screen->root, 1, 1);
+	xcb_create_gc(b->conn, gc, pixmap, 0, NULL);
+	xcb_put_image(b->conn, XCB_IMAGE_FORMAT_XY_PIXMAP,
 		      pixmap, gc, 1, 1, 0, 0, 0, 32, sizeof data, data);
-	c->null_cursor = xcb_generate_id(c->conn);
-	xcb_create_cursor (c->conn, c->null_cursor,
+	b->null_cursor = xcb_generate_id(b->conn);
+	xcb_create_cursor (b->conn, b->null_cursor,
 			   pixmap, pixmap, 0, 0, 0,  0, 0, 0,  1, 1);
-	xcb_free_gc(c->conn, gc);
-	xcb_free_pixmap(c->conn, pixmap);
+	xcb_free_gc(b->conn, gc);
+	xcb_free_pixmap(b->conn, pixmap);
 }
 
 static void
-x11_compositor_get_wm_info(struct x11_compositor *c)
+x11_backend_get_wm_info(struct x11_backend *c)
 {
 	xcb_get_property_cookie_t cookie;
 	xcb_get_property_reply_t *reply;
@@ -1418,19 +1419,19 @@  x11_restore(struct weston_compositor *ec)
 static void
 x11_destroy(struct weston_compositor *ec)
 {
-	struct x11_compositor *compositor = (struct x11_compositor *)ec;
+	struct x11_backend *backend = (struct x11_backend *)ec->backend;
 
-	wl_event_source_remove(compositor->xcb_source);
-	x11_input_destroy(compositor);
+	wl_event_source_remove(backend->xcb_source);
+	x11_input_destroy(backend);
 
 	weston_compositor_shutdown(ec); /* destroys outputs, too */
 
-	XCloseDisplay(compositor->dpy);
-	free(ec);
+	XCloseDisplay(backend->dpy);
+	free(backend);
 }
 
 static int
-init_gl_renderer(struct x11_compositor *c)
+init_gl_renderer(struct x11_backend *b)
 {
 	int ret;
 
@@ -1439,20 +1440,20 @@  init_gl_renderer(struct x11_compositor *c)
 	if (!gl_renderer)
 		return -1;
 
-	ret = gl_renderer->create(&c->base, (EGLNativeDisplayType) c->dpy,
+	ret = gl_renderer->create(b->compositor, (EGLNativeDisplayType) b->dpy,
 				  gl_renderer->opaque_attribs, NULL);
 
 	return ret;
 }
-static struct weston_compositor *
-x11_compositor_create(struct wl_display *display,
-		      int fullscreen,
-		      int no_input,
-		      int use_pixman,
-		      int *argc, char *argv[],
-		      struct weston_config *config)
+static struct x11_backend *
+x11_backend_create(struct weston_compositor *compositor,
+		   int fullscreen,
+		   int no_input,
+		   int use_pixman,
+		   int *argc, char *argv[],
+		   struct weston_config *config)
 {
-	struct x11_compositor *c;
+	struct x11_backend *b;
 	struct x11_output *output;
 	struct weston_config_section *section;
 	xcb_screen_iterator_t s;
@@ -1464,54 +1465,54 @@  x11_compositor_create(struct wl_display *display,
 
 	weston_log("initializing x11 backend\n");
 
-	c = zalloc(sizeof *c);
-	if (c == NULL)
+	b = zalloc(sizeof *b);
+	if (b == NULL)
 		return NULL;
 
-	if (weston_compositor_init(&c->base, display, argc, argv, config) < 0)
+	b->compositor = compositor;
+	if (weston_compositor_init(compositor, argc, argv, config) < 0)
 		goto err_free;
 
-	if (weston_compositor_set_presentation_clock_software(&c->base) < 0)
+	if (weston_compositor_set_presentation_clock_software(compositor) < 0)
 		goto err_free;
 
-	c->dpy = XOpenDisplay(NULL);
-	if (c->dpy == NULL)
+	b->dpy = XOpenDisplay(NULL);
+	if (b->dpy == NULL)
 		goto err_free;
 
-	c->conn = XGetXCBConnection(c->dpy);
-	XSetEventQueueOwner(c->dpy, XCBOwnsEventQueue);
+	b->conn = XGetXCBConnection(b->dpy);
+	XSetEventQueueOwner(b->dpy, XCBOwnsEventQueue);
 
-	if (xcb_connection_has_error(c->conn))
+	if (xcb_connection_has_error(b->conn))
 		goto err_xdisplay;
 
-	s = xcb_setup_roots_iterator(xcb_get_setup(c->conn));
-	c->screen = s.data;
-	wl_array_init(&c->keys);
+	s = xcb_setup_roots_iterator(xcb_get_setup(b->conn));
+	b->screen = s.data;
+	wl_array_init(&b->keys);
 
-	x11_compositor_get_resources(c);
-	x11_compositor_get_wm_info(c);
+	x11_backend_get_resources(b);
+	x11_backend_get_wm_info(b);
 
-	if (!c->has_net_wm_state_fullscreen && fullscreen) {
+	if (!b->has_net_wm_state_fullscreen && fullscreen) {
 		weston_log("Can not fullscreen without window manager support"
 			   "(need _NET_WM_STATE_FULLSCREEN)\n");
 		fullscreen = 0;
 	}
 
-	c->base.wl_display = display;
-	c->use_pixman = use_pixman;
-	if (c->use_pixman) {
-		if (pixman_renderer_init(&c->base) < 0)
+	b->use_pixman = use_pixman;
+	if (b->use_pixman) {
+		if (pixman_renderer_init(compositor) < 0)
 			goto err_xdisplay;
 	}
-	else if (init_gl_renderer(c) < 0) {
+	else if (init_gl_renderer(b) < 0) {
 		goto err_xdisplay;
 	}
 	weston_log("Using %s renderer\n", use_pixman ? "pixman" : "gl");
 
-	c->base.destroy = x11_destroy;
-	c->base.restore = x11_restore;
+	b->base.destroy = x11_destroy;
+	b->base.restore = x11_restore;
 
-	if (x11_input_create(c, no_input) < 0)
+	if (x11_input_create(b, no_input) < 0)
 		goto err_renderer;
 
 	width = option_width ? option_width : 1024;
@@ -1520,7 +1521,7 @@  x11_compositor_create(struct wl_display *display,
 	count = option_count ? option_count : 1;
 
 	section = NULL;
-	while (weston_config_next_section(c->base.config,
+	while (weston_config_next_section(config,
 					  &section, &section_name)) {
 		if (strcmp(section_name, "output") != 0)
 			continue;
@@ -1556,10 +1557,10 @@  x11_compositor_create(struct wl_display *display,
 				   t, name);
 		free(t);
 
-		output = x11_compositor_create_output(c, x, 0,
-						      width, height,
-						      fullscreen, no_input,
-						      name, transform, scale);
+		output = x11_backend_create_output(b, x, 0,
+						   width, height,
+						   fullscreen, no_input,
+						   name, transform, scale);
 		free(name);
 		if (output == NULL)
 			goto err_x11_input;
@@ -1572,38 +1573,40 @@  x11_compositor_create(struct wl_display *display,
 	}
 
 	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);
+		output = x11_backend_create_output(b, 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->xcb_source =
-		wl_event_loop_add_fd(c->base.input_loop,
-				     xcb_get_file_descriptor(c->conn),
+	b->xcb_source =
+		wl_event_loop_add_fd(compositor->input_loop,
+				     xcb_get_file_descriptor(b->conn),
 				     WL_EVENT_READABLE,
-				     x11_compositor_handle_event, c);
-	wl_event_source_check(c->xcb_source);
+				     x11_backend_handle_event, b);
+	wl_event_source_check(b->xcb_source);
 
-	return &c->base;
+	compositor->backend = &b->base;
+	return b;
 
 err_x11_input:
-	x11_input_destroy(c);
+	x11_input_destroy(b);
 err_renderer:
-	c->base.renderer->destroy(&c->base);
+	compositor->renderer->destroy(compositor);
 err_xdisplay:
-	XCloseDisplay(c->dpy);
+	XCloseDisplay(b->dpy);
 err_free:
-	free(c);
+	free(b);
 	return NULL;
 }
 
-WL_EXPORT struct weston_compositor *
-backend_init(struct wl_display *display, int *argc, char *argv[],
+WL_EXPORT int
+backend_init(struct weston_compositor *compositor, int *argc, char *argv[],
 	     struct weston_config *config)
 {
+	struct x11_backend *b;
 	int fullscreen = 0;
 	int no_input = 0;
 	int use_pixman = 0;
@@ -1620,9 +1623,12 @@  backend_init(struct wl_display *display, int *argc, char *argv[],
 
 	parse_options(x11_options, ARRAY_LENGTH(x11_options), argc, argv);
 
-	return x11_compositor_create(display,
-				     fullscreen,
-				     no_input,
-				     use_pixman,
-				     argc, argv, config);
+	b = x11_backend_create(compositor,
+			       fullscreen,
+			       no_input,
+			       use_pixman,
+			       argc, argv, config);
+	if (b == NULL)
+		return -1;
+	return 0;
 }
diff --git a/src/compositor.c b/src/compositor.c
index 53f6220..b5a3cb3 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -4010,7 +4010,6 @@  weston_environment_get_fd(const char *env)
 
 WL_EXPORT int
 weston_compositor_init(struct weston_compositor *ec,
-		       struct wl_display *display,
 		       int *argc, char *argv[],
 		       struct weston_config *config)
 {
@@ -4019,7 +4018,6 @@  weston_compositor_init(struct weston_compositor *ec,
 	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);
 	wl_signal_init(&ec->activate_signal);
@@ -4039,11 +4037,11 @@  weston_compositor_init(struct weston_compositor *ec,
 
 	ec->output_id_pool = 0;
 
-	if (!wl_global_create(display, &wl_compositor_interface, 3,
+	if (!wl_global_create(ec->wl_display, &wl_compositor_interface, 3,
 			      ec, compositor_bind))
 		return -1;
 
-	if (!wl_global_create(display, &wl_subcompositor_interface, 1,
+	if (!wl_global_create(ec->wl_display, &wl_subcompositor_interface, 1,
 			      ec, bind_subcompositor))
 		return -1;
 
@@ -4094,7 +4092,7 @@  weston_compositor_init(struct weston_compositor *ec,
 
 	wl_data_device_manager_init(ec->wl_display);
 
-	wl_display_init_shm(display);
+	wl_display_init_shm(ec->wl_display);
 
 	loop = wl_display_get_event_loop(ec->wl_display);
 	ec->idle_source = wl_event_loop_add_timer(loop, idle_handler, ec);
@@ -4363,7 +4361,7 @@  on_caught_signal(int s, siginfo_t *siginfo, void *context)
 
 	print_backtrace();
 
-	segv_compositor->restore(segv_compositor);
+	segv_compositor->backend->restore(segv_compositor);
 
 	raise(SIGTRAP);
 }
@@ -4700,10 +4698,9 @@  int main(int argc, char *argv[])
 	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 (*backend_init)(struct weston_compositor *c,
+			    int *argc, char *argv[],
+			    struct weston_config *config);
 	int i, fd;
 	char *backend = NULL;
 	char *shell = NULL;
@@ -4799,13 +4796,20 @@  int main(int argc, char *argv[])
 		goto out_signals;
 	}
 
-	ec = backend_init(display, &argc, argv, config);
+	ec = zalloc(sizeof *ec);
 	if (ec == NULL) {
 		weston_log("fatal: failed to create compositor\n");
 		ret = EXIT_FAILURE;
 		goto out_signals;
 	}
 
+	ec->wl_display = display;
+	if (backend_init(ec, &argc, argv, config) < 0) {
+		weston_log("fatal: failed to create compositor backend\n");
+		ret = EXIT_FAILURE;
+		goto out_signals;
+	}
+
 	catch_signals();
 	segv_compositor = ec;
 
@@ -4897,7 +4901,8 @@  out:
 
 	weston_compositor_xkb_destroy(ec);
 
-	ec->destroy(ec);
+	ec->backend->destroy(ec);
+	free(ec);
 
 out_signals:
 	for (i = ARRAY_LENGTH(signals) - 1; i >= 0; i--)
diff --git a/src/compositor.h b/src/compositor.h
index 2bec183..bc10137 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -583,6 +583,11 @@  enum weston_capability {
 	WESTON_CAP_ARBITRARY_MODES		= 0x0008,
 };
 
+struct weston_backend {
+	void (*destroy)(struct weston_compositor *ec);
+	void (*restore)(struct weston_compositor *ec);
+};
+
 struct weston_compositor {
 	struct wl_signal destroy_signal;
 
@@ -644,9 +649,7 @@  struct weston_compositor {
 
 	pixman_format_code_t read_format;
 
-	void (*destroy)(struct weston_compositor *ec);
-	void (*restore)(struct weston_compositor *ec);
-	int (*authenticate)(struct weston_compositor *c, uint32_t id);
+	struct weston_backend *backend;
 
 	struct weston_launcher *launcher;
 
@@ -1254,7 +1257,7 @@  uint32_t
 weston_compositor_get_time(void);
 
 int
-weston_compositor_init(struct weston_compositor *ec, struct wl_display *display,
+weston_compositor_init(struct weston_compositor *ec,
 		       int *argc, char *argv[], struct weston_config *config);
 int
 weston_compositor_set_presentation_clock(struct weston_compositor *compositor,
@@ -1446,10 +1449,10 @@  weston_output_mode_switch_to_native(struct weston_output *output);
 int
 noop_renderer_init(struct weston_compositor *ec);
 
-struct weston_compositor *
-backend_init(struct wl_display *display, int *argc, char *argv[],
+int
+backend_init(struct weston_compositor *c,
+	     int *argc, char *argv[],
 	     struct weston_config *config);
-
 int
 module_init(struct weston_compositor *compositor,
 	    int *argc, char *argv[]);