[PATCH weston v3 01/11] compositor: introduce struct weston_backend

Giulio Camuffo giuliocamuffo at gmail.com
Sat Jun 27 04:07:41 PDT 2015


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.
This enable us to logically separate the compositor core from the backend,
allowing the core to be extended without messing with the backends.
---
 src/compositor-drm.c      | 654 +++++++++++++++++++++++-----------------------
 src/compositor-fbdev.c    | 165 ++++++------
 src/compositor-headless.c | 106 ++++----
 src/compositor-rdp.c      | 159 +++++------
 src/compositor-rpi.c      | 148 +++++------
 src/compositor-wayland.c  | 371 +++++++++++++-------------
 src/compositor-x11.c      | 554 ++++++++++++++++++++-------------------
 src/compositor.c          |  29 +-
 src/compositor.h          |  16 +-
 9 files changed, 1123 insertions(+), 1079 deletions(-)

diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index 6d8684d..6d24f05 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -83,8 +83,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;
@@ -201,7 +202,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;
@@ -233,11 +234,11 @@ static int
 drm_sprite_crtc_supported(struct drm_output *output, 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;
 	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))
@@ -262,7 +263,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;
@@ -280,16 +281,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;
@@ -301,18 +302,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;
@@ -342,7 +343,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;
@@ -363,34 +364,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) {
@@ -469,8 +470,8 @@ static struct weston_plane *
 drm_output_prepare_scanout_view(struct drm_output *output,
 				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 *buffer = ev->surface->buffer_ref.buffer;
 	struct weston_buffer_viewport *viewport = &ev->surface->buffer_viewport;
 	struct gbm_bo *bo;
@@ -478,7 +479,7 @@ drm_output_prepare_scanout_view(struct drm_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 ||
@@ -488,7 +489,7 @@ drm_output_prepare_scanout_view(struct drm_output *output,
 	if (ev->geometry.scissor_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 */
@@ -501,7 +502,7 @@ drm_output_prepare_scanout_view(struct drm_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;
@@ -515,11 +516,12 @@ drm_output_prepare_scanout_view(struct drm_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) {
@@ -527,7 +529,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);
@@ -564,16 +566,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
@@ -582,7 +584,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)
@@ -590,7 +593,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)
@@ -602,8 +605,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;
@@ -619,7 +622,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);
@@ -630,7 +633,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");
@@ -644,7 +647,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,
@@ -655,10 +658,10 @@ drm_output_repaint(struct weston_output *output_base,
 		    !drm_sprite_crtc_supported(output, 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,
@@ -676,7 +679,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));
@@ -702,8 +705,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;
 
@@ -717,7 +720,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;
@@ -727,7 +730,7 @@ drm_output_start_repaint_loop(struct weston_output *output_base)
 
 finish_frame:
 	/* if we cannot page-flip, immediately finish frame */
-	weston_compositor_read_presentation_clock(&compositor->base, &ts);
+	weston_compositor_read_presentation_clock(output_base->compositor, &ts);
 	weston_output_finish_frame(output_base, &ts,
 				   PRESENTATION_FEEDBACK_INVALID);
 }
@@ -848,7 +851,7 @@ drm_output_prepare_overlay_view(struct drm_output *output,
 				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;
@@ -858,7 +861,7 @@ drm_output_prepare_overlay_view(struct drm_output *output,
 	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)
@@ -867,7 +870,7 @@ drm_output_prepare_overlay_view(struct drm_output *output,
 	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))
@@ -885,7 +888,7 @@ drm_output_prepare_overlay_view(struct drm_output *output,
 	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, s->possible_crtcs))
 			continue;
 
@@ -899,7 +902,7 @@ drm_output_prepare_overlay_view(struct drm_output *output,
 	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)
@@ -911,7 +914,7 @@ drm_output_prepare_overlay_view(struct drm_output *output,
 		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;
@@ -991,11 +994,11 @@ static struct weston_plane *
 drm_output_prepare_cursor_view(struct drm_output *output,
 			       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;
 
-	if (c->gbm == NULL)
+	if (b->gbm == NULL)
 		return NULL;
 	if (output->base.transform != WL_OUTPUT_TRANSFORM_NORMAL)
 		return NULL;
@@ -1005,7 +1008,7 @@ drm_output_prepare_cursor_view(struct drm_output *output,
 		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->geometry.scissor_enabled)
 		return NULL;
@@ -1024,17 +1027,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;
 	}
 
@@ -1051,7 +1054,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);
 
@@ -1059,19 +1062,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;
@@ -1082,8 +1085,8 @@ drm_output_set_cursor(struct drm_output *output)
 static void
 drm_assign_planes(struct weston_output *output_base)
 {
-	struct drm_compositor *c =
-		(struct drm_compositor *)output_base->compositor;
+	struct drm_backend *b =
+		(struct drm_backend *)output_base->compositor->backend;
 	struct drm_output *output = (struct drm_output *)output_base;
 	struct weston_view *ev, *next;
 	pixman_region32_t overlap, surface_overlap;
@@ -1103,9 +1106,9 @@ drm_assign_planes(struct weston_output *output_base)
 	 * as we do for flipping full screen surfaces.
 	 */
 	pixman_region32_init(&overlap);
-	primary = &c->base.primary_plane;
+	primary = &output_base->compositor->primary_plane;
 
-	wl_list_for_each_safe(ev, next, &c->base.view_list, link) {
+	wl_list_for_each_safe(ev, next, &output_base->compositor->view_list, link) {
 		struct weston_surface *es = ev->surface;
 
 		/* Test whether this buffer can ever go into a plane:
@@ -1116,7 +1119,7 @@ drm_assign_planes(struct weston_output *output_base)
 		 * 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))))
@@ -1169,8 +1172,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) {
@@ -1185,18 +1188,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);
@@ -1237,16 +1240,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");
@@ -1258,7 +1261,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);
 
@@ -1281,9 +1284,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;
@@ -1292,7 +1295,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;
@@ -1317,7 +1320,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;
@@ -1326,14 +1329,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",
@@ -1343,8 +1346,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)
@@ -1352,7 +1355,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;
@@ -1360,15 +1363,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;
 }
@@ -1419,19 +1422,19 @@ fallback_format_for(uint32_t format)
 }
 
 static int
-drm_compositor_create_gl_renderer(struct drm_compositor *ec)
+drm_backend_create_gl_renderer(struct drm_backend *b)
 {
 	EGLint format[2] = {
-		ec->format,
-		fallback_format_for(ec->format),
+		b->format,
+		fallback_format_for(b->format),
 	};
 	int n_formats = 1;
 
 	if (format[1])
 		n_formats = 2;
-	if (gl_renderer->create(&ec->base,
+	if (gl_renderer->create(b->compositor,
 				EGL_PLATFORM_GBM_KHR,
-				(void *)ec->gbm,
+				(void *)b->gbm,
 				gl_renderer->opaque_attribs,
 				format,
 				n_formats) < 0) {
@@ -1442,15 +1445,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;
 	}
 
@@ -1458,9 +1461,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 *
@@ -1580,12 +1583,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);
 }
 
@@ -1608,7 +1611,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;
@@ -1616,7 +1619,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;
@@ -1626,7 +1629,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;
 		}
 	}
@@ -1636,7 +1639,7 @@ 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[2] = {
 		output->format,
@@ -1644,7 +1647,7 @@ drm_output_init_egl(struct drm_output *output, struct drm_compositor *ec)
 	};
 	int i, flags, n_formats = 1;
 
-	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[0],
@@ -1675,20 +1678,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;
@@ -1697,7 +1700,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;
 
@@ -1843,7 +1846,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)
 {
@@ -1853,12 +1856,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);
@@ -1930,14 +1933,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;
 
@@ -1978,7 +1981,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)
@@ -1996,7 +1999,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;
@@ -2019,7 +2022,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)
@@ -2048,29 +2051,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;
@@ -2087,7 +2090,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;
 	}
@@ -2142,16 +2145,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;
 	}
@@ -2167,9 +2170,9 @@ create_output_for_connector(struct drm_compositor *ec,
 		weston_log("Failed to initialize backlight\n");
 	}
 
-	weston_compositor_add_output(&ec->base, &output->base);
+	weston_compositor_add_output(b->compositor, &output->base);
 
-	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;
 
@@ -2183,12 +2186,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);
@@ -2214,22 +2217,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));
@@ -2237,7 +2240,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;
 
@@ -2254,32 +2257,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);
@@ -2291,7 +2294,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;
@@ -2299,28 +2302,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;
@@ -2328,14 +2331,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;
 		}
@@ -2343,7 +2346,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;
@@ -2355,7 +2358,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;
@@ -2364,7 +2367,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;
@@ -2374,7 +2377,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;
 
@@ -2385,18 +2388,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);
@@ -2406,9 +2409,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);
@@ -2420,18 +2423,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");
@@ -2444,13 +2447,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);
 
@@ -2466,35 +2469,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
@@ -2506,7 +2509,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);
@@ -2523,21 +2526,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
@@ -2548,16 +2551,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);
@@ -2580,14 +2583,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]*");
 
@@ -2595,7 +2598,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");
@@ -2631,17 +2634,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;
@@ -2665,17 +2668,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] "
@@ -2692,18 +2695,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);
 }
@@ -2712,11 +2715,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) {
@@ -2730,7 +2733,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;
@@ -2759,56 +2762,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;
@@ -2817,8 +2820,8 @@ 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;
 
 	/*
@@ -2830,162 +2833,164 @@ drm_compositor_create(struct wl_display *display,
 	 *
 	 * These can be enabled again when nuclear/atomic support lands.
 	 */
-	ec->sprites_are_broken = 1;
-	ec->cursors_are_broken = 1;
+	b->sprites_are_broken = 1;
+	b->cursors_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, true);
-	if (ec->base.launcher == NULL) {
+	compositor->launcher = weston_launcher_connect(compositor, param->tty,
+						       param->seat_id, true);
+	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, compositor);
 
-	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[] = {
@@ -3000,5 +3005,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 a6fd823..6a640ee 100644
--- a/src/compositor-fbdev.c
+++ b/src/compositor-fbdev.c
@@ -50,8 +50,9 @@
 #include "gl-renderer.h"
 #include "presentation_timing-server-protocol.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;
@@ -76,7 +77,7 @@ struct fbdev_screeninfo {
 };
 
 struct fbdev_output {
-	struct fbdev_compositor *compositor;
+	struct fbdev_backend *backend;
 	struct weston_output base;
 
 	struct weston_mode mode;
@@ -110,10 +111,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
@@ -182,10 +183,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);
@@ -481,7 +482,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;
@@ -499,7 +500,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. */
@@ -508,7 +509,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;
@@ -536,7 +537,7 @@ fbdev_output_create(struct fbdev_compositor *compositor,
 	output->base.model = output->fb_info.id;
 	output->base.name = strdup("fbdev");
 
-	section = weston_config_get_section(compositor->base.config,
+	section = weston_config_get_section(backend->compositor->config,
 					    "output", "name",
 					    output->base.name);
 	weston_config_section_get_string(section, "transform", &s, "normal");
@@ -545,7 +546,7 @@ fbdev_output_create(struct fbdev_compositor *compositor,
 			   s, output->base.name);
 	free(s);
 
-	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,
 	                   config_transform,
@@ -566,7 +567,7 @@ fbdev_output_create(struct fbdev_compositor *compositor,
 		goto out_hw_surface;
 	}
 
-	if (compositor->use_pixman) {
+	if (backend->use_pixman) {
 		if (pixman_renderer_output_create(&output->base) < 0)
 			goto out_shadow_surface;
 	} else {
@@ -581,11 +582,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);
 
-	weston_compositor_add_output(&compositor->base, &output->base);
+	weston_compositor_add_output(backend->compositor, &output->base);
 
 	weston_log("fbdev output %d×%d px\n",
 	           output->mode.width, output->mode.height);
@@ -613,14 +614,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);
 
@@ -661,7 +662,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);
@@ -696,13 +697,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;
@@ -722,11 +723,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);
@@ -737,48 +738,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
@@ -788,7 +790,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;
 		}
 	}
@@ -808,61 +810,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",
-							    false);
-	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", false);
+	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)
+	if (backend->use_pixman) {
+		if (pixman_renderer_init(compositor) < 0)
 			goto out_launcher;
 	} else {
 		gl_renderer = weston_load_module("gl-renderer.so",
@@ -872,7 +874,7 @@ fbdev_compositor_create(struct wl_display *display, int *argc, char *argv[],
 			goto out_launcher;
 		}
 
-		if (gl_renderer->create(&compositor->base, NO_EGL_PLATFORM,
+		if (gl_renderer->create(compositor, NO_EGL_PLATFORM,
 					EGL_DEFAULT_DISPLAY,
 					gl_renderer->opaque_attribs,
 					NULL, 0) < 0) {
@@ -881,35 +883,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 = {
@@ -926,5 +930,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 c0e35ce..8e40152 100644
--- a/src/compositor-headless.c
+++ b/src/compositor-headless.c
@@ -36,8 +36,9 @@
 #include "pixman-renderer.h"
 #include "presentation_timing-server-protocol.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;
 };
@@ -99,12 +100,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);
@@ -118,9 +119,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;
 
@@ -137,13 +139,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);
 
@@ -155,7 +157,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;
@@ -173,28 +175,28 @@ headless_compositor_create_output(struct headless_compositor *c,
 						  output->image);
 	}
 
-	weston_compositor_add_output(&c->base, &output->base);
+	weston_compositor_add_output(c, &output->base);
 
 	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
@@ -205,68 +207,69 @@ 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, int *argc, char *argv[],
+			struct weston_config *config)
 {
-	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)
+	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)
-		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 },
@@ -284,6 +287,9 @@ 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,
+				    argc, argv, config);
+	if (b == NULL)
+		return -1;
+	return 0;
 }
