[clutter/multi-backend: 2/7] Rework the interaction between the Cogl and GDK / X11 backends.
- From: Emmanuele Bassi <ebassi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [clutter/multi-backend: 2/7] Rework the interaction between the Cogl and GDK / X11 backends.
- Date: Thu, 29 Sep 2011 17:19:03 +0000 (UTC)
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"><clutter/egl/clutter-cex100.h></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]