[clutter/multi-backend: 2/7] Rework the interaction between the Cogl and GDK / X11 backends.



commit 856906bb7bbdeb58417b31df64c63188fd2c2e5d
Author: Giovanni Campagna <gcampagna src gnome org>
Date:   Sat Aug 27 00:16:12 2011 +0200

    Rework the interaction between the Cogl and GDK / X11 backends.
    
    Previously, the Cogl backend was at times a subclass of the X11
    backend, and at times a standalone one. Now it is the other way
    round, with GDK and X11 backends providing the concrete classes,
    layered on top of the generic Cogl backend. A new EglNative backend
    was introduced for direct to framebuffer rendering. This greatly
    simplifies the API design (at the expense of some casts needed)
    and reduces the amount of #ifdefs, without duplicating code.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=657434

 clutter/Makefile.am                                |   21 +-
 clutter/cogl/clutter-backend-cogl.c                |  327 +-------------------
 clutter/cogl/clutter-backend-cogl.h                |   41 ---
 clutter/cogl/clutter-stage-cogl.c                  |  167 +++-------
 clutter/cogl/clutter-stage-cogl.h                  |   20 --
 clutter/egl/clutter-backend-eglnative.c            |  262 ++++++++++++++++
 clutter/egl/clutter-backend-eglnative.h            |   80 +++++
 clutter/egl/clutter-cex100.h                       |   91 ++++++
 clutter/{cogl => egl}/clutter-event-tslib.c        |    4 +-
 clutter/gdk/clutter-backend-gdk.c                  |  176 ++++++++---
 clutter/gdk/clutter-backend-gdk.h                  |    5 +-
 clutter/gdk/clutter-stage-gdk.c                    |  161 +++++-----
 clutter/gdk/clutter-stage-gdk.h                    |    9 +-
 clutter/x11/clutter-backend-x11.c                  |  211 +++++++++----
 clutter/x11/clutter-backend-x11.h                  |   12 +-
 clutter/{cogl => x11}/clutter-glx-texture-pixmap.c |    0
 clutter/{cogl => x11}/clutter-glx-texture-pixmap.h |    0
 clutter/{cogl => x11}/clutter-glx.h                |    0
 clutter/x11/clutter-stage-x11.c                    |  139 ++++++---
 clutter/x11/clutter-stage-x11.h                    |    9 +-
 configure.ac                                       |   29 +-
 21 files changed, 973 insertions(+), 791 deletions(-)
---
diff --git a/clutter/Makefile.am b/clutter/Makefile.am
index 68a45ad..b9538ec 100644
--- a/clutter/Makefile.am
+++ b/clutter/Makefile.am
@@ -345,12 +345,6 @@ backend_source_c_priv += $(x11_source_c_priv)
 # the list of files we want to introspect on X11
 x11_introspection = $(x11_source_c) $(x11_source_h)
 
-# pkg-config file for the X11 meta-backend
-clutter-x11-$(CLUTTER_API_VERSION).pc: clutter-$(CLUTTER_API_VERSION).pc
-	$(QUIET_GEN)cp -f $< $(@F)
-
-pc_files += clutter-x11-$(CLUTTER_API_VERSION).pc
-
 clutterx11_includedir = $(clutter_includedir)/x11
 clutterx11_include_HEADERS = $(x11_source_h)
 endif # SUPPORT_X11
@@ -370,14 +364,20 @@ cogl_source_h_priv = \
 
 cogl_source_c_priv =
 
+# pkg-config file for the cogl meta-backend
+clutter-cogl-$(CLUTTER_API_VERSION).pc: clutter-$(CLUTTER_API_VERSION).pc
+	$(QUIET_GEN)cp -f $< $(@F)
+
+pc_files += clutter-cogl-$(CLUTTER_API_VERSION).pc
+
 if SUPPORT_X11
 # For compatability with the old GLX backend
 #
 # Note: there wasn't actually anything GLX specific so we can add
 # the compatability if clutter supports x11
-backend_source_c += $(srcdir)/cogl/clutter-glx-texture-pixmap.c
-glx_source_h = $(srcdir)/cogl/clutter-glx-texture-pixmap.h \
-	       $(srcdir)/cogl/clutter-glx.h
+backend_source_c += $(srcdir)/x11/clutter-glx-texture-pixmap.c
+glx_source_h = $(srcdir)/x11/clutter-glx-texture-pixmap.h \
+	       $(srcdir)/x11/clutter-glx.h
 clutterglx_includedir = $(clutter_includedir)/glx
 clutterglx_include_HEADERS = $(glx_source_h)
 
@@ -419,6 +419,9 @@ if SUPPORT_GDK
 backend_source_h += $(cogl_source_h) $(gdk_source_h)
 backend_source_c += $(cogl_source_c) $(gdk_source_c)
 backend_source_h_priv += $(cogl_source_h_priv) $(gdk_source_h_priv)
+
+cluttergdk_includedir = $(clutter_includedir)/gdk
+cluttergdk_include_HEADERS = $(gdk_source_h)
 endif # SUPPORT_GDK
 
 # Windows backend rules
diff --git a/clutter/cogl/clutter-backend-cogl.c b/clutter/cogl/clutter-backend-cogl.c
index 134ae94..aa8432c 100644
--- a/clutter/cogl/clutter-backend-cogl.c
+++ b/clutter/cogl/clutter-backend-cogl.c
@@ -36,53 +36,19 @@
 
 #include <errno.h>
 
-#include "clutter-config.h"
-
-#ifdef CLUTTER_WINDOWING_GDK
-#include <gdk/gdk.h>
-
-#ifdef GDK_WINDOWING_X11
-#include <gdk/gdkx.h>
-#endif
-
-#endif
-
 #include "clutter-backend-cogl.h"
 #include "clutter-stage-cogl.h"
 
-#ifdef HAVE_EVDEV
-#include "clutter-device-manager-evdev.h"
-#endif
-
 #include "clutter-debug.h"
 #include "clutter-private.h"
 #include "clutter-main.h"
 #include "clutter-stage-private.h"
 
-#ifdef COGL_HAS_EGL_SUPPORT
-#include "clutter-egl.h"
-#endif
-#ifdef COGL_HAS_EGL_PLATFORM_GDL_SUPPORT
-#include "clutter-cex100.h"
-#endif
-
 static ClutterBackendCogl *backend_singleton = NULL;
 
 static gchar *clutter_vblank = NULL;
 
-/* FIXME: We should have CLUTTER_ define for this... */
-#ifdef COGL_HAS_EGL_PLATFORM_GDL_SUPPORT
-static gdl_plane_id_t gdl_plane = GDL_PLANE_ID_UPP_C;
-static guint gdl_n_buffers = CLUTTER_CEX100_TRIPLE_BUFFERING;
-#endif
-
-#ifdef CLUTTER_WINDOWING_X11
-G_DEFINE_TYPE (ClutterBackendCogl, _clutter_backend_cogl, CLUTTER_TYPE_BACKEND_X11);
-#elif defined(CLUTTER_WINDOWING_GDK)
-G_DEFINE_TYPE (ClutterBackendCogl, _clutter_backend_cogl, CLUTTER_TYPE_BACKEND_GDK);
-#else
 G_DEFINE_TYPE (ClutterBackendCogl, _clutter_backend_cogl, CLUTTER_TYPE_BACKEND);
-#endif
 
 static void
 clutter_backend_at_exit (void)
@@ -105,13 +71,6 @@ clutter_backend_cogl_pre_parse (ClutterBackend  *backend,
                                 GError         **error)
 {
   const gchar *env_string;
-#if defined(CLUTTER_WINDOWING_X11) || defined(CLUTTER_WINDOWING_GDK)
-  ClutterBackendClass *parent_class =
-    CLUTTER_BACKEND_CLASS (_clutter_backend_cogl_parent_class);
-
-  if (!parent_class->pre_parse (backend, error))
-    return FALSE;
-#endif
 
   env_string = g_getenv ("CLUTTER_VBLANK");
   if (env_string)
@@ -127,58 +86,11 @@ static gboolean
 clutter_backend_cogl_post_parse (ClutterBackend  *backend,
                                  GError         **error)
 {
-#if defined(CLUTTER_WINDOWING_X11) || defined(CLUTTER_WINDOWING_GDK)
-  ClutterBackendClass *parent_class =
-    CLUTTER_BACKEND_CLASS (_clutter_backend_cogl_parent_class);
-
-  if (!parent_class->post_parse (backend, error))
-    return FALSE;
-
-  return TRUE;
-#endif
-
   g_atexit (clutter_backend_at_exit);
 
   return TRUE;
 }
 
-#if !(defined(CLUTTER_WINDOWING_X11) || defined(CLUTTER_WINDOWING_GDK))
-static ClutterDeviceManager *
-clutter_backend_cogl_get_device_manager (ClutterBackend *backend)
-{
-  ClutterBackendCogl *backend_cogl = CLUTTER_BACKEND_COGL (backend);
-
-  if (G_UNLIKELY (backend_cogl->device_manager == NULL))
-    {
-#ifdef HAVE_EVDEV
-      backend_cogl->device_manager =
-	g_object_new (CLUTTER_TYPE_DEVICE_MANAGER_EVDEV,
-		      "backend", backend_cogl,
-		      NULL);
-#endif
-    }
-
-  return backend_cogl->device_manager;
-}
-#endif /* !(X11 || GDK) */
-
-static void
-clutter_backend_cogl_init_events (ClutterBackend *backend)
-{
-#ifdef HAVE_TSLIB
-  /* XXX: This should be renamed to _clutter_events_tslib_init */
-  _clutter_events_tslib_init (CLUTTER_BACKEND_COGL (backend));
-#endif
-#ifdef HAVE_EVDEV
-  _clutter_events_evdev_init (CLUTTER_BACKEND (backend));
-#endif
-#if defined (CLUTTER_WINDOWING_X11) || defined (CLUTTER_WINDOWING_GDK)
-  /* Chain up to the X11 or GDK backend */
-  CLUTTER_BACKEND_CLASS (_clutter_backend_cogl_parent_class)->
-    init_events (backend);
-#endif
-}
-
 static void
 clutter_backend_cogl_finalize (GObject *gobject)
 {
@@ -192,14 +104,6 @@ static void
 clutter_backend_cogl_dispose (GObject *gobject)
 {
   ClutterBackend *backend = CLUTTER_BACKEND (gobject);
-#ifdef HAVE_TSLIB
-  ClutterBackendCogl *backend_cogl = CLUTTER_BACKEND_COGL (gobject);
-#endif
-
-  /* We chain up before disposing our CoglContext so that we will
-   * destroy all of the stages first. Otherwise the actors may try to
-   * make Cogl calls during destruction which would cause a crash */
-  G_OBJECT_CLASS (_clutter_backend_cogl_parent_class)->dispose (gobject);
 
   if (backend->cogl_context)
     {
@@ -207,16 +111,7 @@ clutter_backend_cogl_dispose (GObject *gobject)
       backend->cogl_context = NULL;
     }
 
-#ifdef HAVE_TSLIB
-  /* XXX: This should be renamed to _clutter_events_tslib_uninit */
-  _clutter_events_egl_uninit (backend_cogl);
-
-  if (backend_cogl->event_timer != NULL)
-    {
-      g_timer_destroy (backend_cogl->event_timer);
-      backend_cogl->event_timer = NULL;
-    }
-#endif
+  G_OBJECT_CLASS (_clutter_backend_cogl_parent_class)->dispose (gobject);
 }
 
 static GObject *
@@ -227,7 +122,7 @@ clutter_backend_cogl_constructor (GType                  gtype,
   GObjectClass *parent_class;
   GObject *retval;
 
-  if (!backend_singleton)
+  if (backend_singleton == NULL)
     {
       parent_class = G_OBJECT_CLASS (_clutter_backend_cogl_parent_class);
       retval = parent_class->constructor (gtype, n_params, params);
@@ -249,15 +144,6 @@ clutter_backend_cogl_get_features (ClutterBackend *backend)
   ClutterBackendCogl *backend_cogl = CLUTTER_BACKEND_COGL (backend);
   ClutterFeatureFlags flags = 0;
 
-#if defined(CLUTTER_WINDOWING_X11) || defined(CLUTTER_WINDOWING_GDK)
-  {
-    ClutterBackendClass *parent_class;
-    parent_class = CLUTTER_BACKEND_CLASS (_clutter_backend_cogl_parent_class);
-
-    flags = parent_class->get_features (backend);
-  }
-#endif
-
   if (cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_MULTIPLE_ONSCREEN))
     {
       CLUTTER_NOTE (BACKEND, "Cogl supports multiple onscreen framebuffers");
@@ -292,175 +178,6 @@ clutter_backend_cogl_get_features (ClutterBackend *backend)
   return flags;
 }
 
-#ifdef CLUTTER_WINDOWING_X11
-static XVisualInfo *
-clutter_backend_cogl_get_visual_info (ClutterBackendX11 *backend_x11)
-{
-  return cogl_clutter_winsys_xlib_get_visual_info ();
-}
-#endif
-
-static gboolean
-clutter_backend_cogl_create_context (ClutterBackend  *backend,
-                                     GError         **error)
-{
-#ifdef CLUTTER_WINDOWING_X11
-  ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend);
-#elif CLUTTER_WINDOWING_GDK
-  ClutterBackendGdk *backend_gdk = CLUTTER_BACKEND_GDK (backend);
-#endif
-  CoglSwapChain *swap_chain = NULL;
-  CoglOnscreenTemplate *onscreen_template = NULL;
-
-  if (backend->cogl_context)
-    return TRUE;
-
-  backend->cogl_renderer = cogl_renderer_new ();
-#ifdef CLUTTER_WINDOWING_X11
-  cogl_xlib_renderer_set_foreign_display (backend->cogl_renderer,
-                                          backend_x11->xdpy);
-#elif defined(CLUTTER_WINDOWING_GDK)
-#if defined(COGL_HAS_XLIB_SUPPORT) && defined(GDK_WINDOWING_X11)
-  if (GDK_IS_X11_DISPLAY (backend_gdk->display))
-    {
-      cogl_xlib_renderer_set_foreign_display (backend->cogl_renderer,
-					      gdk_x11_display_get_xdisplay (backend_gdk->display));
-    }
-  else
-#endif
-    {
-      g_warning ("Unsupported GdkDisplay type %s", G_OBJECT_TYPE_NAME (backend_gdk->display));
-      goto error;
-    }
-#endif /* GDK */
-  
-  if (!cogl_renderer_connect (backend->cogl_renderer, error))
-    goto error;
-
-  swap_chain = cogl_swap_chain_new ();
-#if defined(CLUTTER_WINDOWING_X11)
-  cogl_swap_chain_set_has_alpha (swap_chain,
-                                 clutter_x11_get_use_argb_visual ());
-#elif defined(CLUTTER_WINDOWING_GDK)
-  cogl_swap_chain_set_has_alpha (swap_chain,
-				 gdk_screen_get_rgba_visual (backend_gdk->screen) != NULL);
-#endif
-
-#ifdef COGL_HAS_EGL_PLATFORM_GDL_SUPPORT
-  cogl_swap_chain_set_length (swap_chain, gdl_n_buffers);
-#endif
-
-  onscreen_template = cogl_onscreen_template_new (swap_chain);
-  cogl_object_unref (swap_chain);
-
-  /* XXX: I have some doubts that this is a good design.
-   * Conceptually should we be able to check an onscreen_template
-   * without more details about the CoglDisplay configuration?
-   */
-  if (!cogl_renderer_check_onscreen_template (backend->cogl_renderer,
-                                              onscreen_template,
-                                              error))
-    goto error;
-
-  backend->cogl_display = cogl_display_new (backend->cogl_renderer,
-                                            onscreen_template);
-
-#ifdef COGL_HAS_EGL_PLATFORM_GDL_SUPPORT
-  cogl_gdl_display_set_plane (backend->cogl_display, gdl_plane);
-#endif
-
-  cogl_object_unref (backend->cogl_renderer);
-  cogl_object_unref (onscreen_template);
-
-  if (!cogl_display_setup (backend->cogl_display, error))
-    goto error;
-
-  backend->cogl_context = cogl_context_new (backend->cogl_display, error);
-  if (!backend->cogl_context)
-    goto error;
-
-  return TRUE;
-
-error:
-  if (backend->cogl_display)
-    {
-      cogl_object_unref (backend->cogl_display);
-      backend->cogl_display = NULL;
-    }
-
-  if (onscreen_template)
-    cogl_object_unref (onscreen_template);
-  if (swap_chain)
-    cogl_object_unref (swap_chain);
-
-  if (backend->cogl_renderer)
-    {
-      cogl_object_unref (backend->cogl_renderer);
-      backend->cogl_renderer = NULL;
-    }
-  return FALSE;
-}
-
-static ClutterStageWindow *
-clutter_backend_cogl_create_stage (ClutterBackend  *backend,
-                                   ClutterStage    *wrapper,
-                                   GError         **error)
-{
-#if defined(CLUTTER_WINDOWING_X11)
-  ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend);
-  ClutterEventTranslator *translator;
-  ClutterStageWindow *stage;
-  ClutterStageX11 *stage_x11;
-
-  stage = g_object_new (CLUTTER_TYPE_STAGE_COGL, NULL);
-
-  /* copy backend data into the stage */
-  stage_x11 = CLUTTER_STAGE_X11 (stage);
-  stage_x11->wrapper = wrapper;
-  stage_x11->backend = backend_x11;
-
-  translator = CLUTTER_EVENT_TRANSLATOR (stage_x11);
-  _clutter_backend_add_event_translator (backend, translator);
-
-  CLUTTER_NOTE (MISC, "Cogl stage created (display:%p, screen:%d, root:%u)",
-                backend_x11->xdpy,
-                backend_x11->xscreen_num,
-                (unsigned int) backend_x11->xwin_root);
-
-  return stage;
-
-#elif defined(CLUTTER_WINDOWING_GDK)
-  return g_object_new (CLUTTER_TYPE_STAGE_COGL,
-		       "wrapper", wrapper,
-		       "backend", backend,
-		       NULL);
-#else
-
-  ClutterBackendCogl *backend_cogl = CLUTTER_BACKEND_COGL (backend);
-  ClutterStageWindow *stage;
-  ClutterStageCogl *stage_cogl;
-
-  if (G_UNLIKELY (backend_cogl->stage != NULL))
-    {
-      g_set_error (error, CLUTTER_INIT_ERROR,
-                   CLUTTER_INIT_ERROR_BACKEND,
-                   "The Cogl backend does not support multiple "
-                   "onscreen windows");
-      return backend_cogl->stage;
-    }
-
-  stage = g_object_new (CLUTTER_TYPE_STAGE_COGL, NULL);
-
-  stage_cogl = CLUTTER_STAGE_COGL (stage);
-  stage_cogl->backend = backend_cogl;
-  stage_cogl->wrapper = wrapper;
-
-  backend_cogl->stage = stage;
-
-  return stage;
-#endif /* CLUTTER_WINDOWING_X11 || CLUTTER_WINDOWING_GDK */
-}
-
 static void
 clutter_backend_cogl_ensure_context (ClutterBackend *backend,
                                      ClutterStage   *stage)
@@ -482,9 +199,6 @@ _clutter_backend_cogl_class_init (ClutterBackendCoglClass *klass)
 {
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
   ClutterBackendClass *backend_class = CLUTTER_BACKEND_CLASS (klass);
-#ifdef CLUTTER_WINDOWING_X11
-  ClutterBackendX11Class *backendx11_class = CLUTTER_BACKEND_X11_CLASS (klass);
-#endif
 
   gobject_class->constructor = clutter_backend_cogl_constructor;
   gobject_class->dispose     = clutter_backend_cogl_dispose;
@@ -493,31 +207,13 @@ _clutter_backend_cogl_class_init (ClutterBackendCoglClass *klass)
   backend_class->pre_parse          = clutter_backend_cogl_pre_parse;
   backend_class->post_parse         = clutter_backend_cogl_post_parse;
   backend_class->get_features       = clutter_backend_cogl_get_features;
-#if !(defined(CLUTTER_WINDOWING_X11) || defined(CLUTTER_WINDOWING_GDK))
-  backend_class->get_device_manager = clutter_backend_cogl_get_device_manager;
-#endif
-  backend_class->init_events        = clutter_backend_cogl_init_events;
-  backend_class->create_stage       = clutter_backend_cogl_create_stage;
-  backend_class->create_context     = clutter_backend_cogl_create_context;
   backend_class->ensure_context     = clutter_backend_cogl_ensure_context;
-
-#ifdef CLUTTER_WINDOWING_X11
-  backendx11_class->get_visual_info = clutter_backend_cogl_get_visual_info;
-#endif
 }
 
 static void
 _clutter_backend_cogl_init (ClutterBackendCogl *backend_cogl)
 {
-#ifdef HAVE_TSLIB
-  backend_cogl->event_timer = g_timer_new ();
-#endif
-}
 
-GType
-_clutter_backend_impl_get_type (void)
-{
-  return _clutter_backend_cogl_get_type ();
 }
 
 #ifdef COGL_HAS_EGL_SUPPORT
@@ -546,22 +242,3 @@ clutter_egl_get_egl_display (void)
 }
 #endif
 