diff --git a/src/compositor-rdp.c b/src/compositor-rdp.c
index 6d4d1e4..96d4b5f 100644
--- a/src/compositor-rdp.c
+++ b/src/compositor-rdp.c
@@ -73,7 +73,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;
@@ -87,8 +87,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];
@@ -125,7 +126,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;
@@ -137,7 +138,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;
@@ -323,7 +324,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)
@@ -467,7 +468,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;
@@ -491,7 +492,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";
@@ -508,7 +509,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;
@@ -518,9 +519,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;
 
-	weston_compositor_add_output(&c->base, &output->base);
+	weston_compositor_add_output(b->compositor, &output->base);
 	return 0;
 
 out_shadow_surface:
@@ -560,7 +561,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];
@@ -571,15 +572,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;
 }
 
@@ -793,7 +794,7 @@ static BOOL
 xf_peer_activate(freerdp_peer* client)
 {
 	RdpPeerContext *peerCtx;
-	struct rdp_compositor *c;
+	struct rdp_backend *b;
 	struct rdp_output *output;
 	rdpSettings *settings;
 	rdpPointerUpdate *pointer;
@@ -808,9 +809,9 @@ xf_peer_activate(freerdp_peer* client)
 
 
 	peerCtx = (RdpPeerContext *)client->context;
-	c = peerCtx->rdpCompositor;
+	b = peerCtx->rdpBackend;
 	peersItem = &peerCtx->item;
-	output = c->output;
+	output = b->output;
 	settings = client->settings;
 
 	if (!settings->SurfaceCommandsEnabled) {
@@ -821,7 +822,7 @@ xf_peer_activate(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 */
@@ -891,7 +892,7 @@ xf_peer_activate(freerdp_peer* client)
 	else
 		snprintf(seat_name, sizeof(seat_name), "RDP peer @%s", settings->ClientAddress);
 
-	weston_seat_init(&peersItem->seat, &c->base, seat_name);
+	weston_seat_init(&peersItem->seat, b->compositor, seat_name);
 	weston_seat_init_keyboard(&peersItem->seat, keymap);
 	weston_seat_init_pointer(&peersItem->seat);
 
@@ -929,7 +930,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);
@@ -976,7 +977,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);
@@ -993,7 +994,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;
 
@@ -1071,7 +1072,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];
@@ -1087,17 +1088,17 @@ 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;
 
 	client->Initialize(client);
 
 	settings = client->settings;
 	/* configure security settings */
