mirror of
https://github.com/brl/mutter.git
synced 2024-12-23 19:42:05 +00:00
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
This commit is contained in:
parent
610a9c17ba
commit
9c102b7c51
@ -368,12 +368,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
|
||||
@ -393,14 +387,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)
|
||||
|
||||
@ -442,6 +442,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
|
||||
|
@ -36,55 +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
|
||||
|
||||
#include <cogl/cogl-xlib.h>
|
||||
|
||||
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
|
||||
|
||||
const gchar*
|
||||
_clutter_backend_cogl_get_vblank (void)
|
||||
@ -100,13 +64,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)
|
||||
@ -122,54 +79,7 @@ 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
|
||||
|
||||
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
|
||||
@ -185,14 +95,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)
|
||||
{
|
||||
@ -200,16 +102,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 *
|
||||
@ -220,7 +113,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);
|
||||
@ -242,15 +135,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");
|
||||
@ -285,195 +169,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;
|
||||
gboolean status;
|
||||
|
||||
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?
|
||||
*/
|
||||
status = cogl_renderer_check_onscreen_template (backend->cogl_renderer,
|
||||
onscreen_template,
|
||||
error);
|
||||
#ifdef COGL_HAS_XLIB_SUPPORT
|
||||
if (!status && clutter_x11_get_use_argb_visual ())
|
||||
{
|
||||
g_clear_error (error);
|
||||
/* It's possible that the current renderer doesn't support transparency
|
||||
* in a swap_chain so lets see if we can fallback to not having any
|
||||
* transparency...
|
||||
*
|
||||
* XXX: It might be nice to have a CoglRenderer feature we could
|
||||
* explicitly check for ahead of time.
|
||||
*/
|
||||
cogl_swap_chain_set_has_alpha (swap_chain, FALSE);
|
||||
status = cogl_renderer_check_onscreen_template (backend->cogl_renderer,
|
||||
onscreen_template,
|
||||
error);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!status)
|
||||
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)
|
||||
@ -495,9 +190,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;
|
||||
@ -506,31 +198,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
|
||||
@ -559,22 +233,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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
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));
|
||||
}
|
||||
#else
|
||||
static void
|
||||
_clutter_stage_cogl_class_init (ClutterStageCoglClass *klass)
|
||||
{
|
||||
}
|
||||
#endif /* COGL_HAS_X11_SUPPORT */
|
||||
|
||||
static void
|
||||
_clutter_stage_cogl_init (ClutterStageCogl *stage)
|
||||
|
@ -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;
|
||||
|
262
clutter/egl/clutter-backend-eglnative.c
Normal file
262
clutter/egl/clutter-backend-eglnative.c
Normal file
@ -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
|
80
clutter/egl/clutter-backend-eglnative.h
Normal file
80
clutter/egl/clutter-backend-eglnative.h
Normal file
@ -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__ */
|
91
clutter/egl/clutter-cex100.h
Normal file
91
clutter/egl/clutter-cex100.h
Normal file
@ -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__ */
|
@ -95,7 +95,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;
|
||||
@ -151,7 +151,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)
|
@ -35,10 +35,16 @@
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
#include <cogl/cogl.h>
|
||||
|
||||
#include <cogl/cogl-xlib.h>
|
||||
|
||||
#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 +60,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;
|
||||
@ -131,21 +134,13 @@ cogl_gdk_filter (GdkXEvent *xevent,
|
||||
#endif
|
||||
}
|
||||
|
||||
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 +176,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 +197,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 +217,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 +266,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 +408,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 +446,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 ();
|
||||
}
|
||||
|
@ -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 */
|
||||
};
|
||||
|
@ -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;
|
||||
@ -397,51 +426,12 @@ clutter_stage_gdk_dispose (GObject *gobject)
|
||||
G_OBJECT_CLASS (clutter_stage_gdk_parent_class)->dispose (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;
|
||||
}
|
||||
|
@ -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 \
|
||||
|
@ -70,7 +70,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
|
||||
@ -92,9 +92,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;
|
||||
@ -334,7 +331,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
|
||||
@ -462,7 +460,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);
|
||||
}
|
||||
|
||||
|
||||
@ -526,9 +525,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);
|
||||
}
|
||||
|
||||
@ -549,34 +545,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
|
||||
@ -706,13 +682,124 @@ 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);
|
||||
CoglOnscreenTemplate *onscreen_template = NULL;
|
||||
CoglSwapChain *swap_chain = NULL;
|
||||
gboolean status;
|
||||
|
||||
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?
|
||||
*/
|
||||
status = cogl_renderer_check_onscreen_template (backend->cogl_renderer,
|
||||
onscreen_template,
|
||||
error);
|
||||
if (!status && clutter_x11_get_use_argb_visual ())
|
||||
{
|
||||
g_clear_error (error);
|
||||
|
||||
/* It's possible that the current renderer doesn't support transparency
|
||||
* in a swap_chain so lets see if we can fallback to not having any
|
||||
* transparency...
|
||||
*
|
||||
* XXX: It might be nice to have a CoglRenderer feature we could
|
||||
* explicitly check for ahead of time.
|
||||
*/
|
||||
cogl_swap_chain_set_has_alpha (swap_chain, FALSE);
|
||||
status = cogl_renderer_check_onscreen_template (backend->cogl_renderer,
|
||||
onscreen_template,
|
||||
error);
|
||||
}
|
||||
|
||||
if (!status)
|
||||
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;
|
||||
|
||||
@ -725,6 +812,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
|
||||
@ -784,13 +873,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;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -913,13 +1004,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;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -934,13 +1027,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;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -957,21 +1052,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;
|
||||
}
|
||||
@ -991,10 +1090,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)
|
||||
{
|
||||
@ -1004,8 +1113,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);
|
||||
@ -1052,10 +1161,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
|
||||
@ -1159,15 +1273,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 ();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1242,3 +1348,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 ();
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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 \
|
||||
|
29
configure.ac
29
configure.ac
@ -199,15 +199,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
|
||||
@ -228,15 +227,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"
|
||||
@ -245,7 +243,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
|
||||
@ -253,9 +251,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
|
||||
@ -282,7 +279,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
|
||||
@ -290,9 +287,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
|
||||
],
|
||||
|
||||
@ -494,7 +490,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)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user