-/* FIXME we should have a CLUTTER_ define for this */
-#ifdef COGL_HAS_EGL_PLATFORM_GDL_SUPPORT
-void
-clutter_cex100_set_plane (gdl_plane_id_t plane)
-{
-  g_return_if_fail (plane >= GDL_PLANE_ID_UPP_A && plane <= GDL_PLANE_ID_UPP_E);
-
-  gdl_plane = plane;
-}
-
-void
-clutter_cex100_set_buffering_mode (ClutterCex100BufferingMode mode)
-{
-  g_return_if_fail (mode == CLUTTER_CEX100_DOUBLE_BUFFERING ||
-                    mode == CLUTTER_CEX100_TRIPLE_BUFFERING);
-
-  gdl_n_buffers = mode;
-}
-#endif
diff --git a/clutter/cogl/clutter-backend-cogl.h b/clutter/cogl/clutter-backend-cogl.h
index 6806559..2467d9d 100644
--- a/clutter/cogl/clutter-backend-cogl.h
+++ b/clutter/cogl/clutter-backend-cogl.h
@@ -37,13 +37,6 @@
 
 #include "clutter-backend-private.h"
 
-#ifdef CLUTTER_WINDOWING_X11
-#include "../x11/clutter-backend-x11.h"
-#endif
-#ifdef CLUTTER_WINDOWING_GDK
-#include "../gdk/clutter-backend-gdk.h"
-#endif
-
 G_BEGIN_DECLS
 
 #define CLUTTER_TYPE_BACKEND_COGL                (_clutter_backend_cogl_get_type ())
@@ -58,52 +51,18 @@ typedef struct _ClutterBackendCoglClass  ClutterBackendCoglClass;
 
 struct _ClutterBackendCogl
 {
-#ifdef CLUTTER_WINDOWING_X11
-  ClutterBackendX11 parent_instance;
-
-#elif defined(CLUTTER_WINDOWING_GDK)
-  ClutterBackendGdk parent_instance;
-
-#else
   ClutterBackend parent_instance;
 
-  /* main stage singleton */
-  ClutterStageWindow *stage;
-
-  /* device manager (ie evdev) */
-  ClutterDeviceManager *device_manager;
-
-  /* event source */
-  GSource *event_source;
-
-  /* event timer */
-  GTimer *event_timer;
-
-#endif /* CLUTTER_WINDOWING_X11 || CLUTTER_WINDOWING_GDK */
-
-  CoglContext *cogl_context;
-
   gboolean can_blit_sub_buffer;
 };
 
 struct _ClutterBackendCoglClass
 {
-#ifdef CLUTTER_WINDOWING_X11
-  ClutterBackendX11Class parent_class;
-#elif defined(CLUTTER_WINDOWING_GDK)
-  ClutterBackendGdkClass parent_class;
-#else
   ClutterBackendClass parent_class;
-#endif
 };
 
 GType _clutter_backend_cogl_get_type (void) G_GNUC_CONST;
 
-#ifdef HAVE_TSLIB
-void _clutter_events_tslib_init   (ClutterBackendCogl *backend);
-void _clutter_events_tslib_uninit (ClutterBackendCogl *backend);
-#endif
-
 const gchar *_clutter_backend_cogl_get_vblank (void);
 
 G_END_DECLS
diff --git a/clutter/cogl/clutter-stage-cogl.c b/clutter/cogl/clutter-stage-cogl.c
index 9e9c0fd..57f1057 100644
--- a/clutter/cogl/clutter-stage-cogl.c
+++ b/clutter/cogl/clutter-stage-cogl.c
@@ -32,15 +32,6 @@
 
 #include "clutter-config.h"
 
-#ifdef CLUTTER_WINDOWING_GDK
-#include <gdk/gdk.h>
-
-#ifdef GDK_WINDOWING_X11
-#include <gdk/gdkx.h>
-#endif
-
-#endif
-
 #include "clutter-stage-cogl.h"
 #include "clutter-backend-cogl.h"
 
@@ -54,24 +45,26 @@
 #include "clutter-stage-private.h"
 #include "clutter-util.h"
 
-#if defined(CLUTTER_WINDOWING_X11) || defined(CLUTTER_WINDOWING_GDK)
-static ClutterStageWindowIface *clutter_stage_window_parent_iface = NULL;
+#ifdef CLUTTER_WINDOWING_X11
+/* needed for a small check in redraw() */
+#include "x11/clutter-stage-x11.h"
 #endif
 
 static void clutter_stage_window_iface_init (ClutterStageWindowIface *iface);
 
 G_DEFINE_TYPE_WITH_CODE (ClutterStageCogl,
                          _clutter_stage_cogl,
-#if defined(CLUTTER_WINDOWING_X11)
-                         CLUTTER_TYPE_STAGE_X11,
-#elif defined(CLUTTER_WINDOWING_GDK)
-			 CLUTTER_TYPE_STAGE_GDK,
-#else
                          G_TYPE_OBJECT,
-#endif
                          G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_STAGE_WINDOW,
                                                 clutter_stage_window_iface_init));
 
+enum {
+  PROP_0,
+  PROP_WRAPPER,
+  PROP_BACKEND,
+  PROP_LAST
+};
+
 static void
 clutter_stage_cogl_unrealize (ClutterStageWindow *stage_window)
 {
@@ -79,11 +72,6 @@ clutter_stage_cogl_unrealize (ClutterStageWindow *stage_window)
 
   CLUTTER_NOTE (BACKEND, "Unrealizing Cogl stage [%p]", stage_cogl);
 
-#if defined(CLUTTER_WINDOWING_X11) || defined(CLUTTER_WINDOWING_GDK)
-  /* chain up to the StageX11 implementation */
-  clutter_stage_window_parent_iface->unrealize (stage_window);
-#endif
-
   if (stage_cogl->onscreen != NULL)
     {
       cogl_object_unref (stage_cogl->onscreen);
@@ -114,11 +102,6 @@ static gboolean
 clutter_stage_cogl_realize (ClutterStageWindow *stage_window)
 {
   ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
-#if defined(CLUTTER_WINDOWING_X11)
-  ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
-#elif defined(CLUTTER_WINDOWING_GDK)
-  ClutterStageGdk *stage_gdk = CLUTTER_STAGE_GDK (stage_window);
-#endif
   ClutterBackend *backend;
   CoglFramebuffer *framebuffer;
   GError *error = NULL;
@@ -130,52 +113,13 @@ clutter_stage_cogl_realize (ClutterStageWindow *stage_window)
                 G_OBJECT_TYPE_NAME (stage_cogl),
                 stage_cogl);
 
-#if defined(CLUTTER_WINDOWING_GDK)
-  /* we need to chain early to parent in the Gdk case, as the X window
-     must be created by GDK, not Cogl */
-  if (!clutter_stage_window_parent_iface->realize (stage_window))
-    return FALSE;
-#endif
-
   backend = clutter_get_default_backend ();
 
-#if defined(CLUTTER_WINDOWING_X11)
-  clutter_actor_get_size (CLUTTER_ACTOR (stage_x11->wrapper), &width, &height);
-#elif defined(CLUTTER_WINDOWING_GDK)
-  clutter_actor_get_size (CLUTTER_ACTOR (stage_gdk->wrapper), &width, &height);
-#endif
-
-  stage_cogl->onscreen = cogl_onscreen_new (backend->cogl_context,
-                                            width, height);
-
-#if defined(CLUTTER_WINDOWING_X11)
-  if (stage_x11->xwin != None)
+  if (stage_cogl->onscreen == NULL)
     {
-      cogl_x11_onscreen_set_foreign_window_xid (stage_cogl->onscreen,
-                                                stage_x11->xwin,
-                                                _clutter_stage_x11_update_foreign_event_mask,
-                                                stage_x11);
-
+      stage_cogl->onscreen = cogl_onscreen_new (backend->cogl_context,
+						width, height);
     }
-#elif defined(CLUTTER_WINDOWING_GDK)
-#if defined(COGL_HAS_XLIB_SUPPORT) && defined(GDK_WINDOWING_X11)
-  if (GDK_IS_X11_WINDOW (stage_gdk->window))
-    {
-      cogl_x11_onscreen_set_foreign_window_xid (stage_cogl->onscreen,
-						gdk_x11_window_get_xid (stage_gdk->window),
-						_clutter_stage_gdk_update_foreign_event_mask,
-						stage_gdk);
-    }
-  else
-#endif
-    {
-      g_warning ("Unsupported GdkWindow type %s", G_OBJECT_TYPE_NAME (stage_gdk->window));
-
-      cogl_object_unref (stage_cogl->onscreen);
-      stage_cogl->onscreen = NULL;
-      return FALSE;
-    }
-#endif
 
   clutter_vblank = _clutter_backend_cogl_get_vblank ();
   if (clutter_vblank && strcmp (clutter_vblank, "none") == 0)
@@ -191,7 +135,7 @@ clutter_stage_cogl_realize (ClutterStageWindow *stage_window)
       return FALSE;
     }
 
-  /* FIXME: for fullscreen Cogl platforms then the size we gave above
+  /* FIXME: for fullscreen Cogl platforms then the size we gave
    * will be ignored, so we need to make sure the stage size is
    * updated to this size. */
 
@@ -203,14 +147,7 @@ clutter_stage_cogl_realize (ClutterStageWindow *stage_window)
                                                     stage_cogl);
     }
 