-	if (c->rdp_key)
-		settings->RdpKeyFile = strdup(c->rdp_key);
-	if (c->tls_enabled) {
-		settings->CertificateFile = strdup( c->server_cert);
-		settings->PrivateKeyFile = strdup(c->server_key);
+	if (b->rdp_key)
+		settings->RdpKeyFile = strdup(b->rdp_key);
+	if (b->tls_enabled) {
+		settings->CertificateFile = strdup(b->server_cert);
+		settings->PrivateKeyFile = strdup(b->server_key);
 	} else {
 		settings->TlsSecurity = FALSE;
 	}
@@ -1130,7 +1131,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]);
 
@@ -1140,7 +1141,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;
 }
 
@@ -1148,8 +1149,8 @@ rdp_peer_init(freerdp_peer *client, struct rdp_compositor *c)
 static FREERDP_CB_RET_TYPE
 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) {
 		weston_log("error when treating incoming peer");
 		FREERDP_CB_RETURN(FALSE);
 	}
@@ -1157,58 +1158,59 @@ rdp_incoming_peer(freerdp_listener *instance, freerdp_peer *client)
 	FREERDP_CB_RETURN(TRUE);
 }
 
-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 */
@@ -1219,36 +1221,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);
@@ -1273,5 +1277,8 @@ backend_init(struct wl_display *display, int *argc, char *argv[],
 		return NULL;
 	}
 
-	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 8012461..14bd76b 100644
--- a/src/compositor-rpi.c
+++ b/src/compositor-rpi.c
@@ -60,7 +60,7 @@
 #define DBG(...) do {} while (0)
 #endif
 
-struct rpi_compositor;
+struct rpi_backend;
 struct rpi_output;
 
 struct rpi_flippipe {
@@ -71,7 +71,7 @@ struct rpi_flippipe {
 };
 
 struct rpi_output {
-	struct rpi_compositor *compositor;
+	struct rpi_backend *backend;
 	struct weston_output base;
 	int single_buffer;
 
@@ -90,8 +90,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;
@@ -113,10 +114,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
@@ -191,9 +192,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);
@@ -229,8 +230,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");
@@ -241,7 +242,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);
@@ -291,7 +292,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;
@@ -302,8 +303,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");
@@ -354,14 +355,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;
 
-	weston_compositor_add_output(&compositor->base, &output->base);
+	weston_compositor_add_output(backend->compositor, &output->base);
 
 	weston_log("Raspberry Pi HDMI output %dx%d px\n",
 		   output->mode.width, output->mode.height);
@@ -391,38 +392,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
@@ -433,7 +435,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;
 		}
 	};
@@ -459,56 +461,50 @@ 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",
-							    false);
-	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", false);
+	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);
 