-#ifdef CLUTTER_WINDOWING_X11
-  if (stage_x11->xwin == None)
-    stage_x11->xwin = cogl_x11_onscreen_get_window_xid (stage_cogl->onscreen);
-
-  return clutter_stage_window_parent_iface->realize (stage_window);
-#else
   return TRUE;
-#endif
 }
 
 static int
@@ -221,8 +158,6 @@ clutter_stage_cogl_get_pending_swaps (ClutterStageWindow *stage_window)
   return stage_cogl->pending_swaps;
 }
 
-#if !(defined(CLUTTER_WINDOWING_X11) || defined(CLUTTER_WINDOWING_GDK))
-
 static ClutterActor *
 clutter_stage_cogl_get_wrapper (ClutterStageWindow *stage_window)
 {
@@ -231,7 +166,7 @@ clutter_stage_cogl_get_wrapper (ClutterStageWindow *stage_window)
 
 static void
 clutter_stage_cogl_show (ClutterStageWindow *stage_window,
-                        gboolean            do_raise)
+			 gboolean            do_raise)
 {
   ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
 
@@ -280,8 +215,6 @@ clutter_stage_cogl_resize (ClutterStageWindow *stage_window,
 {
 }
 
-#endif /* X11 || GDK */
-
 static gboolean
 clutter_stage_cogl_has_redraw_clips (ClutterStageWindow *stage_window)
 {
@@ -410,17 +343,7 @@ clutter_stage_cogl_redraw (ClutterStageWindow *stage_window)
                         "The time spent in blit_sub_buffer",
                         0 /* no application private data */);
 
-#if defined(CLUTTER_WINDOWING_X11)
-  ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_cogl);
-
-  wrapper = CLUTTER_ACTOR (stage_x11->wrapper);
-#elif defined(CLUTTER_WINDOWING_GDK)
-  ClutterStageGdk *stage_gdk = CLUTTER_STAGE_GDK (stage_cogl);
-
-  wrapper = CLUTTER_ACTOR (stage_gdk->wrapper);
-#else
   wrapper = CLUTTER_ACTOR (stage_cogl->wrapper);
-#endif
 
   if (!stage_cogl->onscreen)
     return;
@@ -440,7 +363,7 @@ clutter_stage_cogl_redraw (ClutterStageWindow *stage_window)
       /* While resizing a window clipped redraws are disabled to avoid
        * artefacts. See clutter-event-x11.c:event_translate for a
        * detailed explanation */
-      && G_LIKELY (stage_x11->clipped_redraws_cool_off == 0)
+      && G_LIKELY (CLUTTER_STAGE_X11 (stage_cogl)->clipped_redraws_cool_off == 0)
 #endif
       )
     {
@@ -610,16 +533,6 @@ clutter_stage_cogl_get_active_framebuffer (ClutterStageWindow *stage_window)
 static void
 clutter_stage_window_iface_init (ClutterStageWindowIface *iface)
 {
-#if defined(CLUTTER_WINDOWING_X11) || defined(CLUTTER_WINDOWING_GDK)
-  clutter_stage_window_parent_iface = g_type_interface_peek_parent (iface);
-
-  iface->realize = clutter_stage_cogl_realize;
-  iface->unrealize = clutter_stage_cogl_unrealize;
-
-  /* the rest is inherited from ClutterStageX11 */
-
-#else /* COGL_HAS_X11_SUPPORT */
-
   iface->realize = clutter_stage_cogl_realize;
   iface->unrealize = clutter_stage_cogl_unrealize;
   iface->get_wrapper = clutter_stage_cogl_get_wrapper;
@@ -627,9 +540,6 @@ clutter_stage_window_iface_init (ClutterStageWindowIface *iface)
   iface->resize = clutter_stage_cogl_resize;
   iface->show = clutter_stage_cogl_show;
   iface->hide = clutter_stage_cogl_hide;
-
-#endif /* COGL_HAS_X11_SUPPORT */
-
   iface->get_pending_swaps = clutter_stage_cogl_get_pending_swaps;
   iface->add_redraw_clip = clutter_stage_cogl_add_redraw_clip;
   iface->has_redraw_clips = clutter_stage_cogl_has_redraw_clips;
@@ -639,11 +549,28 @@ clutter_stage_window_iface_init (ClutterStageWindowIface *iface)
   iface->get_active_framebuffer = clutter_stage_cogl_get_active_framebuffer;
 }
 
-#ifdef COGL_HAS_X11_SUPPORT
 static void
-clutter_stage_cogl_dispose (GObject *gobject)
+clutter_stage_cogl_set_property (GObject      *gobject,
+				 guint         prop_id,
+				 const GValue *value,
+				 GParamSpec   *pspec)
 {
-  G_OBJECT_CLASS (_clutter_stage_cogl_parent_class)->dispose (gobject);
+  ClutterStageCogl *self = CLUTTER_STAGE_COGL (gobject);
+
+  switch (prop_id)
+    {
+    case PROP_WRAPPER:
+      self->wrapper = CLUTTER_STAGE (g_value_get_object (value));
+      break;
+
+    case PROP_BACKEND:
+      self->backend = CLUTTER_BACKEND_COGL (g_value_get_object (value));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
+      break;
+    }
 }
 
 static void
@@ -651,14 +578,22 @@ _clutter_stage_cogl_class_init (ClutterStageCoglClass *klass)
 {
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 
-  gobject_class->dispose = clutter_stage_cogl_dispose;
-}
-#else
-static void
-_clutter_stage_cogl_class_init (ClutterStageCoglClass *klass)
-{
+  gobject_class->set_property = clutter_stage_cogl_set_property;
+
+  g_object_class_install_property (gobject_class, PROP_WRAPPER,
+				   g_param_spec_object ("wrapper",
+							"Wrapper",
+							"ClutterStage wrapping this native stage",
+							CLUTTER_TYPE_STAGE,
+							CLUTTER_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
+
+  g_object_class_install_property (gobject_class, PROP_BACKEND,
+				   g_param_spec_object ("backend",
+							"ClutterBackend",
+							"The Clutter backend singleton",
+							CLUTTER_TYPE_BACKEND_COGL,
+							CLUTTER_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
 }
-#endif /* COGL_HAS_X11_SUPPORT */
 
 static void
 _clutter_stage_cogl_init (ClutterStageCogl *stage)
diff --git a/clutter/cogl/clutter-stage-cogl.h b/clutter/cogl/clutter-stage-cogl.h
index ade2322..b514c9b 100644
--- a/clutter/cogl/clutter-stage-cogl.h
+++ b/clutter/cogl/clutter-stage-cogl.h
@@ -15,13 +15,6 @@
 #include <X11/Xutil.h>
 #endif
 
-#ifdef CLUTTER_WINDOWING_X11
-#include "../x11/clutter-stage-x11.h"
-#endif
-#ifdef CLUTTER_WINDOWING_GDK
-#include "../gdk/clutter-stage-gdk.h"
-#endif
-
 #include "clutter-backend-cogl.h"
 
 G_BEGIN_DECLS
@@ -38,13 +31,6 @@ typedef struct _ClutterStageCoglClass    ClutterStageCoglClass;
 
 struct _ClutterStageCogl
 {
-#ifdef CLUTTER_WINDOWING_X11
-  ClutterStageX11 parent_instance;
-
-#elif defined(CLUTTER_WINDOWING_GDK)
-  ClutterStageGdk parent_instance;
-
-#else
   GObject parent_instance;
 
  /* the stage wrapper */
@@ -53,8 +39,6 @@ struct _ClutterStageCogl
   /* back pointer to the backend */
   ClutterBackendCogl *backend;
 
-#endif
-
   CoglOnscreen *onscreen;
 
   gint pending_swaps;
@@ -76,11 +60,7 @@ struct _ClutterStageCogl
 
 struct _ClutterStageCoglClass
 {
-#ifdef CLUTTER_WINDOWING_X11
-  ClutterStageX11Class parent_class;
-#elif defined(CLUTTER_WINDOWING_GDK)
   GObjectClass parent_class;
-#endif
 };
 
 GType _clutter_stage_cogl_get_type (void) G_GNUC_CONST;
diff --git a/clutter/egl/clutter-backend-eglnative.c b/clutter/egl/clutter-backend-eglnative.c
new file mode 100644
index 0000000..2ee1f03
--- /dev/null
+++ b/clutter/egl/clutter-backend-eglnative.c
@@ -0,0 +1,262 @@
+/*
+ * Clutter.
+ *
+ * An OpenGL based 'interactive canvas' library.
+ *
+ * Copyright (C) 2010,2011  Intel Corporation.
+ *               2011 Giovanni Campagna <scampa giovanni gmail com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+
+ * Authors:
+ *  Matthew Allum
+ *  Emmanuele Bassi
+ *  Robert Bragg
+ *  Neil Roberts
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <errno.h>
+
+#include "clutter-backend-eglnative.h"
+/* This is a Cogl based backend */
+#include "cogl/clutter-stage-cogl.h"
+
+#ifdef HAVE_EVDEV
+#include "clutter-device-manager-evdev.h"
+#endif
+
+#include "clutter-debug.h"
+#include "clutter-private.h"
+#include "clutter-main.h"
+#include "clutter-stage-private.h"
+
+#ifdef COGL_HAS_EGL_SUPPORT
+#include "clutter-egl.h"
+#endif
+#ifdef COGL_HAS_EGL_PLATFORM_GDL_SUPPORT
+#include "clutter-cex100.h"
+#endif
+
+static gchar *clutter_vblank = NULL;
+
+/* FIXME: We should have CLUTTER_ define for this... */
+#ifdef COGL_HAS_EGL_PLATFORM_GDL_SUPPORT
+static gdl_plane_id_t gdl_plane = GDL_PLANE_ID_UPP_C;
+static guint gdl_n_buffers = CLUTTER_CEX100_TRIPLE_BUFFERING;
+#endif
+
+G_DEFINE_TYPE (ClutterBackendEglNative, _clutter_backend_egl_native, CLUTTER_TYPE_BACKEND_COGL);
+
+static ClutterDeviceManager *
+clutter_backend_egl_native_get_device_manager (ClutterBackend *backend)
+{
+  ClutterBackendEglNative *backend_egl_native = CLUTTER_BACKEND_EGL_NATIVE (backend);
+
+  if (G_UNLIKELY (backend_egl_native->device_manager == NULL))
+    {
+#ifdef HAVE_EVDEV
+      backend_egl_native->device_manager =
+	g_object_new (CLUTTER_TYPE_DEVICE_MANAGER_EVDEV,
+		      "backend", backend_egl_native,
+		      NULL);
+#endif
+    }
+
+  return backend_egl_native->device_manager;
+}
+
+static void
+clutter_backend_egl_native_init_events (ClutterBackend *backend)
+{
+#ifdef HAVE_TSLIB
+  _clutter_events_tslib_init (CLUTTER_BACKEND_EGL (backend));
+#endif
+#ifdef HAVE_EVDEV
+  _clutter_events_evdev_init (CLUTTER_BACKEND (backend));
+#endif
+}
+
+static void
+clutter_backend_cogl_dispose (GObject *gobject)
+{
+#ifdef HAVE_TSLIB
+  ClutterBackendEglNative *backend_egl_native = CLUTTER_BACKEND_EGL_NATIVE (gobject);
+
+  _clutter_events_tslib_uninit (backend_egl_native);
+
+  if (backend_egl_native->event_timer != NULL)
+    {
+      g_timer_destroy (backend_egl_native->event_timer);
+      backend_egl_native->event_timer = NULL;
+    }
+#endif
+
+  G_OBJECT_CLASS (_clutter_backend_cogl_parent_class)->dispose (gobject);
+}
+
+static ClutterStageWindow *
+clutter_backend_egl_native_create_stage (ClutterBackend  *backend,
+					 ClutterStage    *wrapper,
+					 GError         **error)
+{
+  ClutterBackendEglNative *backend_egl_native = CLUTTER_BACKEND_EGL_NATIVE (backend);
+  ClutterStageWindow *stage;
+  ClutterStageCogl *stage_cogl;
+
+  if (G_UNLIKELY (backend_egl_native->stage != NULL))
+    {
+      g_set_error (error, CLUTTER_INIT_ERROR,
+                   CLUTTER_INIT_ERROR_BACKEND,
+                   "The EglNative backend does not support multiple "
+                   "onscreen windows");
+      return backend_egl_native->stage;
+    }
+
+  stage = g_object_new (CLUTTER_TYPE_STAGE_COGL,
+			"backend", backend,
+			"wrapper", wrapper,
+			NULL);
+  backend_egl_native->stage = stage;
+
+  return stage;
+}
+
+static gboolean
+clutter_backend_egl_native_create_context (ClutterBackend  *backend,
+					   GError         **error)
+{
+  CoglSwapChain *swap_chain = NULL;
+  CoglOnscreenTemplate *onscreen_template = NULL;
+
+  if (backend->cogl_context != NULL)
+    return TRUE;
+
+  backend->cogl_renderer = cogl_renderer_new ();
+  if (!cogl_renderer_connect (backend->cogl_renderer, error))
+    goto error;
+
+  swap_chain = cogl_swap_chain_new ();
+
+#ifdef COGL_HAS_EGL_PLATFORM_GDL_SUPPORT
+  cogl_swap_chain_set_length (swap_chain, gdl_n_buffers);
+#endif
+
+  onscreen_template = cogl_onscreen_template_new (swap_chain);
+  cogl_object_unref (swap_chain);
+
+  /* XXX: I have some doubts that this is a good design.
+   * Conceptually should we be able to check an onscreen_template
+   * without more details about the CoglDisplay configuration?
+   */
+  if (!cogl_renderer_check_onscreen_template (backend->cogl_renderer,
+                                              onscreen_template,
+                                              error))
+    goto error;
+
+  backend->cogl_display = cogl_display_new (backend->cogl_renderer,
+                                            onscreen_template);
+
+#ifdef COGL_HAS_EGL_PLATFORM_GDL_SUPPORT
+  cogl_gdl_display_set_plane (backend->cogl_display, gdl_plane);
+#endif
+
+  cogl_object_unref (backend->cogl_renderer);
+  cogl_object_unref (onscreen_template);
+
+  if (!cogl_display_setup (backend->cogl_display, error))
+    goto error;
+
+  backend->cogl_context = cogl_context_new (backend->cogl_display, error);
+  if (backend->cogl_context == NULL)
+    goto error;
+
+  return TRUE;
+
+error:
+  if (backend->cogl_display != NULL)
+    {
+      cogl_object_unref (backend->cogl_display);
+      backend->cogl_display = NULL;
+    }
+
+  if (onscreen_template != NULL)
+    cogl_object_unref (onscreen_template);
+  if (swap_chain != NULL)
+    cogl_object_unref (swap_chain);
+
+  if (backend->cogl_renderer != NULL)
+    {
+      cogl_object_unref (backend->cogl_renderer);
+      backend->cogl_renderer = NULL;
+    }
+  return FALSE;
+}
+
+static void
+_clutter_backend_egl_native_class_init (ClutterBackendEglNativeClass *klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+  ClutterBackendClass *backend_class = CLUTTER_BACKEND_CLASS (klass);
+
+  gobject_class->dispose     = clutter_backend_egl_native_dispose;
+  gobject_class->finalize    = clutter_backend_egl_native_finalize;
+
+  backend_class->get_device_manager = clutter_backend_egl_native_get_device_manager;
+  backend_class->init_events        = clutter_backend_egl_native_init_events;
+  backend_class->create_stage       = clutter_backend_egl_native_create_stage;
+  backend_class->create_context     = clutter_backend_egl_native_create_context;
+}
+
+static void
+_clutter_backend_egl_native_init (ClutterBackendEglNative *backend_egl_native)
+{
+#ifdef HAVE_TSLIB
+  backend_egl_native->event_timer = g_timer_new ();
+#endif
+}
+
+GType
+_clutter_backend_impl_get_type (void)
+{
+  return _clutter_backend_egl_native_get_type ();
+}
+
+/* FIXME we should have a CLUTTER_ define for this */
+#ifdef COGL_HAS_EGL_PLATFORM_GDL_SUPPORT
+void
+clutter_cex100_set_plane (gdl_plane_id_t plane)
+{
+  g_return_if_fail (plane >= GDL_PLANE_ID_UPP_A && plane <= GDL_PLANE_ID_UPP_E);
+
+  gdl_plane = plane;
+}
+
+void
+clutter_cex100_set_buffering_mode (ClutterCex100BufferingMode mode)
+{
+  g_return_if_fail (mode == CLUTTER_CEX100_DOUBLE_BUFFERING ||
+                    mode == CLUTTER_CEX100_TRIPLE_BUFFERING);
+
+  gdl_n_buffers = mode;
+}
+#endif
diff --git a/clutter/egl/clutter-backend-eglnative.h b/clutter/egl/clutter-backend-eglnative.h
new file mode 100644
index 0000000..959e61c
--- /dev/null
+++ b/clutter/egl/clutter-backend-eglnative.h
@@ -0,0 +1,80 @@
+/* Clutter.
+ * An OpenGL based 'interactive canvas' library.
+ *
+ * Copyright (C) 2006, 2007 OpenedHand
+ * Copyright (C) 2010 Intel Corp
+ *               2011 Giovanni Campagna <scampa giovanni gmail com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ *  Matthew Allum
+ *  Robert Bragg
+ */
+
+#ifndef __CLUTTER_BACKEND_EGL_NATIVE_H__
+#define __CLUTTER_BACKEND_EGL_NATIVE_H__
+
+#include <glib-object.h>
+#include <clutter/clutter-event.h>
+#include <clutter/clutter-backend.h>
+#include <clutter/clutter-device-manager.h>
+
+#include "clutter-backend-private.h"
+#include "cogl/clutter-backend-cogl.h"
+
+G_BEGIN_DECLS
+
+#define CLUTTER_TYPE_BACKEND_EGL_NATIVE                (_clutter_backend_egl_native_get_type ())
+#define CLUTTER_BACKEND_EGL_NATIVE(obj)                (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_BACKEND_EGL_NATIVE, ClutterBackendEglNative))
+#define CLUTTER_IS_BACKEND_EGL_NATIVE(obj)             (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_BACKEND_EGL_NATIVE))
+#define CLUTTER_BACKEND_EGL_NATIVE_CLASS(klass)        (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_BACKEND_EGL_NATIVE, ClutterBackendEglNativeClass))
+#define CLUTTER_IS_BACKEND_EGL_NATIVE_CLASS(klass)     (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_BACKEND_EGL_NATIVE))
+#define CLUTTER_BACKEND_EGL_NATIVE_GET_CLASS(obj)      (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_BACKEND_EGL_NATIVE, ClutterBackendEglNativeClass))
+
+typedef struct _ClutterBackendEglNative       ClutterBackendEglNative;
+typedef struct _ClutterBackendEglNativeClass  ClutterBackendEglNativeClass;
+
+struct _ClutterBackendEglNative
+{
+  ClutterBackendCogl parent_instance;
+
+  /* main stage singleton */
+  ClutterStageWindow *stage;
+
+  /* device manager (ie evdev) */
+  ClutterDeviceManager *device_manager;
+
+  /* event source */
+  GSource *event_source;
+
+  /* event timer */
+  GTimer *event_timer;
+};
+
+struct _ClutterBackendEglNativeClass
+{
+  ClutterBackendCoglClass parent_class;
+};
+
+GType _clutter_backend_egl_native_get_type (void) G_GNUC_CONST;
+
+#ifdef HAVE_TSLIB
+void _clutter_events_tslib_init   (ClutterBackendEglNative *backend);
+void _clutter_events_tslib_uninit (ClutterBackendEglNative *backend);
+#endif
+
+G_END_DECLS
+
+#endif /* __CLUTTER_BACKEND_EGL_NATIVE_H__ */
diff --git a/clutter/egl/clutter-cex100.h b/clutter/egl/clutter-cex100.h
new file mode 100644
index 0000000..452c4ab
--- /dev/null
+++ b/clutter/egl/clutter-cex100.h
@@ -0,0 +1,91 @@
+/*
+ * Clutter.
+ *
+ * An OpenGL based 'interactive canvas' library.
+ *
+ * Copyright (C) 2010 Intel Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ *   Damien Lespiau <damien lespiau intel com>
+ */
+
+/**
+ * SECTION:clutter-cex100
+ * @short_description: Intel CE3100, CE4100 Specific API
+ *
+ * The CEX100 backend for Clutter provides some Intel CE3100/CE4100
+ * specific API
+ *
+ * You need to include
+ * <filename class="headerfile">&lt;clutter/egl/clutter-cex100.h&gt;</filename>
+ * to have access to the functions documented here.
+ */
+
+#ifndef __CLUTTER_CEX100_H__
+#define __CLUTTER_CEX100_H__
+
+#include <glib.h>
+
+#include <libgdl.h>
+
+G_BEGIN_DECLS
+
+/**
+ * clutter_cex100_set_plane:
+ * @plane: a GDL plane
+ *
+ * Intel CE3100 and CE4100 have several planes (frame buffers) and a
+ * hardware blender to blend the planes togeteher and produce the final
+ * image.
+ *
+ * clutter_cex100_set_plane() let's you configure the GDL plane where
+ * the stage will be drawn. By default Clutter will pick UPP_C
+ * (GDL_PLANE_ID_UPP_C).
+ *
+ * <note>This function has to be called before clutter_init()</note>
+ */
+void clutter_cex100_set_plane (gdl_plane_id_t plane);
+
+/**
+ * ClutterCex100BufferingMode:
+ * @CLUTTER_CEX100_DOUBLE_BUFFERING: The GDL plane will be double buffered
+ * @CLUTTER_CEX100_TRIPLE_BUFFERING: The GDL plane will be triple buffered
+ *
+ * Enum passed to clutter_cex100_set_buffering_mode().
+ */
+typedef enum /*< prefix=CLUTTER_CEX100 >*/
+{
+  CLUTTER_CEX100_DOUBLE_BUFFERING = 2,
+  CLUTTER_CEX100_TRIPLE_BUFFERING = 3
+} ClutterCex100BufferingMode;
+
+/**
+ * clutter_cex100_set_buffering_mode:
+ * @mode: a #ClutterCex100BufferingMode
+ *
+ * Configure the buffering mode of the underlying GDL plane. The GDL
+ * surface used by Clutter to draw can be backed up by either one or two
+ * back buffers thus being double or triple buffered, respectively.
+ *
+ * Clutter defaults to %CLUTTER_CEX100_TRIPLE_BUFFERING.
+ *
+ * <note>This function has to be called before clutter_init()</note>
+ */
+void clutter_cex100_set_buffering_mode (ClutterCex100BufferingMode mode);
+
+G_END_DECLS
+
+#endif /* __CLUTTER_CEX100_H__ */
diff --git a/clutter/cogl/clutter-event-tslib.c b/clutter/egl/clutter-event-tslib.c
similarity index 98%
rename from clutter/cogl/clutter-event-tslib.c
rename to clutter/egl/clutter-event-tslib.c
index de04fd8..ca64f48 100644
--- a/clutter/cogl/clutter-event-tslib.c
+++ b/clutter/egl/clutter-event-tslib.c
@@ -96,7 +96,7 @@ get_backend_time (void)
 #endif
 
 void
-_clutter_events_tslib_init (ClutterBackendEGL *backend_egl)
+_clutter_events_tslib_init (ClutterBackendEglNative *backend_egl)
 {
 #ifdef HAVE_TSLIB
   ClutterEventSource *event_source;
@@ -152,7 +152,7 @@ _clutter_events_tslib_init (ClutterBackendEGL *backend_egl)
 }
 
 void
-_clutter_events_egl_uninit (ClutterBackendEGL *backend_egl)
+_clutter_events_egl_uninit (ClutterBackendEglNative *backend_egl)
 {
 #ifdef HAVE_TSLIB
   if (backend_egl->event_timer != NULL)
diff --git a/clutter/gdk/clutter-backend-gdk.c b/clutter/gdk/clutter-backend-gdk.c
index 9286d85..564f1c7 100644
--- a/clutter/gdk/clutter-backend-gdk.c
+++ b/clutter/gdk/clutter-backend-gdk.c
@@ -38,7 +38,9 @@
 #ifdef GDK_WINDOWING_X11
 #include <gdk/gdkx.h>
 #endif
-/* other backends not yet supported */
+#ifdef GDK_WINDOWING_WIN32
+#include <gdk/gdkwin32.h>
+#endif
 
 #include "clutter-backend-gdk.h"
 #include "clutter-device-manager-gdk.h"
@@ -54,10 +56,7 @@
 #include "clutter-private.h"
 
 #define clutter_backend_gdk_get_type _clutter_backend_gdk_get_type
-G_DEFINE_TYPE (ClutterBackendGdk, clutter_backend_gdk, CLUTTER_TYPE_BACKEND);
-
-/* singleton object */
-static ClutterBackendGdk *backend_singleton = NULL;
+G_DEFINE_TYPE (ClutterBackendGdk, clutter_backend_gdk, CLUTTER_TYPE_BACKEND_COGL);
 
 /* global for pre init setup calls */
 static GdkDisplay  *_foreign_dpy = NULL;
@@ -132,20 +131,12 @@ cogl_gdk_filter (GdkXEvent  *xevent,
 }
 
 static gboolean
-_clutter_backend_gdk_pre_parse (ClutterBackend  *backend,
-				GError         **error)
-{
-  /* nothing to do here */
-  return TRUE;
-}
-
-static gboolean
 _clutter_backend_gdk_post_parse (ClutterBackend  *backend,
                                  GError         **error)
 {
   ClutterBackendGdk *backend_gdk = CLUTTER_BACKEND_GDK (backend);
 
-  if (_foreign_dpy)
+  if (_foreign_dpy != NULL)
     backend_gdk->display = _foreign_dpy;
 
   /* Init Gdk, if outside code did not already */
@@ -181,7 +172,8 @@ _clutter_backend_gdk_post_parse (ClutterBackend  *backend,
                 "Gdk Display '%s' opened",
                 gdk_display_get_name (backend_gdk->display));
 
-  return TRUE;
+  return CLUTTER_BACKEND_CLASS (clutter_backend_gdk_parent_class)->post_parse (backend,
+									       error);
 }
 
 
@@ -201,9 +193,6 @@ clutter_backend_gdk_finalize (GObject *gobject)
   gdk_window_remove_filter (NULL, cogl_gdk_filter, NULL);
   g_object_unref (backend_gdk->display);
 
-  if (backend_singleton)
-    backend_singleton = NULL;
-
   G_OBJECT_CLASS (clutter_backend_gdk_parent_class)->finalize (gobject);
 }
 
@@ -224,34 +213,14 @@ clutter_backend_gdk_dispose (GObject *gobject)
   G_OBJECT_CLASS (clutter_backend_gdk_parent_class)->dispose (gobject);
 }
 
-static GObject *
-clutter_backend_gdk_constructor (GType                  gtype,
-                                 guint                  n_params,
-                                 GObjectConstructParam *params)
-{
-  GObjectClass *parent_class;
-  GObject *retval;
-
-  if (backend_singleton == NULL)
-    {
-      parent_class = G_OBJECT_CLASS (clutter_backend_gdk_parent_class);
-      retval = parent_class->constructor (gtype, n_params, params);
-
-      backend_singleton = CLUTTER_BACKEND_GDK (retval);
-
-      return retval;
-    }
-
-  g_critical ("Attempting to create a new backend object. This should "
-	      "never happen, so we return the singleton instance.");
-
-  return g_object_ref (backend_singleton);
-}
-
 static ClutterFeatureFlags
 clutter_backend_gdk_get_features (ClutterBackend *backend)
 {
-  return CLUTTER_FEATURE_STAGE_USER_RESIZE | CLUTTER_FEATURE_STAGE_CURSOR;
+  ClutterFeatureFlags flags = CLUTTER_FEATURE_STAGE_USER_RESIZE | CLUTTER_FEATURE_STAGE_CURSOR;
+
+  flags |= CLUTTER_BACKEND_CLASS (clutter_backend_gdk_parent_class)->get_features (backend);
+
+  return flags;
 }
 
 static void
@@ -293,23 +262,128 @@ clutter_backend_gdk_get_device_manager (ClutterBackend *backend)
   return backend_gdk->device_manager;
 }
 
+static gboolean
+clutter_backend_gdk_create_context (ClutterBackend  *backend,
+				    GError         **error)
+{
+  ClutterBackendGdk *backend_gdk = CLUTTER_BACKEND_GDK (backend);
+  CoglSwapChain *swap_chain = NULL;
+  CoglOnscreenTemplate *onscreen_template = NULL;
+  GdkVisual *rgba_visual = NULL;
+
+  if (backend->cogl_context != NULL)
+    return TRUE;
+
+  backend->cogl_renderer = cogl_renderer_new ();
+
+#if defined(GDK_WINDOWING_X11) && defined(COGL_HAS_XLIB_SUPPORT)
+  if (GDK_IS_X11_DISPLAY (backend_gdk->display))
+    {
+      cogl_xlib_renderer_set_foreign_display (backend->cogl_renderer,
+					      gdk_x11_display_get_xdisplay (backend_gdk->display));
+    }
+  else
+#endif
+#if defined(GDK_WINDOWING_WIN32)
+  if (GDK_IS_WIN32_DISPLAY (backend_gdk->display))
+    {
+      /* Force a WGL winsys on windows */
+      cogl_renderer_set_winsys_id (backend_cogl->cogl_renderer, COGL_WINSYS_ID_WGL);
+    }
+  else
+#endif
+    {
+      g_set_error (error, CLUTTER_INIT_ERROR,
+                   CLUTTER_INIT_ERROR_BACKEND,
+                   "Could not find a suitable CoglWinsys for"
+                   "a GdkDisplay of type %s", G_OBJECT_TYPE_NAME (backend_gdk->display));
+      goto error;
+    }
+
+
+  if (!cogl_renderer_connect (backend->cogl_renderer, error))
+    goto error;
+
+  swap_chain = cogl_swap_chain_new ();
+
+  rgba_visual = gdk_screen_get_rgba_visual (backend_gdk->screen);
+  cogl_swap_chain_set_has_alpha (swap_chain, rgba_visual != NULL);
+
+  onscreen_template = cogl_onscreen_template_new (swap_chain);
+  cogl_object_unref (swap_chain);
+
+  /* XXX: I have some doubts that this is a good design.
+   * Conceptually should we be able to check an onscreen_template
+   * without more details about the CoglDisplay configuration?
+   */
+  if (!cogl_renderer_check_onscreen_template (backend->cogl_renderer,
+                                              onscreen_template,
+                                              error))
+    goto error;
+
+  backend->cogl_display = cogl_display_new (backend->cogl_renderer,
+                                            onscreen_template);
+
+  cogl_object_unref (backend->cogl_renderer);
+  cogl_object_unref (onscreen_template);
+
+  if (!cogl_display_setup (backend->cogl_display, error))
+    goto error;
+
+  backend->cogl_context = cogl_context_new (backend->cogl_display, error);
+  if (backend->cogl_context == NULL)
+    goto error;
+
+  return TRUE;
+
+error:
+  if (backend->cogl_display != NULL)
+    {
+      cogl_object_unref (backend->cogl_display);
+      backend->cogl_display = NULL;
+    }
+
+  if (onscreen_template != NULL)
+    cogl_object_unref (onscreen_template);
+  if (swap_chain != NULL)
+    cogl_object_unref (swap_chain);
+
+  if (backend->cogl_renderer != NULL)
+    {
+      cogl_object_unref (backend->cogl_renderer);
+      backend->cogl_renderer = NULL;
+    }
+  return FALSE;
+}
+
+static ClutterStageWindow *
+clutter_backend_gdk_create_stage (ClutterBackend  *backend,
+				  ClutterStage    *wrapper,
+				  GError         **error)
+{
+  return g_object_new (CLUTTER_TYPE_STAGE_GDK,
+		       "backend", backend,
+		       "wrapper", wrapper,
+		       NULL);
+}
+
 static void
 clutter_backend_gdk_class_init (ClutterBackendGdkClass *klass)
 {
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
   ClutterBackendClass *backend_class = CLUTTER_BACKEND_CLASS (klass);
 
-  gobject_class->constructor = clutter_backend_gdk_constructor;
   gobject_class->dispose = clutter_backend_gdk_dispose;
   gobject_class->finalize = clutter_backend_gdk_finalize;
 
-  backend_class->pre_parse = _clutter_backend_gdk_pre_parse;
   backend_class->post_parse = _clutter_backend_gdk_post_parse;
   backend_class->init_events = clutter_backend_gdk_init_events;
   backend_class->get_features = clutter_backend_gdk_get_features;
   backend_class->get_device_manager = clutter_backend_gdk_get_device_manager;
   backend_class->copy_event_data = clutter_backend_gdk_copy_event_data;
   backend_class->free_event_data = clutter_backend_gdk_free_event_data;
+  backend_class->create_context = clutter_backend_gdk_create_context;
+  backend_class->create_stage = clutter_backend_gdk_create_stage;
 }
 
 static void
@@ -330,13 +404,15 @@ clutter_backend_gdk_init (ClutterBackendGdk *backend_gdk)
 GdkDisplay *
 clutter_gdk_get_default_display (void)
 {
-  if (!backend_singleton)
+  ClutterBackend *backend = clutter_get_default_backend ();
+
+  if (!backend || !CLUTTER_IS_BACKEND_GDK (backend))
     {
       g_critical ("GDK backend has not been initialised");
       return NULL;
     }
 
-  return backend_singleton->display;
+  return CLUTTER_BACKEND_GDK (backend)->display;
 }
 
 /**
@@ -366,3 +442,9 @@ clutter_gdk_set_display (GdkDisplay *display)
 
   _foreign_dpy = g_object_ref (display);
 }
+
+GType
+_clutter_backend_impl_get_type (void)
+{
+  return _clutter_backend_gdk_get_type ();
+}
diff --git a/clutter/gdk/clutter-backend-gdk.h b/clutter/gdk/clutter-backend-gdk.h
index effa642..73d8de1 100644
--- a/clutter/gdk/clutter-backend-gdk.h
+++ b/clutter/gdk/clutter-backend-gdk.h
@@ -30,6 +30,7 @@
 #include "clutter-gdk.h"
 
 #include "clutter-backend-private.h"
+#include "cogl/clutter-backend-cogl.h"
 
 G_BEGIN_DECLS
 
@@ -45,7 +46,7 @@ typedef struct _ClutterBackendGdkClass  ClutterBackendGdkClass;
 
 struct _ClutterBackendGdk
 {
-  ClutterBackend parent_instance;
+  ClutterBackendCogl parent_instance;
 
   GdkDisplay *display;
   GdkScreen  *screen;
@@ -55,7 +56,7 @@ struct _ClutterBackendGdk
 
 struct _ClutterBackendGdkClass
 {
-  ClutterBackendClass parent_class;
+  ClutterBackendCoglClass parent_class;
 
   /* nothing here, for now */
 };
diff --git a/clutter/gdk/clutter-stage-gdk.c b/clutter/gdk/clutter-stage-gdk.c
index 600da64..2938a6a 100644
--- a/clutter/gdk/clutter-stage-gdk.c
+++ b/clutter/gdk/clutter-stage-gdk.c
@@ -27,6 +27,15 @@
 #include <unistd.h>
 #endif
 
+#include <cogl/cogl.h>
+#include <gdk/gdk.h>
+#ifdef GDK_WINDOWING_X11
+#include <gdk/gdkx.h>
+#endif
+#ifdef GDK_WINDOWING_WIN32
+#include <gdk/gdkwin32.h>
+#endif
+
 #include "clutter-backend-gdk.h"
 #include "clutter-stage-gdk.h"
 #include "clutter-gdk.h"
@@ -43,29 +52,22 @@
 #include "clutter-private.h"
 #include "clutter-stage-private.h"
 
-#include "cogl/cogl.h"
-
 static void clutter_stage_window_iface_init     (ClutterStageWindowIface     *iface);
 
+static ClutterStageWindowIface *clutter_stage_window_parent_iface = NULL;
+
 #define clutter_stage_gdk_get_type      _clutter_stage_gdk_get_type
 
 G_DEFINE_TYPE_WITH_CODE (ClutterStageGdk,
                          clutter_stage_gdk,
-                         G_TYPE_OBJECT,
+                         CLUTTER_TYPE_STAGE_COGL,
                          G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_STAGE_WINDOW,
                                                 clutter_stage_window_iface_init));
 
-enum {
-  PROP_0,
-  PROP_WRAPPER,
-  PROP_BACKEND,
-  PROP_LAST
-};
-
-void
-_clutter_stage_gdk_update_foreign_event_mask (CoglOnscreen *onscreen,
-					      guint32 event_mask,
-					      void *user_data)
+static void
+clutter_stage_gdk_update_foreign_event_mask (CoglOnscreen *onscreen,
+					     guint32 event_mask,
+					     void *user_data)
 {
   ClutterStageGdk *stage_gdk = user_data;
 
@@ -79,7 +81,8 @@ static void
 clutter_stage_gdk_set_gdk_geometry (ClutterStageGdk *stage)
 {
   GdkGeometry geometry;
-  gboolean resize = clutter_stage_get_user_resizable (stage->wrapper);
+  ClutterStage *wrapper = CLUTTER_STAGE_COGL (stage)->wrapper;
+  gboolean resize = clutter_stage_get_user_resizable (wrapper);
 
   if (!resize)
     {
@@ -92,7 +95,7 @@ clutter_stage_gdk_set_gdk_geometry (ClutterStageGdk *stage)
     }
   else
     {
-      clutter_stage_get_minimum_size (stage->wrapper,
+      clutter_stage_get_minimum_size (wrapper,
 				      (guint *)&geometry.min_width,
 				      (guint *)&geometry.min_height);
 
@@ -108,7 +111,7 @@ clutter_stage_gdk_get_geometry (ClutterStageWindow *stage_window,
 {
   ClutterStageGdk *stage_gdk = CLUTTER_STAGE_GDK (stage_window);
 
-  if (stage_gdk->window)
+  if (stage_gdk->window != NULL)
     {
       geometry->width = gdk_window_get_width (stage_gdk->window);
       geometry->height = gdk_window_get_height (stage_gdk->window);
@@ -139,7 +142,7 @@ clutter_stage_gdk_resize (ClutterStageWindow *stage_window,
 
   CLUTTER_NOTE (BACKEND, "New size received: (%d, %d)", width, height);
 
-  CLUTTER_SET_PRIVATE_FLAGS (stage_gdk->wrapper,
+  CLUTTER_SET_PRIVATE_FLAGS (CLUTTER_STAGE_COGL (stage_gdk)->wrapper,
 			     CLUTTER_IN_RESIZE);
 
   gdk_window_resize (stage_gdk->window, width, height);
@@ -150,7 +153,7 @@ clutter_stage_gdk_unrealize (ClutterStageWindow *stage_window)
 {
   ClutterStageGdk *stage_gdk = CLUTTER_STAGE_GDK (stage_window);
 
-  if (stage_gdk->window)
+  if (stage_gdk->window != NULL)
     {
       g_object_set_data (G_OBJECT (stage_gdk->window),
 			 "clutter-stage-window", NULL);
@@ -166,20 +169,22 @@ static gboolean
 clutter_stage_gdk_realize (ClutterStageWindow *stage_window)
 {
   ClutterStageGdk *stage_gdk = CLUTTER_STAGE_GDK (stage_window);
-  ClutterBackendGdk *backend_gdk = stage_gdk->backend;
+  ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
+  ClutterBackend *backend = CLUTTER_BACKEND (stage_cogl->backend);
+  ClutterBackendGdk *backend_gdk = CLUTTER_BACKEND_GDK (backend);
   GdkWindowAttr attributes;
   gboolean cursor_visible;
   gboolean use_alpha;
   gfloat   width, height;
 
   if (stage_gdk->foreign_window &&
-      stage_gdk->window)
+      stage_gdk->window != NULL)
     {
       /* complete realizing the stage */
       ClutterGeometry geometry;
 
       clutter_stage_gdk_get_geometry (stage_window, &geometry);
-      clutter_actor_set_geometry (CLUTTER_ACTOR (stage_gdk->wrapper), &geometry);
+      clutter_actor_set_geometry (CLUTTER_ACTOR (stage_cogl->wrapper), &geometry);
 
       gdk_window_ensure_native (stage_gdk->window);
       gdk_window_set_events (stage_gdk->window,
@@ -189,7 +194,7 @@ clutter_stage_gdk_realize (ClutterStageWindow *stage_window)
     }
 
   attributes.title = NULL;
-  g_object_get (stage_gdk->wrapper,
+  g_object_get (stage_cogl->wrapper,
 		"cursor-visible", &cursor_visible,
 		"title", &attributes.title,
 		"width", &width,
@@ -212,14 +217,16 @@ clutter_stage_gdk_realize (ClutterStageWindow *stage_window)
       attributes.cursor = stage_gdk->blank_cursor;
     }
 
+  attributes.visual = NULL;
   if (use_alpha)
     {
       attributes.visual = gdk_screen_get_rgba_visual (backend_gdk->screen);
 
       if (attributes.visual == NULL)
-	clutter_stage_set_use_alpha (stage_gdk->wrapper, FALSE);
+	clutter_stage_set_use_alpha (stage_cogl->wrapper, FALSE);
     }
-  else
+
+  if (attributes.visual == NULL)
     {
       /* This could still be an RGBA visual, although normally it's not */
       attributes.visual = gdk_screen_get_system_visual (backend_gdk->screen);
@@ -228,12 +235,8 @@ clutter_stage_gdk_realize (ClutterStageWindow *stage_window)
   if (stage_gdk->window != NULL)
     {
       g_critical ("Stage realized more than once");
-      g_object_set_data (G_OBJECT (stage_gdk->window),
-			 "clutter-stage-window", NULL);
-      if (stage_gdk->foreign_window)
-	g_object_unref (stage_gdk->window);
-      else
-	gdk_window_destroy (stage_gdk->window);
+
+      return FALSE;
     }
 
   stage_gdk->foreign_window = FALSE;
@@ -248,9 +251,41 @@ clutter_stage_gdk_realize (ClutterStageWindow *stage_window)
 
   g_free (attributes.title);
 
-  CLUTTER_NOTE (BACKEND, "Successfully realized stage");
+  stage_cogl->onscreen = cogl_onscreen_new (backend->cogl_context,
+					    width, height);
 
-  return TRUE;
+#if defined(GDK_WINDOWING_X11) && defined(COGL_HAS_XLIB_SUPPORT)
+  if (GDK_IS_X11_WINDOW (stage_gdk->window))
+    {
+      cogl_x11_onscreen_set_foreign_window_xid (stage_cogl->onscreen,
+                                                GDK_WINDOW_XID (stage_gdk->window),
+                                                clutter_stage_gdk_update_foreign_event_mask,
+                                                stage_gdk);
+    }
+  else
+#endif
+#if defined(GDK_WINDOWING_WIN32) && defined(COGL_HAS_WIN32_SUPPORT)
+  if (GDK_IS_WIN32_WINDOW (stage_gdk->window))
+    {
+      cogl_win32_onscreen_set_foreign_window (stage_cogl->onscreen,
+					      gdk_win32_window_get_handle (stage_gdk->window));
+    }
+  else
+#endif
+    {
+      g_warning ("Cannot find an appropriate CoglWinsys for a "
+		 "GdkWindow of type %s", G_OBJECT_TYPE_NAME (stage_gdk->window));
+
+      cogl_object_unref (stage_cogl->onscreen);
+      stage_cogl->onscreen = NULL;
+
+      gdk_window_destroy (stage_gdk->window);
+      stage_gdk->window = NULL;
+
+      return FALSE;
+    }
+
+  return clutter_stage_window_parent_iface->realize (stage_window);
 }
 
 static void
@@ -258,7 +293,7 @@ clutter_stage_gdk_set_fullscreen (ClutterStageWindow *stage_window,
                                   gboolean            is_fullscreen)
 {
   ClutterStageGdk *stage_gdk = CLUTTER_STAGE_GDK (stage_window);
-  ClutterStage *stage = stage_gdk->wrapper;
+  ClutterStage *stage = CLUTTER_STAGE_COGL (stage_window)->wrapper;
 
   if (stage == NULL || CLUTTER_ACTOR_IN_DESTRUCTION (stage))
     return;
@@ -347,7 +382,7 @@ clutter_stage_gdk_show (ClutterStageWindow *stage_window,
 
   g_return_if_fail (stage_gdk->window != NULL);
 
-  clutter_actor_map (CLUTTER_ACTOR (stage_gdk->wrapper));
+  clutter_actor_map (CLUTTER_ACTOR (CLUTTER_STAGE_COGL (stage_gdk)->wrapper));
 
   if (do_raise)
     gdk_window_show (stage_gdk->window);
@@ -362,22 +397,16 @@ clutter_stage_gdk_hide (ClutterStageWindow *stage_window)
 
   g_return_if_fail (stage_gdk->window != NULL);
 
-  clutter_actor_unmap (CLUTTER_ACTOR (stage_gdk->wrapper));
+  clutter_actor_unmap (CLUTTER_ACTOR (CLUTTER_STAGE_COGL (stage_gdk)->wrapper));
   gdk_window_hide (stage_gdk->window);
 }
 
-static ClutterActor *
-clutter_stage_gdk_get_wrapper (ClutterStageWindow *stage_window)
-{
-  return CLUTTER_ACTOR (CLUTTER_STAGE_GDK (stage_window)->wrapper);
-}
-
 static void
 clutter_stage_gdk_dispose (GObject *gobject)
 {
   ClutterStageGdk *stage_gdk = CLUTTER_STAGE_GDK (gobject);
 
-  if (stage_gdk->window)
+  if (stage_gdk->window != NULL)
     {
       g_object_set_data (G_OBJECT (stage_gdk->window),
 			 "clutter-stage-window", NULL);
@@ -388,7 +417,7 @@ clutter_stage_gdk_dispose (GObject *gobject)
       stage_gdk->window = NULL;
     }
 
-  if (stage_gdk->blank_cursor)
+  if (stage_gdk->blank_cursor != NULL)
     {
       g_object_unref (stage_gdk->blank_cursor);
       stage_gdk->blank_cursor = NULL;
@@ -398,50 +427,11 @@ clutter_stage_gdk_dispose (GObject *gobject)
 }
 
 static void
-clutter_stage_gdk_set_property (GObject      *gobject,
-				guint         prop_id,
-				const GValue *value,
-				GParamSpec   *pspec)
-{
-  ClutterStageGdk *self = CLUTTER_STAGE_GDK (gobject);
-
-  switch (prop_id)
-    {
-    case PROP_WRAPPER:
-      self->wrapper = CLUTTER_STAGE (g_value_get_object (value));
-      break;
-
-    case PROP_BACKEND:
-      self->backend = CLUTTER_BACKEND_GDK (g_value_get_object (value));
-      break;
-
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
-      break;
-    }
-}
-
-static void
 clutter_stage_gdk_class_init (ClutterStageGdkClass *klass)
 {
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 
   gobject_class->dispose = clutter_stage_gdk_dispose;
-  gobject_class->set_property = clutter_stage_gdk_set_property;
-
-  g_object_class_install_property (gobject_class, PROP_WRAPPER,
-				   g_param_spec_object ("wrapper",
-							"Wrapper",
-							"ClutterStage wrapping this native stage",
-							CLUTTER_TYPE_STAGE,
-							CLUTTER_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
-
-  g_object_class_install_property (gobject_class, PROP_BACKEND,
-				   g_param_spec_object ("backend",
-							"ClutterBackend",
-							"The Clutter backend singleton",
-							CLUTTER_TYPE_BACKEND_GDK,
-							CLUTTER_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
 }
 
 static void
@@ -453,7 +443,8 @@ clutter_stage_gdk_init (ClutterStageGdk *stage)
 static void
 clutter_stage_window_iface_init (ClutterStageWindowIface *iface)
 {
-  iface->get_wrapper = clutter_stage_gdk_get_wrapper;
+  clutter_stage_window_parent_iface = g_type_interface_peek_parent (iface);
+
   iface->set_title = clutter_stage_gdk_set_title;
   iface->set_fullscreen = clutter_stage_gdk_set_fullscreen;
   iface->set_cursor_visible = clutter_stage_gdk_set_cursor_visible;
@@ -507,7 +498,7 @@ clutter_gdk_get_stage_from_window (GdkWindow *window)
   ClutterStageGdk *stage_gdk = g_object_get_data (G_OBJECT (window), "clutter-stage-window");
 
   if (stage_gdk != NULL && CLUTTER_IS_STAGE_GDK (stage_gdk))
-    return stage_gdk->wrapper;
+    return CLUTTER_STAGE_COGL (stage_gdk)->wrapper;
 
   return NULL;
 }
diff --git a/clutter/gdk/clutter-stage-gdk.h b/clutter/gdk/clutter-stage-gdk.h
index 38cf399..8c4cb20 100644
--- a/clutter/gdk/clutter-stage-gdk.h
+++ b/clutter/gdk/clutter-stage-gdk.h
@@ -28,6 +28,7 @@
 #include <gdk/gdk.h>
 
 #include "clutter-backend-gdk.h"
+#include "cogl/clutter-stage-cogl.h"
 
 G_BEGIN_DECLS
 
@@ -43,21 +44,17 @@ typedef struct _ClutterStageGdkClass    ClutterStageGdkClass;
 
 struct _ClutterStageGdk
 {
-  GObject parent_instance;
+  ClutterStageCogl parent_instance;
 
   GdkWindow *window;
   GdkCursor *blank_cursor;
 
-  /* backpointers */
-  ClutterStage *wrapper;
-  ClutterBackendGdk *backend;
-
   gboolean foreign_window;
 };
 
 struct _ClutterStageGdkClass
 {
-  GObjectClass parent_class;
+  ClutterStageCoglClass parent_class;
 };
 
 #define CLUTTER_STAGE_GDK_EVENT_MASK \
diff --git a/clutter/x11/clutter-backend-x11.c b/clutter/x11/clutter-backend-x11.c
index ab1cde2..483205d 100644
--- a/clutter/x11/clutter-backend-x11.c
+++ b/clutter/x11/clutter-backend-x11.c
@@ -69,7 +69,7 @@
 
 #define clutter_backend_x11_get_type    _clutter_backend_x11_get_type
 
-G_DEFINE_TYPE (ClutterBackendX11, clutter_backend_x11, CLUTTER_TYPE_BACKEND);
+G_DEFINE_TYPE (ClutterBackendX11, clutter_backend_x11, CLUTTER_TYPE_BACKEND_COGL);
 
 /* atoms; remember to add the code that assigns the atom value to
  * the member of the ClutterBackendX11 structure if you add an
@@ -91,9 +91,6 @@ static const gchar *atom_names[] = {
 
 #define N_ATOM_NAMES G_N_ELEMENTS (atom_names)
 
-/* singleton object */
-static ClutterBackendX11 *backend_singleton = NULL;
-
 /* various flags corresponding to pre init setup calls */
 static gboolean _no_xevent_retrieval = FALSE;
 static gboolean clutter_enable_xinput = FALSE;
@@ -333,7 +330,8 @@ _clutter_backend_x11_pre_parse (ClutterBackend  *backend,
       env_string = NULL;
     }
 
-  return TRUE;
+  return CLUTTER_BACKEND_CLASS (clutter_backend_x11_parent_class)->pre_parse (backend,
+									      error);
 }
 
 gboolean
@@ -461,7 +459,8 @@ _clutter_backend_x11_post_parse (ClutterBackend  *backend,
                 (unsigned int) backend_x11->xwin_root,
                 clutter_backend_get_resolution (backend));
 
-  return TRUE;
+  return CLUTTER_BACKEND_CLASS (clutter_backend_x11_parent_class)->post_parse (backend,
+									       error);
 }
 
 
@@ -525,9 +524,6 @@ clutter_backend_x11_finalize (GObject *gobject)
 
   XCloseDisplay (backend_x11->xdpy);
 
-  if (backend_singleton)
-    backend_singleton = NULL;
-
   G_OBJECT_CLASS (clutter_backend_x11_parent_class)->finalize (gobject);
 }
 
@@ -548,34 +544,14 @@ clutter_backend_x11_dispose (GObject *gobject)
   G_OBJECT_CLASS (clutter_backend_x11_parent_class)->dispose (gobject);
 }
 
-static GObject *
-clutter_backend_x11_constructor (GType                  gtype,
-                                 guint                  n_params,
-                                 GObjectConstructParam *params)
-{
-  GObjectClass *parent_class;
-  GObject *retval;
-
-  if (backend_singleton == NULL)
-    {
-      parent_class = G_OBJECT_CLASS (clutter_backend_x11_parent_class);
-      retval = parent_class->constructor (gtype, n_params, params);
-
-      backend_singleton = CLUTTER_BACKEND_X11 (retval);
-
-      return retval;
-    }
-
-  g_warning ("Attempting to create a new backend object. This should "
-             "never happen, so we return the singleton instance.");
-
-  return g_object_ref (backend_singleton);
-}
-
 static ClutterFeatureFlags
 clutter_backend_x11_get_features (ClutterBackend *backend)
 {
-  return CLUTTER_FEATURE_STAGE_USER_RESIZE | CLUTTER_FEATURE_STAGE_CURSOR;
+  ClutterFeatureFlags flags = CLUTTER_FEATURE_STAGE_USER_RESIZE | CLUTTER_FEATURE_STAGE_CURSOR;
+
+  flags |= CLUTTER_BACKEND_CLASS (clutter_backend_x11_parent_class)->get_features (backend);
+
+  return flags;
 }
 
 static void
@@ -705,13 +681,105 @@ clutter_backend_x11_translate_event (ClutterBackend *backend,
   return parent_class->translate_event (backend, native, event);
 }
 
+static gboolean
+clutter_backend_x11_create_context (ClutterBackend  *backend,
+				    GError         **error)
+{
+  ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend);
+  CoglSwapChain *swap_chain = NULL;
+  CoglOnscreenTemplate *onscreen_template = NULL;
+
+  if (backend->cogl_context != NULL)
+    return TRUE;
+
+  backend->cogl_renderer = cogl_renderer_new ();
+  cogl_xlib_renderer_set_foreign_display (backend->cogl_renderer,
+                                          backend_x11->xdpy);
+  if (!cogl_renderer_connect (backend->cogl_renderer, error))
+    goto error;
+
+  swap_chain = cogl_swap_chain_new ();
+  cogl_swap_chain_set_has_alpha (swap_chain,
+                                 clutter_x11_get_use_argb_visual ());
+
+  onscreen_template = cogl_onscreen_template_new (swap_chain);
+  cogl_object_unref (swap_chain);
+
+  /* XXX: I have some doubts that this is a good design.
+   * Conceptually should we be able to check an onscreen_template
+   * without more details about the CoglDisplay configuration?
+   */
+  if (!cogl_renderer_check_onscreen_template (backend->cogl_renderer,
+                                              onscreen_template,
+                                              error))
+    goto error;
+
+  backend->cogl_display = cogl_display_new (backend->cogl_renderer,
+                                            onscreen_template);
+
+  cogl_object_unref (backend->cogl_renderer);
+  cogl_object_unref (onscreen_template);
+
+  if (!cogl_display_setup (backend->cogl_display, error))
+    goto error;
+
+  backend->cogl_context = cogl_context_new (backend->cogl_display, error);
+  if (backend->cogl_context == NULL)
+    goto error;
+
+  return TRUE;
+
+error:
+  if (backend->cogl_display != NULL)
+    {
+      cogl_object_unref (backend->cogl_display);
+      backend->cogl_display = NULL;
+    }
+
+  if (onscreen_template != NULL)
+    cogl_object_unref (onscreen_template);
+  if (swap_chain != NULL)
+    cogl_object_unref (swap_chain);
+
+  if (backend->cogl_renderer != NULL)
+    {
+      cogl_object_unref (backend->cogl_renderer);
+      backend->cogl_renderer = NULL;
+    }
+  return FALSE;
+}
+
+static ClutterStageWindow *
+clutter_backend_x11_create_stage (ClutterBackend  *backend,
+				  ClutterStage    *wrapper,
+				  GError         **error)
+{
+  ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend);
+  ClutterEventTranslator *translator;
+  ClutterStageWindow *stage;
+
+  stage = g_object_new (CLUTTER_TYPE_STAGE_X11,
+			"backend", backend,
+			"wrapper", wrapper,
+			NULL);
+
+  translator = CLUTTER_EVENT_TRANSLATOR (stage);
+  _clutter_backend_add_event_translator (backend, translator);
+
+  CLUTTER_NOTE (MISC, "Cogl stage created (display:%p, screen:%d, root:%u)",
+                backend_x11->xdpy,
+                backend_x11->xscreen_num,
+                (unsigned int) backend_x11->xwin_root);
+
+  return stage;
+}
+
 static void
 clutter_backend_x11_class_init (ClutterBackendX11Class *klass)
 {
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
   ClutterBackendClass *backend_class = CLUTTER_BACKEND_CLASS (klass);
 
-  gobject_class->constructor = clutter_backend_x11_constructor;
   gobject_class->dispose = clutter_backend_x11_dispose;
   gobject_class->finalize = clutter_backend_x11_finalize;
 
@@ -724,6 +792,8 @@ clutter_backend_x11_class_init (ClutterBackendX11Class *klass)
   backend_class->copy_event_data = clutter_backend_x11_copy_event_data;
   backend_class->free_event_data = clutter_backend_x11_free_event_data;
   backend_class->translate_event = clutter_backend_x11_translate_event;
+  backend_class->create_context = clutter_backend_x11_create_context;
+  backend_class->create_stage = clutter_backend_x11_create_stage;
 }
 
 static void
@@ -783,13 +853,15 @@ clutter_x11_untrap_x_errors (void)
 Display *
 clutter_x11_get_default_display (void)
 {
-  if (!backend_singleton)
+  ClutterBackend *backend = clutter_get_default_backend ();
+
+  if (!backend || !CLUTTER_IS_BACKEND_X11 (backend))
     {
       g_critical ("X11 backend has not been initialised");
       return NULL;
     }
 
-  return backend_singleton->xdpy;
+  return CLUTTER_BACKEND_X11 (backend)->xdpy;
 }
 
 /**
@@ -912,13 +984,15 @@ clutter_x11_has_event_retrieval (void)
 int
 clutter_x11_get_default_screen (void)
 {
-  if (!backend_singleton)
+ ClutterBackend *backend = clutter_get_default_backend ();
+
+  if (!backend || !CLUTTER_IS_BACKEND_X11 (backend))
     {
       g_critical ("X11 backend has not been initialised");
       return 0;
     }
 
-  return backend_singleton->xscreen_num;
+  return CLUTTER_BACKEND_X11 (backend)->xscreen_num;
 }
 
 /**
@@ -933,13 +1007,15 @@ clutter_x11_get_default_screen (void)
 Window
 clutter_x11_get_root_window (void)
 {
-  if (!backend_singleton)
+ ClutterBackend *backend = clutter_get_default_backend ();
+
+  if (!backend || !CLUTTER_IS_BACKEND_X11 (backend))
     {
       g_critical ("X11 backend has not been initialised");
       return None;
     }
 
-  return backend_singleton->xwin_root;
+  return CLUTTER_BACKEND_X11 (backend)->xwin_root;
 }
 
 /**
@@ -956,21 +1032,25 @@ clutter_x11_add_filter (ClutterX11FilterFunc func,
                         gpointer             data)
 {
   ClutterX11EventFilter *filter;
+  ClutterBackend *backend = clutter_get_default_backend ();
+  ClutterBackendX11 *backend_x11;
 
   g_return_if_fail (func != NULL);
 
-  if (!backend_singleton)
+  if (!backend || !CLUTTER_IS_BACKEND_X11 (backend))
     {
       g_critical ("X11 backend has not been initialised");
       return;
     }
 
+  backend_x11 = CLUTTER_BACKEND_X11 (backend);
+
   filter = g_new0 (ClutterX11EventFilter, 1);
   filter->func = func;
   filter->data = data;
 
-  backend_singleton->event_filters =
-    g_slist_append (backend_singleton->event_filters, filter);
+  backend_x11->event_filters =
+    g_slist_append (backend_x11->event_filters, filter);
 
   return;
 }
@@ -990,10 +1070,20 @@ clutter_x11_remove_filter (ClutterX11FilterFunc func,
 {
   GSList                *tmp_list, *this;
   ClutterX11EventFilter *filter;
+  ClutterBackend *backend = clutter_get_default_backend ();
+  ClutterBackendX11 *backend_x11;
 
   g_return_if_fail (func != NULL);
 
-  tmp_list = backend_singleton->event_filters;
+  if (!backend || !CLUTTER_IS_BACKEND_X11 (backend))
+    {
+      g_critical ("X11 backend has not been initialised");
+      return;
+    }
+
+  backend_x11 = CLUTTER_BACKEND_X11 (backend);
+
+  tmp_list = backend_x11->event_filters;
 
   while (tmp_list)
     {
@@ -1003,8 +1093,8 @@ clutter_x11_remove_filter (ClutterX11FilterFunc func,
 
       if (filter->func == func && filter->data == data)
         {
-          backend_singleton->event_filters =
-            g_slist_remove_link (backend_singleton->event_filters, this);
+          backend_x11->event_filters =
+            g_slist_remove_link (backend_x11->event_filters, this);
 
           g_slist_free_1 (this);
           g_free (filter);
@@ -1051,10 +1141,15 @@ gboolean
 clutter_x11_has_xinput (void)
 {
 #if defined(HAVE_XINPUT) || defined(HAVE_XINPUT_2)
-  if (backend_singleton != NULL)
-    return backend_singleton->has_xinput;
+ ClutterBackend *backend = clutter_get_default_backend ();
 
-  return FALSE;
+  if (!backend || !CLUTTER_IS_BACKEND_X11 (backend))
+    {
+      g_critical ("X11 backend has not been initialised");
+      return FALSE;
+    }
+
+  return CLUTTER_BACKEND_X11 (backend)->has_xinput;
 #else
   return FALSE;
 #endif
@@ -1158,15 +1253,7 @@ clutter_x11_get_use_argb_visual (void)
 XVisualInfo *
 _clutter_backend_x11_get_visual_info (ClutterBackendX11 *backend_x11)
 {
-  ClutterBackendX11Class *klass;
-
-  g_return_val_if_fail (CLUTTER_IS_BACKEND_X11 (backend_x11), NULL);
-
-  klass = CLUTTER_BACKEND_X11_GET_CLASS (backend_x11);
-  if (klass->get_visual_info)
-    return klass->get_visual_info (backend_x11);
-
-  return NULL;
+  return cogl_clutter_winsys_xlib_get_visual_info ();
 }
 
 /**
@@ -1241,3 +1328,9 @@ _clutter_x11_input_device_translate_screen_coord (ClutterInputDevice *device,
 
   return TRUE;
 }
+
+GType
+_clutter_backend_impl_get_type (void)
+{
+  return _clutter_backend_x11_get_type ();
+}
diff --git a/clutter/x11/clutter-backend-x11.h b/clutter/x11/clutter-backend-x11.h
index 0c4a5d8..7013285 100644
--- a/clutter/x11/clutter-backend-x11.h
+++ b/clutter/x11/clutter-backend-x11.h
@@ -31,6 +31,7 @@
 
 #include "clutter-backend-private.h"
 #include "clutter-keymap-x11.h"
+#include "cogl/clutter-backend-cogl.h"
 
 #include "xsettings/xsettings-client.h"
 
@@ -67,7 +68,7 @@ struct _ClutterEventX11
 
 struct _ClutterBackendX11
 {
-  ClutterBackend parent_instance;
+  ClutterBackendCogl parent_instance;
 
   Display *xdpy;
   gchar   *display_name;
@@ -112,14 +113,7 @@ struct _ClutterBackendX11
 
 struct _ClutterBackendX11Class
 {
-  ClutterBackendClass parent_class;
-
-  /*
-   * To support foreign stage windows the we need a way to ask for an
-   * XVisualInfo that may be used by toolkits to create an XWindow, and this
-   * may need to be handled differently for different backends.
-   */
-  XVisualInfo *(* get_visual_info) (ClutterBackendX11 *backend);
+  ClutterBackendCoglClass parent_class;
 };
 
 void   _clutter_backend_x11_events_init (ClutterBackend *backend);
diff --git a/clutter/cogl/clutter-glx-texture-pixmap.c b/clutter/x11/clutter-glx-texture-pixmap.c
similarity index 100%
rename from clutter/cogl/clutter-glx-texture-pixmap.c
rename to clutter/x11/clutter-glx-texture-pixmap.c
diff --git a/clutter/cogl/clutter-glx-texture-pixmap.h b/clutter/x11/clutter-glx-texture-pixmap.h
similarity index 100%
rename from clutter/cogl/clutter-glx-texture-pixmap.h
rename to clutter/x11/clutter-glx-texture-pixmap.h
diff --git a/clutter/cogl/clutter-glx.h b/clutter/x11/clutter-glx.h
similarity index 100%
rename from clutter/cogl/clutter-glx.h
rename to clutter/x11/clutter-glx.h
diff --git a/clutter/x11/clutter-stage-x11.c b/clutter/x11/clutter-stage-x11.c
index 410afd7..b2ac9df 100644
--- a/clutter/x11/clutter-stage-x11.c
+++ b/clutter/x11/clutter-stage-x11.c
@@ -27,6 +27,8 @@
 #include <unistd.h>
 #endif
 
+#include <cogl/cogl.h>
+
 #include "clutter-backend-x11.h"
 #include "clutter-stage-x11.h"
 #include "clutter-x11.h"
@@ -43,14 +45,14 @@
 #include "clutter-private.h"
 #include "clutter-stage-private.h"
 
-#include "cogl/cogl.h"
-
 #ifdef HAVE_XFIXES
 #include <X11/extensions/Xfixes.h>
 #endif
 
 #define STAGE_X11_IS_MAPPED(s)  ((((ClutterStageX11 *) (s))->wm_state & STAGE_X11_WITHDRAWN) == 0)
 
+static ClutterStageWindowIface *clutter_stage_window_parent_iface = NULL;
+
 static void clutter_stage_window_iface_init     (ClutterStageWindowIface     *iface);
 static void clutter_event_translator_iface_init (ClutterEventTranslatorIface *iface);
 
@@ -60,7 +62,7 @@ static GHashTable *clutter_stages_by_xid = NULL;
 
 G_DEFINE_TYPE_WITH_CODE (ClutterStageX11,
                          clutter_stage_x11,
-                         G_TYPE_OBJECT,
+                         CLUTTER_TYPE_STAGE_COGL,
                          G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_STAGE_WINDOW,
                                                 clutter_stage_window_iface_init)
                          G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_EVENT_TRANSLATOR,
@@ -129,7 +131,8 @@ clutter_stage_x11_fix_window_size (ClutterStageX11 *stage_x11,
                                    gint             new_width,
                                    gint             new_height)
 {
-  ClutterBackendX11 *backend_x11 = stage_x11->backend;
+  ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_x11);
+  ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (stage_cogl->backend);
 
   if (stage_x11->xwin != None && !stage_x11->is_foreign_xwin)
     {
@@ -137,11 +140,11 @@ clutter_stage_x11_fix_window_size (ClutterStageX11 *stage_x11,
       XSizeHints *size_hints;
       gboolean resize;
 
-      resize = clutter_stage_get_user_resizable (stage_x11->wrapper);
+      resize = clutter_stage_get_user_resizable (stage_cogl->wrapper);
 
       size_hints = XAllocSizeHints();
 
-      clutter_stage_get_minimum_size (stage_x11->wrapper,
+      clutter_stage_get_minimum_size (stage_cogl->wrapper,
                                       &min_width,
                                       &min_height);
 
@@ -182,7 +185,8 @@ clutter_stage_x11_fix_window_size (ClutterStageX11 *stage_x11,
 static void
 clutter_stage_x11_set_wm_protocols (ClutterStageX11 *stage_x11)
 {
-  ClutterBackendX11 *backend_x11 = stage_x11->backend;
+  ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_x11);
+  ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (stage_cogl->backend);
   Atom protocols[2];
   int n = 0;
   
@@ -197,7 +201,8 @@ clutter_stage_x11_get_geometry (ClutterStageWindow    *stage_window,
                                 cairo_rectangle_int_t *geometry)
 {
   ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
-  ClutterBackendX11 *backend_x11 = stage_x11->backend;
+  ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_x11);
+  ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (stage_cogl->backend);
 
   /* If we're fullscreen, return the size of the display. */
   if ((stage_x11->state & CLUTTER_STAGE_STATE_FULLSCREEN) &&
@@ -219,7 +224,8 @@ clutter_stage_x11_resize (ClutterStageWindow *stage_window,
                           gint                height)
 {
   ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
-  ClutterBackendX11 *backend_x11 = stage_x11->backend;
+  ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_x11);
+  ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (stage_cogl->backend);
 
   if (stage_x11->is_foreign_xwin)
     {
@@ -229,7 +235,7 @@ clutter_stage_x11_resize (ClutterStageWindow *stage_window,
        */
       stage_x11->xwin_width = width;
       stage_x11->xwin_height = height;
-      clutter_actor_queue_relayout (CLUTTER_ACTOR (stage_x11->wrapper));
+      clutter_actor_queue_relayout (CLUTTER_ACTOR (stage_cogl->wrapper));
       return;
     }
 
@@ -262,7 +268,7 @@ clutter_stage_x11_resize (ClutterStageWindow *stage_window,
                         width,
                         height);
 
-          CLUTTER_SET_PRIVATE_FLAGS (stage_x11->wrapper,
+          CLUTTER_SET_PRIVATE_FLAGS (stage_cogl->wrapper,
                                      CLUTTER_IN_RESIZE);
 
           /* XXX: in this case we can rely on a subsequent
@@ -280,7 +286,8 @@ clutter_stage_x11_resize (ClutterStageWindow *stage_window,
 static inline void
 set_wm_pid (ClutterStageX11 *stage_x11)
 {
-  ClutterBackendX11 *backend_x11 = stage_x11->backend;
+  ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_x11);
+  ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (stage_cogl->backend);
   long pid;
 
   if (stage_x11->xwin == None || stage_x11->is_foreign_xwin)
@@ -304,7 +311,8 @@ set_wm_pid (ClutterStageX11 *stage_x11)
 static inline void
 set_wm_title (ClutterStageX11 *stage_x11)
 {
-  ClutterBackendX11 *backend_x11 = stage_x11->backend;
+  ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_x11);
+  ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (stage_cogl->backend);
 
   if (stage_x11->xwin == None || stage_x11->is_foreign_xwin)
     return;
@@ -331,7 +339,8 @@ set_wm_title (ClutterStageX11 *stage_x11)
 static inline void
 set_cursor_visible (ClutterStageX11 *stage_x11)
 {
-  ClutterBackendX11 *backend_x11 = stage_x11->backend;
+  ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_x11);
+  ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (stage_cogl->backend);
 
   if (stage_x11->xwin == None)
     return;
@@ -385,6 +394,8 @@ clutter_stage_x11_unrealize (ClutterStageWindow *stage_window)
       g_hash_table_remove (clutter_stages_by_xid,
                            GINT_TO_POINTER (stage_x11->xwin));
     }
+
+  clutter_stage_window_parent_iface->unrealize (stage_window);
 }
 
 void
@@ -393,7 +404,8 @@ _clutter_stage_x11_update_foreign_event_mask (CoglOnscreen *onscreen,
                                               void *user_data)
 {
   ClutterStageX11 *stage_x11 = user_data;
-  ClutterBackendX11 *backend_x11 = stage_x11->backend;
+  ClutterStageCogl *stage_cogl = user_data;
+  ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (stage_cogl->backend);
   XSetWindowAttributes attrs;
 
   attrs.event_mask = event_mask | CLUTTER_STAGE_X11_EVENT_MASK;
@@ -408,9 +420,36 @@ static gboolean
 clutter_stage_x11_realize (ClutterStageWindow *stage_window)
 {
   ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
-  ClutterBackendX11 *backend_x11 = stage_x11->backend;
+  ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
+  ClutterBackend *backend = CLUTTER_BACKEND (stage_cogl->backend);
+  ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend);
   ClutterDeviceManager *device_manager;
   int event_flags;
+  gfloat width, height;
+
+  clutter_actor_get_size (CLUTTER_ACTOR (stage_cogl->wrapper),
+			  &width, &height);
+
+  stage_cogl->onscreen = cogl_onscreen_new (backend->cogl_context,
+                                            width, height);
+
+  if (stage_x11->xwin != None)
+    {
+      cogl_x11_onscreen_set_foreign_window_xid (stage_cogl->onscreen,
+                                                stage_x11->xwin,
+                                                _clutter_stage_x11_update_foreign_event_mask,
+                                                stage_x11);
+
+    }
+
+  /* Chain to the parent class now. ClutterStageCogl will call cogl_framebuffer_allocate,
+     which will create the X Window we need */
+
+  if (!(clutter_stage_window_parent_iface->realize (stage_window)))
+    return FALSE;
+
+  if (stage_x11->xwin == None)
+    stage_x11->xwin = cogl_x11_onscreen_get_window_xid (stage_cogl->onscreen);
 
   if (clutter_stages_by_xid == NULL)
     clutter_stages_by_xid = g_hash_table_new (NULL, NULL);
@@ -456,7 +495,7 @@ clutter_stage_x11_realize (ClutterStageWindow *stage_window)
    */
   device_manager = clutter_device_manager_get_default ();
   _clutter_device_manager_select_stage_events (device_manager,
-                                               stage_x11->wrapper,
+                                               stage_cogl->wrapper,
                                                event_flags);
 
   /* no user resize.. */
@@ -475,8 +514,9 @@ clutter_stage_x11_set_fullscreen (ClutterStageWindow *stage_window,
                                   gboolean            is_fullscreen)
 {
   ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
-  ClutterBackendX11 *backend_x11 = stage_x11->backend;
-  ClutterStage *stage = stage_x11->wrapper;
+  ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_x11);
+  ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (stage_cogl->backend);
+  ClutterStage *stage = stage_cogl->wrapper;
   gboolean was_fullscreen;
 
   if (stage == NULL || CLUTTER_ACTOR_IN_DESTRUCTION (stage))
@@ -611,7 +651,8 @@ clutter_stage_x11_set_user_resizable (ClutterStageWindow *stage_window,
 static inline void
 update_wm_hints (ClutterStageX11 *stage_x11)
 {
-  ClutterBackendX11 *backend_x11 = stage_x11->backend;
+  ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_x11);
+  ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (stage_cogl->backend);
   XWMHints wm_hints;
 
   if (stage_x11->wm_state & STAGE_X11_WITHDRAWN)
@@ -661,7 +702,8 @@ clutter_stage_x11_show (ClutterStageWindow *stage_window,
                         gboolean            do_raise)
 {
   ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
-  ClutterBackendX11 *backend_x11 = stage_x11->backend;
+  ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_x11);
+  ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (stage_cogl->backend);
 
   if (stage_x11->xwin != None)
     {
@@ -689,7 +731,7 @@ clutter_stage_x11_show (ClutterStageWindow *stage_window,
 
       g_assert (STAGE_X11_IS_MAPPED (stage_x11));
 
-      clutter_actor_map (CLUTTER_ACTOR (stage_x11->wrapper));
+      clutter_actor_map (CLUTTER_ACTOR (stage_cogl->wrapper));
 
       if (!stage_x11->is_foreign_xwin)
         XMapWindow (backend_x11->xdpy, stage_x11->xwin);
@@ -700,7 +742,8 @@ static void
 clutter_stage_x11_hide (ClutterStageWindow *stage_window)
 {
   ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
-  ClutterBackendX11 *backend_x11 = stage_x11->backend;
+  ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_x11);
+  ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (stage_cogl->backend);
 
   if (stage_x11->xwin != None)
     {
@@ -709,19 +752,13 @@ clutter_stage_x11_hide (ClutterStageWindow *stage_window)
 
       g_assert (!STAGE_X11_IS_MAPPED (stage_x11));
 
-      clutter_actor_unmap (CLUTTER_ACTOR (stage_x11->wrapper));
+      clutter_actor_unmap (CLUTTER_ACTOR (stage_cogl->wrapper));
 
       if (!stage_x11->is_foreign_xwin)
         XWithdrawWindow (backend_x11->xdpy, stage_x11->xwin, 0);
     }
 }
 
-static ClutterActor *
-clutter_stage_x11_get_wrapper (ClutterStageWindow *stage_window)
-{
-  return CLUTTER_ACTOR (CLUTTER_STAGE_X11 (stage_window)->wrapper);
-}
-
 static void
 clutter_stage_x11_finalize (GObject *gobject)
 {
@@ -736,7 +773,7 @@ static void
 clutter_stage_x11_dispose (GObject *gobject)
 {
   ClutterEventTranslator *translator = CLUTTER_EVENT_TRANSLATOR (gobject);
-  ClutterBackendX11 *backend = CLUTTER_STAGE_X11 (gobject)->backend;
+  ClutterBackendCogl *backend = CLUTTER_STAGE_COGL (gobject)->backend;
 
   _clutter_backend_remove_event_translator (CLUTTER_BACKEND (backend),
                                             translator);
@@ -768,14 +805,13 @@ clutter_stage_x11_init (ClutterStageX11 *stage)
   stage->accept_focus = TRUE;
 
   stage->title = NULL;
-
-  stage->wrapper = NULL;
 }
 
 static void
 clutter_stage_window_iface_init (ClutterStageWindowIface *iface)
 {
-  iface->get_wrapper = clutter_stage_x11_get_wrapper;
+  clutter_stage_window_parent_iface = g_type_interface_peek_parent (iface);
+
   iface->set_title = clutter_stage_x11_set_title;
   iface->set_fullscreen = clutter_stage_x11_set_fullscreen;
   iface->set_cursor_visible = clutter_stage_x11_set_cursor_visible;
@@ -810,6 +846,7 @@ handle_wm_protocols_event (ClutterBackendX11 *backend_x11,
                            ClutterStageX11   *stage_x11,
                            XEvent            *xevent)
 {
+  ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_x11);
   Atom atom = (Atom) xevent->xclient.data.l[0];
 
   if (atom == backend_x11->atom_WM_DELETE_WINDOW &&
@@ -821,8 +858,8 @@ handle_wm_protocols_event (ClutterBackendX11 *backend_x11,
        * handle the request
        */
       CLUTTER_NOTE (EVENT, "Delete stage %s[%p], win:0x%x",
-                    _clutter_actor_get_debug_name (CLUTTER_ACTOR (stage_x11->wrapper)),
-                    stage_x11->wrapper,
+                    _clutter_actor_get_debug_name (CLUTTER_ACTOR (stage_cogl->wrapper)),
+                    stage_cogl->wrapper,
                     (unsigned int) stage_x11->xwin);
 
       set_user_time (backend_x11, stage_x11, xevent->xclient.data.l[1]);
@@ -862,8 +899,9 @@ clutter_stage_x11_translate_event (ClutterEventTranslator *translator,
                                    ClutterEvent           *event)
 {
   ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (translator);
+  ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (translator);
   ClutterTranslateReturn res = CLUTTER_TRANSLATE_CONTINUE;
-  ClutterBackendX11 *backend_x11 = stage_x11->backend;
+  ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (stage_cogl->backend);
   Window stage_xwindow = stage_x11->xwin;
   XEvent *xevent = native;
   ClutterStage *stage;
@@ -901,7 +939,7 @@ clutter_stage_x11_translate_event (ClutterEventTranslator *translator,
                                   xevent->xconfigure.width,
                                   xevent->xconfigure.height);
 
-          CLUTTER_UNSET_PRIVATE_FLAGS (stage_x11->wrapper, CLUTTER_IN_RESIZE);
+          CLUTTER_UNSET_PRIVATE_FLAGS (stage_cogl->wrapper, CLUTTER_IN_RESIZE);
 
           if (size_changed)
             {
@@ -1171,16 +1209,16 @@ clutter_x11_get_stage_window (ClutterStage *stage)
 ClutterStage *
 clutter_x11_get_stage_from_window (Window win)
 {
-  ClutterStageX11 *stage_x11;
+  ClutterStageCogl *stage_cogl;
 
   if (clutter_stages_by_xid == NULL)
     return NULL;
 
-  stage_x11 = g_hash_table_lookup (clutter_stages_by_xid,
-                                   GINT_TO_POINTER (win));
+  stage_cogl = g_hash_table_lookup (clutter_stages_by_xid,
+				    GINT_TO_POINTER (win));
 
-  if (stage_x11 != NULL)
-    return stage_x11->wrapper;
+  if (stage_cogl != NULL)
+    return stage_cogl->wrapper;
 
   return NULL;
 }
@@ -1228,7 +1266,8 @@ set_foreign_window_callback (ClutterActor *actor,
                              void         *data)
 {
   ForeignWindowData *fwd = data;
-  ClutterBackendX11 *backend_x11 = fwd->stage_x11->backend;
+  ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (fwd->stage_x11);
+  ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (stage_cogl->backend);
 
   CLUTTER_NOTE (BACKEND, "Setting foreign window (0x%x)",
                 (unsigned int) fwd->xwindow);
@@ -1279,6 +1318,7 @@ clutter_x11_set_stage_foreign (ClutterStage *stage,
 {
   ClutterBackendX11 *backend_x11;
   ClutterStageX11 *stage_x11;
+  ClutterStageCogl *stage_cogl;
   ClutterStageWindow *impl;
   ClutterActor *actor;
   gint x, y;
@@ -1294,7 +1334,8 @@ clutter_x11_set_stage_foreign (ClutterStage *stage,
 
   impl = _clutter_stage_get_window (stage);
   stage_x11 = CLUTTER_STAGE_X11 (impl);
-  backend_x11 = stage_x11->backend;
+  stage_cogl = CLUTTER_STAGE_COGL (impl);
+  backend_x11 = CLUTTER_BACKEND_X11 (stage_cogl->backend);
 
   xvisinfo = _clutter_backend_x11_get_visual_info (backend_x11);
   g_return_val_if_fail (xvisinfo != NULL, FALSE);
@@ -1369,7 +1410,10 @@ void
 _clutter_stage_x11_set_user_time (ClutterStageX11 *stage_x11,
                                   guint32          user_time)
 {
-  set_user_time (stage_x11->backend, stage_x11, user_time);
+  ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_x11);
+  ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (stage_cogl->backend);
+
+  set_user_time (backend_x11, stage_x11, user_time);
 }
 
 gboolean
@@ -1377,7 +1421,8 @@ _clutter_stage_x11_get_root_coords (ClutterStageX11 *stage_x11,
                                     gint            *root_x,
                                     gint            *root_y)
 {
-  ClutterBackendX11 *backend_x11 = stage_x11->backend;
+  ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_x11);
+  ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (stage_cogl->backend);
   gint return_val;
   Window child;
   gint tx, ty;
diff --git a/clutter/x11/clutter-stage-x11.h b/clutter/x11/clutter-stage-x11.h
index a070c58..3e2ae27 100644
--- a/clutter/x11/clutter-stage-x11.h
+++ b/clutter/x11/clutter-stage-x11.h
@@ -28,6 +28,7 @@
 #include <X11/Xatom.h>
 
 #include "clutter-backend-x11.h"
+#include "cogl/clutter-stage-cogl.h"
 
 G_BEGIN_DECLS
 
@@ -48,7 +49,7 @@ typedef enum
 
 struct _ClutterStageX11
 {
-  GObject parent_instance;
+  ClutterStageCogl parent_instance;
 
   Window xwin;
   gint xwin_width;
@@ -62,10 +63,6 @@ struct _ClutterStageX11
 
   ClutterStageX11State wm_state;
 
-  /* backpointers */
-  ClutterStage *wrapper;
-  ClutterBackendX11 *backend;
-
   guint is_foreign_xwin      : 1;
   guint fullscreening        : 1;
   guint is_cursor_visible    : 1;
@@ -75,7 +72,7 @@ struct _ClutterStageX11
 
 struct _ClutterStageX11Class
 {
-  GObjectClass parent_class;
+  ClutterStageCoglClass parent_class;
 };
 
 #define CLUTTER_STAGE_X11_EVENT_MASK \
diff --git a/configure.ac b/configure.ac
index 98f53a4..66e8c63 100644
--- a/configure.ac
+++ b/configure.ac
@@ -206,15 +206,14 @@ AS_CASE([$CLUTTER_FLAVOUR],
 
         [glx],
         [
-          CLUTTER_STAGE_TYPE="CLUTTER_TYPE_STAGE_GLX"
+          CLUTTER_STAGE_TYPE="CLUTTER_TYPE_STAGE_X11"
 
           SUPPORT_X11=1
           SUPPORT_XLIB=1
           SUPPORT_GLX=1
 
-          CLUTTER_WINSYS=cogl
-          CLUTTER_WINSYS_BASE=x11
-          CLUTTER_WINSYS_BASE_LIB="x11/libclutter-x11.la"
+          CLUTTER_WINSYS=x11
+          CLUTTER_WINSYS_BASE=cogl
           CLUTTER_SONAME_INFIX=glx
 
           # Mesa 7.3 added a GL pkg-config file, finally
@@ -235,15 +234,14 @@ AS_CASE([$CLUTTER_FLAVOUR],
 
 	[gdk],
 	[
-	  CLUTTER_STAGE_TYPE="CLUTTER_TYPE_STAGE_COGL"
+	  CLUTTER_STAGE_TYPE="CLUTTER_TYPE_STAGE_GDK"
 
 	  # We don't claim to support X11 (even though that's the preferred
 	  # GDK backend), to avoid building all the ClutterX11 stuff
 	  SUPPORT_GDK=1
 
-	  CLUTTER_WINSYS=cogl
-	  CLUTTER_WINSYS_BASE=gdk
-	  CLUTTER_WINSYS_BASE_LIB="gdk/libclutter-gdk.la"
+	  CLUTTER_WINSYS=gdk
+	  CLUTTER_WINSYS_BASE=cogl
 	  CLUTTER_SONAME_INFIX=gdk
 
 	  BACKEND_PC_FILES="$BACKEND_PC_FILES gdk-3.0"
@@ -252,7 +250,7 @@ AS_CASE([$CLUTTER_FLAVOUR],
 
         [opengl-egl-xlib],
         [
-          CLUTTER_STAGE_TYPE="CLUTTER_TYPE_STAGE_EGL"
+          CLUTTER_STAGE_TYPE="CLUTTER_TYPE_STAGE_X11"
           CLUTTER_EGL_BACKEND="generic"
 
           SUPPORT_X11=1
@@ -260,9 +258,8 @@ AS_CASE([$CLUTTER_FLAVOUR],
           SUPPORT_EGL=1
           SUPPORT_EGL_PLATFORM_POWERVR_X11=1
 
-          CLUTTER_WINSYS=cogl
-          CLUTTER_WINSYS_BASE=x11
-          CLUTTER_WINSYS_BASE_LIB="x11/libclutter-x11.la"
+          CLUTTER_WINSYS=x11
+          CLUTTER_WINSYS_BASE=cogl
           # I think this winsys can be API and ABI compatible with the
           # glx flavour so we can also be cheeky and use the same soname
           CLUTTER_SONAME_INFIX=glx
@@ -289,7 +286,7 @@ AS_CASE([$CLUTTER_FLAVOUR],
 
         [eglx],
         [
-          CLUTTER_STAGE_TYPE="CLUTTER_TYPE_STAGE_EGL"
+          CLUTTER_STAGE_TYPE="CLUTTER_TYPE_STAGE_X11"
           CLUTTER_EGL_BACKEND="generic"
 
           SUPPORT_X11=1
@@ -297,9 +294,8 @@ AS_CASE([$CLUTTER_FLAVOUR],
           SUPPORT_EGL=1
           SUPPORT_EGL_PLATFORM_POWERVR_X11=1
 
-          CLUTTER_WINSYS=cogl
-          CLUTTER_WINSYS_BASE=x11
-          CLUTTER_WINSYS_BASE_LIB="x11/libclutter-x11.la"
+          CLUTTER_WINSYS=x11
+          CLUTTER_WINSYS_BASE=cogl
           CLUTTER_SONAME_INFIX=eglx
         ],
 
@@ -509,7 +505,6 @@ dnl === Clutter substitutions =================================================
 AC_SUBST([CLUTTER_WINSYS])
 # The same goes for the winsys-base...
 AC_SUBST([CLUTTER_WINSYS_BASE])
-AC_SUBST([CLUTTER_WINSYS_BASE_LIB])
 AC_SUBST(CLUTTER_STAGE_TYPE)
 AC_SUBST(CLUTTER_SONAME_INFIX)
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]