@@ -521,45 +517,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 */
@@ -582,5 +579,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 ab73853..626d8de 100644
--- a/src/compositor-wayland.c
+++ b/src/compositor-wayland.c
@@ -51,8 +51,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;
@@ -157,7 +158,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 {
@@ -217,9 +218,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;
@@ -424,8 +425,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
@@ -442,7 +443,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
@@ -557,8 +558,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;
 
@@ -575,21 +576,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;
 }
 
@@ -597,10 +598,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);
@@ -672,8 +673,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;
@@ -686,13 +687,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);
@@ -700,12 +701,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);
@@ -749,8 +750,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;
 
@@ -768,14 +769,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)
@@ -796,8 +797,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);
@@ -809,8 +810,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);
 	}
@@ -888,7 +889,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;
@@ -905,9 +906,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);
@@ -921,14 +922,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);
@@ -942,7 +943,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);
 
@@ -958,7 +959,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;
@@ -980,7 +981,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)
 {
@@ -1002,16 +1003,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;
@@ -1019,10 +1020,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)
@@ -1042,10 +1043,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;
@@ -1062,7 +1063,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;
 
-	weston_compositor_add_output(&c->base, &output->base);
+	weston_compositor_add_output(b->compositor, &output->base);
 
 	return output;
 
@@ -1082,7 +1083,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)
@@ -1133,7 +1134,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);
 
@@ -1141,7 +1142,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;
@@ -1160,15 +1161,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)
@@ -1190,13 +1191,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));
@@ -1245,10 +1246,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;
@@ -1402,8 +1403,8 @@ input_handle_button(void *data, struct wl_pointer *pointer,
 			input->output = NULL;
 			input->keyboard_focus = NULL;
 
-			if (wl_list_empty(&input->compositor->base.output_list))
-				wl_display_terminate(input->compositor->base.wl_display);
+			if (wl_list_empty(&input->backend->compositor->output_list))
+				wl_display_terminate(input->backend->compositor->wl_display);
 
 			return;
 		}
@@ -1455,7 +1456,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);
@@ -1574,16 +1575,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,
@@ -1596,10 +1597,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 = {
@@ -1651,7 +1652,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;
 
@@ -1659,17 +1660,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
@@ -1751,7 +1752,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;
 
@@ -1760,7 +1761,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);
@@ -1773,11 +1774,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);
 	}
 }
 
@@ -1803,26 +1804,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);
 	}
 }
@@ -1831,10 +1832,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);
 }
@@ -1845,24 +1846,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;
@@ -1876,14 +1877,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[] = {
@@ -1894,7 +1895,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;
@@ -1905,19 +1906,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;
 	}
@@ -1927,10 +1928,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;
 
@@ -1945,123 +1946,123 @@ 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,
+	if (!b->use_pixman) {
+		if (gl_renderer->create(compositor,
 					EGL_PLATFORM_WAYLAND_KHR,
-					c->parent.wl_display,
+					b->parent.wl_display,
 					gl_renderer->alpha_attribs,
 					NULL,
 					0) < 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;
@@ -2091,29 +2092,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;
@@ -2131,7 +2132,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;
@@ -2149,7 +2150,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;
@@ -2160,13 +2161,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 80ed8c0..8ca809a 100644
--- a/src/compositor-x11.c
+++ b/src/compositor-x11.c
@@ -64,8 +64,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;
@@ -122,14 +123,14 @@ struct x11_output {
 };
 
 struct window_delete_data {
-	struct x11_compositor	*compositor;
+	struct x11_backend	*backend;
 	xcb_window_t		window;
 };
 
 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;
@@ -140,9 +141,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;
 
@@ -164,16 +165,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)
@@ -197,12 +198,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;
@@ -216,17 +217,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,
@@ -234,17 +235,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;
@@ -260,14 +261,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 "
@@ -277,72 +278,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
@@ -375,7 +376,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;
@@ -409,11 +410,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);
@@ -428,7 +429,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;
 
@@ -438,7 +439,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,
@@ -446,7 +447,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);
@@ -469,16 +470,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);
@@ -490,18 +491,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);
 
@@ -509,16 +510,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),
@@ -541,7 +542,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;
@@ -562,15 +563,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;
@@ -591,10 +592,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) {
@@ -659,7 +660,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;
@@ -672,7 +673,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");
@@ -680,7 +681,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");
@@ -695,7 +696,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) {
@@ -736,9 +737,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, op code %d, resource id %d\n",
 			   err->error_code, err->major_code, err->minor_code);
@@ -752,14 +753,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)
@@ -817,10 +818,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,
@@ -832,10 +833,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 {
@@ -847,32 +848,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;
@@ -888,15 +889,15 @@ 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) {
 			weston_log("Failed to initialize SHM for the X11 output\n");
@@ -904,7 +905,7 @@ x11_compositor_create_output(struct x11_compositor *c, int x, int y,
 		}
 		if (pixman_renderer_output_create(&output->base) < 0) {
 			weston_log("Failed to create pixman renderer for output\n");
-			x11_output_deinit_shm(c, output);
+			x11_output_deinit_shm(b, output);
 			return NULL;
 		}
 	} else {
@@ -922,11 +923,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);
 
-	weston_compositor_add_output(&c->base, &output->base);
+	weston_compositor_add_output(b->compositor, &output->base);
 
 	weston_log("x11 output %dx%d, window id %d\n",
 		   width, height, output->window);
@@ -935,11 +936,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;
 	}
@@ -948,42 +949,42 @@ 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);
 	if (output)
 		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);
 }
 
 static void delete_cb(void *data)
 {
 	struct window_delete_data *wd = data;
 
-	x11_compositor_delete_window(wd->compositor, wd->window);
+	x11_backend_delete_window(wd->backend, wd->window);
 	free(wd);
 }
 
 #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
 
@@ -999,37 +1000,37 @@ 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 (!output)
 		return;
 
 	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 |
@@ -1040,10 +1041,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) {
 	case 1:
@@ -1059,28 +1060,28 @@ 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);
@@ -1090,24 +1091,24 @@ x11_compositor_deliver_button_event(struct x11_compositor *c,
 		break;
 	}
 
-	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);
 	if (!output)
 		return;
 
@@ -1116,16 +1117,16 @@ x11_compositor_deliver_motion_event(struct x11_compositor *c,
 					   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;
@@ -1134,9 +1135,9 @@ 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);
 	if (!output)
 		return;
 
@@ -1144,23 +1145,23 @@ x11_compositor_deliver_enter_event(struct x11_compositor *c,
 					   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
 	}
 
@@ -1168,9 +1169,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;
@@ -1188,7 +1189,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) {
@@ -1210,8 +1211,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,
@@ -1224,12 +1225,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;
 				}
 			}
@@ -1238,7 +1239,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);
@@ -1253,42 +1254,42 @@ 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);
 			if (!output)
 				break;
 
@@ -1297,23 +1298,23 @@ x11_compositor_handle_event(int fd, uint32_t mask, void *data)
 			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) {
+			if (atom == b->atom.wm_delete_window) {
 				struct wl_event_loop *loop;
 				struct window_delete_data *data = malloc(sizeof *data);
 
@@ -1322,12 +1323,12 @@ x11_compositor_handle_event(int fd, uint32_t mask, void *data)
 				 * a crash.
 				 */
 				if (!data) {
-					x11_compositor_delete_window(c, window);
+					x11_backend_delete_window(b, window);
 					break;
 				}
-				data->compositor = c;
+				data->backend = b;
 				data->window = window;
-				loop = wl_display_get_event_loop(c->base.wl_display);
+				loop = wl_display_get_event_loop(b->compositor->wl_display);
 				wl_event_loop_add_idle(loop, delete_cb, data);
 			}
 			break;
@@ -1345,7 +1346,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:
@@ -1353,19 +1354,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
@@ -1378,8 +1379,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,
@@ -1394,10 +1395,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) },
@@ -1426,31 +1427,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;
@@ -1482,19 +1483,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;
 
@@ -1503,20 +1504,20 @@ init_gl_renderer(struct x11_compositor *c)
 	if (!gl_renderer)
 		return -1;
 
-	ret = gl_renderer->create(&c->base, EGL_PLATFORM_X11_KHR, (void *) c->dpy,
+	ret = gl_renderer->create(b->compositor, EGL_PLATFORM_X11_KHR, (void *) b->dpy,
 				  gl_renderer->opaque_attribs, NULL, 0);
 
 	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;
@@ -1528,56 +1529,56 @@ 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) {
 			weston_log("Failed to initialize pixman renderer for X11 backend\n");
 			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) {
 		weston_log("Failed to create X11 input\n");
 		goto err_renderer;
 	}
@@ -1588,7 +1589,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;
@@ -1624,10 +1625,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) {
 			weston_log("Failed to create configured x11 output\n");
@@ -1642,9 +1643,9 @@ 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) {
 			weston_log("Failed to create x11 output #%d\n", i);
 			goto err_x11_input;
@@ -1652,30 +1653,32 @@ x11_compositor_create(struct wl_display *display,
 		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;
@@ -1692,9 +1695,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 1e09163..06474a2 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -4502,7 +4502,6 @@ timeline_key_binding_handler(struct weston_seat *seat, uint32_t time,
 
 WL_EXPORT int
 weston_compositor_init(struct weston_compositor *ec,
-		       struct wl_display *display,
 		       int *argc, char *argv[],
 		       struct weston_config *config)
 {
@@ -4511,7 +4510,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);
@@ -4531,11 +4529,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;
 
@@ -4584,7 +4582,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);
@@ -4900,7 +4898,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);
 }
@@ -5281,10 +5279,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;
@@ -5373,12 +5370,19 @@ int main(int argc, char *argv[])
 	if (!backend_init)
 		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");
 		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;
 
@@ -5466,7 +5470,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 9069fe1..bec404a 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -603,6 +603,11 @@ enum weston_capability {
 	WESTON_CAP_VIEW_CLIP_MASK		= 0x0010,
 };
 
+struct weston_backend {
+	void (*destroy)(struct weston_compositor *ec);
+	void (*restore)(struct weston_compositor *ec);
+};
+
 struct weston_compositor {
 	struct wl_signal destroy_signal;
 
@@ -664,8 +669,7 @@ struct weston_compositor {
 
 	pixman_format_code_t read_format;
 
-	void (*destroy)(struct weston_compositor *ec);
-	void (*restore)(struct weston_compositor *ec);
+	struct weston_backend *backend;
 
 	struct weston_launcher *launcher;
 
@@ -1334,7 +1338,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,
@@ -1539,10 +1543,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[]);
-- 
2.4.4



More information about the wayland-devel mailing list