mirror of
https://github.com/brl/mutter.git
synced 2024-12-23 03:22:04 +00:00
2008-04-04 Emmanuele Bassi <ebassi@openedhand.com>
Bug #864 - Allow instantiating and subclassing of ClutterStage * clutter/Makefile.am: Add clutter-stage-window.[ch] * clutter/clutter-stage-manager.c: (_clutter_stage_manager_remove_stage): Do not warn if removing a stage we don't manage, as we might be invoked multiple times during a ClutterState dispose sequence. * clutter/clutter-actor.c: * clutter/clutter-backend.[ch]: * clutter/clutter-main.c: * clutter/clutter-private.h: * clutter/clutter-stage.[ch]: Make ClutterStage a proxy actor, with a private actor implementing the ClutterStageWindow interface for handling the per-backend realization, painting and unrealization, plus all the windowing system abstraction. * clutter/x11/clutter-event-x11.c: * clutter/x11/clutter-stage-x11.[ch]: Port the X11 backend to the new backend and stage API and semantics. * clutter/glx/clutter-backend-glx.c: * clutter/glx/clutter-stage-glx.c: Port the GLX backend to the new backend and stage API and semantics. * clutter/eglx/clutter-backend-egl.[ch]: * clutter/eglx/clutter-stage-egl.[ch]: Port the EGLX backend to the new backend and stage API and semantics (untested). * tests/test-multistage.c (on_button_press): Rename clutter_stage_create_new() to clutter_stage_new().
This commit is contained in:
parent
beb03b9750
commit
f859135082
35
ChangeLog
35
ChangeLog
@ -1,3 +1,38 @@
|
|||||||
|
2008-04-04 Emmanuele Bassi <ebassi@openedhand.com>
|
||||||
|
|
||||||
|
Bug #864 - Allow instantiating and subclassing of ClutterStage
|
||||||
|
|
||||||
|
* clutter/Makefile.am: Add clutter-stage-window.[ch]
|
||||||
|
|
||||||
|
* clutter/clutter-stage-manager.c:
|
||||||
|
(_clutter_stage_manager_remove_stage): Do not warn if removing
|
||||||
|
a stage we don't manage, as we might be invoked multiple times
|
||||||
|
during a ClutterState dispose sequence.
|
||||||
|
|
||||||
|
* clutter/clutter-actor.c:
|
||||||
|
* clutter/clutter-backend.[ch]:
|
||||||
|
* clutter/clutter-main.c:
|
||||||
|
* clutter/clutter-private.h:
|
||||||
|
* clutter/clutter-stage.[ch]: Make ClutterStage a proxy actor,
|
||||||
|
with a private actor implementing the ClutterStageWindow
|
||||||
|
interface for handling the per-backend realization, painting
|
||||||
|
and unrealization, plus all the windowing system abstraction.
|
||||||
|
|
||||||
|
* clutter/x11/clutter-event-x11.c:
|
||||||
|
* clutter/x11/clutter-stage-x11.[ch]: Port the X11 backend
|
||||||
|
to the new backend and stage API and semantics.
|
||||||
|
|
||||||
|
* clutter/glx/clutter-backend-glx.c:
|
||||||
|
* clutter/glx/clutter-stage-glx.c: Port the GLX backend to
|
||||||
|
the new backend and stage API and semantics.
|
||||||
|
|
||||||
|
* clutter/eglx/clutter-backend-egl.[ch]:
|
||||||
|
* clutter/eglx/clutter-stage-egl.[ch]: Port the EGLX backend
|
||||||
|
to the new backend and stage API and semantics (untested).
|
||||||
|
|
||||||
|
* tests/test-multistage.c (on_button_press): Rename
|
||||||
|
clutter_stage_create_new() to clutter_stage_new().
|
||||||
|
|
||||||
2008-04-04 Neil Roberts <neil@o-hand.com>
|
2008-04-04 Neil Roberts <neil@o-hand.com>
|
||||||
|
|
||||||
Applied patch from bug #810.
|
Applied patch from bug #810.
|
||||||
|
@ -162,6 +162,7 @@ source_c = \
|
|||||||
clutter-shader.c \
|
clutter-shader.c \
|
||||||
clutter-stage.c \
|
clutter-stage.c \
|
||||||
clutter-stage-manager.c \
|
clutter-stage-manager.c \
|
||||||
|
clutter-stage-window.c \
|
||||||
clutter-texture.c \
|
clutter-texture.c \
|
||||||
clutter-timeline.c \
|
clutter-timeline.c \
|
||||||
clutter-timeout-pool.c \
|
clutter-timeout-pool.c \
|
||||||
@ -175,6 +176,7 @@ source_h_priv = \
|
|||||||
clutter-private.h \
|
clutter-private.h \
|
||||||
clutter-id-pool.h \
|
clutter-id-pool.h \
|
||||||
clutter-script-private.h \
|
clutter-script-private.h \
|
||||||
|
clutter-stage-window.h \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
libclutter_@CLUTTER_FLAVOUR@_@CLUTTER_API_VERSION@_la_LIBADD = \
|
libclutter_@CLUTTER_FLAVOUR@_@CLUTTER_API_VERSION@_la_LIBADD = \
|
||||||
|
@ -2447,7 +2447,7 @@ clutter_actor_queue_redraw (ClutterActor *self)
|
|||||||
|
|
||||||
/* FIXME: should we check we're visible here? */
|
/* FIXME: should we check we're visible here? */
|
||||||
if ((stage = clutter_actor_get_stage (self)) != NULL)
|
if ((stage = clutter_actor_get_stage (self)) != NULL)
|
||||||
clutter_stage_queue_redraw (CLUTTER_STAGE(stage));
|
clutter_stage_queue_redraw (CLUTTER_STAGE (stage));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -44,6 +44,7 @@
|
|||||||
#include "clutter-fixed.h"
|
#include "clutter-fixed.h"
|
||||||
#include "clutter-backend.h"
|
#include "clutter-backend.h"
|
||||||
#include "clutter-private.h"
|
#include "clutter-private.h"
|
||||||
|
#include "clutter-debug.h"
|
||||||
|
|
||||||
G_DEFINE_ABSTRACT_TYPE (ClutterBackend, clutter_backend, G_TYPE_OBJECT);
|
G_DEFINE_ABSTRACT_TYPE (ClutterBackend, clutter_backend, G_TYPE_OBJECT);
|
||||||
|
|
||||||
@ -138,8 +139,9 @@ _clutter_backend_post_parse (ClutterBackend *backend,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ClutterActor*
|
ClutterActor *
|
||||||
_clutter_backend_create_stage (ClutterBackend *backend,
|
_clutter_backend_create_stage (ClutterBackend *backend,
|
||||||
|
ClutterStage *wrapper,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
ClutterMainContext *context;
|
ClutterMainContext *context;
|
||||||
@ -147,6 +149,7 @@ _clutter_backend_create_stage (ClutterBackend *backend,
|
|||||||
ClutterActor *stage = NULL;
|
ClutterActor *stage = NULL;
|
||||||
|
|
||||||
g_return_val_if_fail (CLUTTER_IS_BACKEND (backend), FALSE);
|
g_return_val_if_fail (CLUTTER_IS_BACKEND (backend), FALSE);
|
||||||
|
g_return_val_if_fail (CLUTTER_IS_STAGE (wrapper), FALSE);
|
||||||
|
|
||||||
context = clutter_context_get_default ();
|
context = clutter_context_get_default ();
|
||||||
|
|
||||||
@ -155,28 +158,30 @@ _clutter_backend_create_stage (ClutterBackend *backend,
|
|||||||
|
|
||||||
klass = CLUTTER_BACKEND_GET_CLASS (backend);
|
klass = CLUTTER_BACKEND_GET_CLASS (backend);
|
||||||
if (klass->create_stage)
|
if (klass->create_stage)
|
||||||
stage = klass->create_stage (backend, error);
|
stage = klass->create_stage (backend, wrapper, error);
|
||||||
|
|
||||||
if (!stage)
|
if (!stage)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
_clutter_stage_manager_add_stage (context->stage_manager,
|
_clutter_stage_manager_add_stage (context->stage_manager, wrapper);
|
||||||
CLUTTER_STAGE(stage));
|
|
||||||
return stage;
|
return stage;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_clutter_backend_redraw (ClutterBackend *backend, ClutterStage *stage)
|
_clutter_backend_redraw (ClutterBackend *backend,
|
||||||
|
ClutterStage *stage)
|
||||||
{
|
{
|
||||||
ClutterBackendClass *klass;
|
ClutterBackendClass *klass;
|
||||||
|
|
||||||
klass = CLUTTER_BACKEND_GET_CLASS (backend);
|
klass = CLUTTER_BACKEND_GET_CLASS (backend);
|
||||||
if (G_LIKELY(klass->redraw))
|
if (G_LIKELY (klass->redraw))
|
||||||
klass->redraw (backend, stage);
|
klass->redraw (backend, stage);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_clutter_backend_ensure_context (ClutterBackend *backend, ClutterStage *stage)
|
_clutter_backend_ensure_context (ClutterBackend *backend,
|
||||||
|
ClutterStage *stage)
|
||||||
{
|
{
|
||||||
ClutterBackendClass *klass;
|
ClutterBackendClass *klass;
|
||||||
static ClutterStage *current_context_stage = NULL;
|
static ClutterStage *current_context_stage = NULL;
|
||||||
@ -184,13 +189,16 @@ _clutter_backend_ensure_context (ClutterBackend *backend, ClutterStage *stage)
|
|||||||
g_return_if_fail (CLUTTER_IS_BACKEND (backend));
|
g_return_if_fail (CLUTTER_IS_BACKEND (backend));
|
||||||
g_return_if_fail (CLUTTER_IS_STAGE (stage));
|
g_return_if_fail (CLUTTER_IS_STAGE (stage));
|
||||||
|
|
||||||
if (stage != current_context_stage || !CLUTTER_ACTOR_IS_REALIZED(stage))
|
if (stage != current_context_stage || !CLUTTER_ACTOR_IS_REALIZED (stage))
|
||||||
{
|
{
|
||||||
if (!CLUTTER_ACTOR_IS_REALIZED(stage))
|
if (!CLUTTER_ACTOR_IS_REALIZED (stage))
|
||||||
stage = NULL;
|
{
|
||||||
|
CLUTTER_NOTE (MULTISTAGE, "Stage is not realized");
|
||||||
|
stage = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
klass = CLUTTER_BACKEND_GET_CLASS (backend);
|
klass = CLUTTER_BACKEND_GET_CLASS (backend);
|
||||||
if (G_LIKELY(klass->ensure_context))
|
if (G_LIKELY (klass->ensure_context))
|
||||||
klass->ensure_context (backend, stage);
|
klass->ensure_context (backend, stage);
|
||||||
|
|
||||||
/* FIXME: With a NULL stage and thus no active context it may make more
|
/* FIXME: With a NULL stage and thus no active context it may make more
|
||||||
|
@ -47,31 +47,33 @@ typedef struct _ClutterBackendClass ClutterBackendClass;
|
|||||||
|
|
||||||
struct _ClutterBackend
|
struct _ClutterBackend
|
||||||
{
|
{
|
||||||
|
/*< private >*/
|
||||||
GObject parent_instance;
|
GObject parent_instance;
|
||||||
ClutterBackendPrivate *priv;
|
ClutterBackendPrivate *priv;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _ClutterBackendClass
|
struct _ClutterBackendClass
|
||||||
{
|
{
|
||||||
|
/*< private >*/
|
||||||
GObjectClass parent_class;
|
GObjectClass parent_class;
|
||||||
|
|
||||||
/* vfuncs */
|
/* vfuncs */
|
||||||
gboolean (* pre_parse) (ClutterBackend *backend,
|
gboolean (* pre_parse) (ClutterBackend *backend,
|
||||||
GError **error);
|
GError **error);
|
||||||
gboolean (* post_parse) (ClutterBackend *backend,
|
gboolean (* post_parse) (ClutterBackend *backend,
|
||||||
GError **error);
|
GError **error);
|
||||||
ClutterActor *(* create_stage) (ClutterBackend *backend,
|
ClutterActor * (* create_stage) (ClutterBackend *backend,
|
||||||
GError **error);
|
ClutterStage *wrapper,
|
||||||
void (* init_events) (ClutterBackend *backend);
|
GError **error);
|
||||||
void (* init_features) (ClutterBackend *backend);
|
void (* init_events) (ClutterBackend *backend);
|
||||||
void (* add_options) (ClutterBackend *backend,
|
void (* init_features) (ClutterBackend *backend);
|
||||||
GOptionGroup *group);
|
void (* add_options) (ClutterBackend *backend,
|
||||||
ClutterFeatureFlags (* get_features) (ClutterBackend *backend);
|
GOptionGroup *group);
|
||||||
void (* redraw) (ClutterBackend *backend,
|
ClutterFeatureFlags (* get_features) (ClutterBackend *backend);
|
||||||
ClutterStage *stage);
|
void (* redraw) (ClutterBackend *backend,
|
||||||
void (* ensure_context) (ClutterBackend *backend,
|
ClutterStage *stage);
|
||||||
ClutterStage *stage);
|
void (* ensure_context) (ClutterBackend *backend,
|
||||||
|
ClutterStage *stage);
|
||||||
};
|
};
|
||||||
|
|
||||||
GType clutter_backend_get_type (void) G_GNUC_CONST;
|
GType clutter_backend_get_type (void) G_GNUC_CONST;
|
||||||
|
@ -104,6 +104,28 @@ clutter_get_show_fps (void)
|
|||||||
return clutter_show_fps;
|
return clutter_show_fps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
clutter_maybe_setup_viewport (ClutterStage *stage)
|
||||||
|
{
|
||||||
|
if (CLUTTER_PRIVATE_FLAGS (stage) & CLUTTER_ACTOR_SYNC_MATRICES)
|
||||||
|
{
|
||||||
|
ClutterPerspective perspective;
|
||||||
|
guint width, height;
|
||||||
|
|
||||||
|
clutter_actor_get_size (CLUTTER_ACTOR (stage), &width, &height);
|
||||||
|
clutter_stage_get_perspectivex (stage, &perspective);
|
||||||
|
|
||||||
|
CLUTTER_NOTE (PAINT, "Setting up the viewport");
|
||||||
|
|
||||||
|
cogl_setup_viewport (width, height,
|
||||||
|
perspective.fovy,
|
||||||
|
perspective.aspect,
|
||||||
|
perspective.z_near,
|
||||||
|
perspective.z_far);
|
||||||
|
|
||||||
|
CLUTTER_UNSET_PRIVATE_FLAGS (stage, CLUTTER_ACTOR_SYNC_MATRICES);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* clutter_redraw:
|
* clutter_redraw:
|
||||||
@ -122,35 +144,21 @@ clutter_redraw (ClutterStage *stage)
|
|||||||
|
|
||||||
CLUTTER_TIMESTAMP (SCHEDULER, "Redraw start for stage:%p", stage);
|
CLUTTER_TIMESTAMP (SCHEDULER, "Redraw start for stage:%p", stage);
|
||||||
CLUTTER_NOTE (PAINT, " Redraw enter for stage:%p", stage);
|
CLUTTER_NOTE (PAINT, " Redraw enter for stage:%p", stage);
|
||||||
CLUTTER_NOTE (MULTISTAGE, "redraw called for stage:%p", stage);
|
CLUTTER_NOTE (MULTISTAGE, "Redraw called for stage:%p", stage);
|
||||||
|
|
||||||
_clutter_backend_ensure_context (ctx->backend, stage);
|
_clutter_backend_ensure_context (ctx->backend, stage);
|
||||||
|
|
||||||
/* Setup FPS count - not currently across *all* stages rather than per */
|
/* Setup FPS count - not currently across *all* stages rather than per */
|
||||||
if (clutter_get_show_fps ())
|
if (G_UNLIKELY (clutter_get_show_fps ()))
|
||||||
{
|
{
|
||||||
if (!timer)
|
if (!timer)
|
||||||
timer = g_timer_new ();
|
timer = g_timer_new ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The below cant go in stage paint as base actor_paint will get
|
/* The code below can't go in stage paint as base actor_paint
|
||||||
* called before the below (and break picking etc)
|
* will get called before it (and break picking, etc)
|
||||||
*/
|
*/
|
||||||
if (CLUTTER_PRIVATE_FLAGS (stage) & CLUTTER_ACTOR_SYNC_MATRICES)
|
clutter_maybe_setup_viewport (stage);
|
||||||
{
|
|
||||||
ClutterPerspective perspective;
|
|
||||||
|
|
||||||
clutter_stage_get_perspectivex (CLUTTER_STAGE (stage), &perspective);
|
|
||||||
|
|
||||||
cogl_setup_viewport (clutter_actor_get_width (CLUTTER_ACTOR(stage)),
|
|
||||||
clutter_actor_get_height (CLUTTER_ACTOR(stage)),
|
|
||||||
perspective.fovy,
|
|
||||||
perspective.aspect,
|
|
||||||
perspective.z_near,
|
|
||||||
perspective.z_far);
|
|
||||||
|
|
||||||
CLUTTER_UNSET_PRIVATE_FLAGS (stage, CLUTTER_ACTOR_SYNC_MATRICES);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Call through to the actual backend to do the painting down from
|
/* Call through to the actual backend to do the painting down from
|
||||||
* the stage. It will likely need to swap buffers, vblank sync etc
|
* the stage. It will likely need to swap buffers, vblank sync etc
|
||||||
@ -159,7 +167,7 @@ clutter_redraw (ClutterStage *stage)
|
|||||||
_clutter_backend_redraw (ctx->backend, stage);
|
_clutter_backend_redraw (ctx->backend, stage);
|
||||||
|
|
||||||
/* Complete FPS info */
|
/* Complete FPS info */
|
||||||
if (clutter_get_show_fps ())
|
if (G_UNLIKELY (clutter_get_show_fps ()))
|
||||||
{
|
{
|
||||||
timer_n_frames++;
|
timer_n_frames++;
|
||||||
|
|
||||||
@ -234,24 +242,8 @@ _clutter_do_pick (ClutterStage *stage,
|
|||||||
|
|
||||||
_clutter_backend_ensure_context (context->backend, stage);
|
_clutter_backend_ensure_context (context->backend, stage);
|
||||||
|
|
||||||
/* FIXME: needed for when a context switch happens - probably
|
/* needed for when a context switch happens */
|
||||||
* should put into its own function somewhere..
|
clutter_maybe_setup_viewport (stage);
|
||||||
*/
|
|
||||||
if (CLUTTER_PRIVATE_FLAGS (stage) & CLUTTER_ACTOR_SYNC_MATRICES)
|
|
||||||
{
|
|
||||||
ClutterPerspective perspective;
|
|
||||||
|
|
||||||
clutter_stage_get_perspectivex (CLUTTER_STAGE (stage), &perspective);
|
|
||||||
|
|
||||||
cogl_setup_viewport (clutter_actor_get_width (CLUTTER_ACTOR(stage)),
|
|
||||||
clutter_actor_get_height (CLUTTER_ACTOR(stage)),
|
|
||||||
perspective.fovy,
|
|
||||||
perspective.aspect,
|
|
||||||
perspective.z_near,
|
|
||||||
perspective.z_far);
|
|
||||||
|
|
||||||
CLUTTER_UNSET_PRIVATE_FLAGS (stage, CLUTTER_ACTOR_SYNC_MATRICES);
|
|
||||||
}
|
|
||||||
|
|
||||||
cogl_paint_init (&white);
|
cogl_paint_init (&white);
|
||||||
cogl_enable (0);
|
cogl_enable (0);
|
||||||
@ -276,10 +268,10 @@ _clutter_do_pick (ClutterStage *stage,
|
|||||||
/* glEnable (GL_DITHER); we never enabled this originally, so its
|
/* glEnable (GL_DITHER); we never enabled this originally, so its
|
||||||
probably not safe to then enable it */
|
probably not safe to then enable it */
|
||||||
|
|
||||||
glReadPixels(x, viewport[3] - y -1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
|
glReadPixels (x, viewport[3] - y -1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
|
||||||
|
|
||||||
if (pixel[0] == 0xff && pixel[1] == 0xff && pixel[2] == 0xff)
|
if (pixel[0] == 0xff && pixel[1] == 0xff && pixel[2] == 0xff)
|
||||||
return CLUTTER_ACTOR (stage);
|
return CLUTTER_ACTOR (stage);
|
||||||
|
|
||||||
cogl_get_bitmasks (&r, &g, &b, NULL);
|
cogl_get_bitmasks (&r, &g, &b, NULL);
|
||||||
|
|
||||||
@ -988,7 +980,6 @@ clutter_init_with_args (int *argc,
|
|||||||
GOptionContext *context;
|
GOptionContext *context;
|
||||||
GOptionGroup *group;
|
GOptionGroup *group;
|
||||||
gboolean res;
|
gboolean res;
|
||||||
GError *stage_error;
|
|
||||||
ClutterActor *stage;
|
ClutterActor *stage;
|
||||||
|
|
||||||
if (clutter_is_initialized)
|
if (clutter_is_initialized)
|
||||||
@ -1018,13 +1009,13 @@ clutter_init_with_args (int *argc,
|
|||||||
|
|
||||||
clutter_context = clutter_context_get_default ();
|
clutter_context = clutter_context_get_default ();
|
||||||
|
|
||||||
stage_error = NULL;
|
stage = clutter_stage_get_default ();
|
||||||
stage = _clutter_backend_create_stage (clutter_context->backend,
|
|
||||||
&stage_error);
|
|
||||||
|
|
||||||
if (!stage)
|
if (!stage)
|
||||||
{
|
{
|
||||||
g_propagate_error (error, stage_error);
|
g_set_error (error, CLUTTER_INIT_ERROR,
|
||||||
|
CLUTTER_INIT_ERROR_INTERNAL,
|
||||||
|
"Unable to create the default stage");
|
||||||
|
|
||||||
return CLUTTER_INIT_ERROR_INTERNAL;
|
return CLUTTER_INIT_ERROR_INTERNAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1032,8 +1023,7 @@ clutter_init_with_args (int *argc,
|
|||||||
|
|
||||||
_clutter_feature_init ();
|
_clutter_feature_init ();
|
||||||
|
|
||||||
clutter_stage_set_title (CLUTTER_STAGE(clutter_stage_get_default()),
|
clutter_stage_set_title (CLUTTER_STAGE (stage), g_get_prgname ());
|
||||||
g_get_prgname ());
|
|
||||||
|
|
||||||
return CLUTTER_INIT_SUCCESS;
|
return CLUTTER_INIT_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -1089,7 +1079,6 @@ clutter_init (int *argc,
|
|||||||
{
|
{
|
||||||
ClutterMainContext *context;
|
ClutterMainContext *context;
|
||||||
ClutterActor *stage;
|
ClutterActor *stage;
|
||||||
GError *stage_error;
|
|
||||||
|
|
||||||
if (clutter_is_initialized)
|
if (clutter_is_initialized)
|
||||||
return CLUTTER_INIT_SUCCESS;
|
return CLUTTER_INIT_SUCCESS;
|
||||||
@ -1115,15 +1104,10 @@ clutter_init (int *argc,
|
|||||||
context = clutter_context_get_default ();
|
context = clutter_context_get_default ();
|
||||||
|
|
||||||
/* Stage will give us a GL Context etc */
|
/* Stage will give us a GL Context etc */
|
||||||
stage_error = NULL;
|
stage = clutter_stage_get_default ();
|
||||||
|
|
||||||
stage = _clutter_backend_create_stage (context->backend, &stage_error);
|
|
||||||
|
|
||||||
if (!stage)
|
if (!stage)
|
||||||
{
|
{
|
||||||
CLUTTER_NOTE (MISC, "stage failed to initialise.");
|
g_critical ("Unable to create the default stage");
|
||||||
g_critical (stage_error->message);
|
|
||||||
g_error_free (stage_error);
|
|
||||||
return CLUTTER_INIT_ERROR_INTERNAL;
|
return CLUTTER_INIT_ERROR_INTERNAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1133,8 +1117,7 @@ clutter_init (int *argc,
|
|||||||
/* finally features - will call to backend and cogl */
|
/* finally features - will call to backend and cogl */
|
||||||
_clutter_feature_init ();
|
_clutter_feature_init ();
|
||||||
|
|
||||||
clutter_stage_set_title (CLUTTER_STAGE(clutter_stage_get_default()),
|
clutter_stage_set_title (CLUTTER_STAGE (stage), g_get_prgname ());
|
||||||
g_get_prgname());
|
|
||||||
|
|
||||||
return CLUTTER_INIT_SUCCESS;
|
return CLUTTER_INIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -40,12 +40,13 @@
|
|||||||
|
|
||||||
#include <pango/pangoft2.h>
|
#include <pango/pangoft2.h>
|
||||||
|
|
||||||
#include "clutter-stage-manager.h"
|
|
||||||
#include "clutter-event.h"
|
|
||||||
#include "clutter-backend.h"
|
#include "clutter-backend.h"
|
||||||
#include "clutter-stage.h"
|
#include "clutter-event.h"
|
||||||
#include "clutter-feature.h"
|
#include "clutter-feature.h"
|
||||||
#include "clutter-id-pool.h"
|
#include "clutter-id-pool.h"
|
||||||
|
#include "clutter-stage-manager.h"
|
||||||
|
#include "clutter-stage-window.h"
|
||||||
|
#include "clutter-stage.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
@ -55,10 +56,11 @@ typedef enum {
|
|||||||
CLUTTER_ACTOR_IN_DESTRUCTION = 1 << 0,
|
CLUTTER_ACTOR_IN_DESTRUCTION = 1 << 0,
|
||||||
CLUTTER_ACTOR_IS_TOPLEVEL = 1 << 1,
|
CLUTTER_ACTOR_IS_TOPLEVEL = 1 << 1,
|
||||||
CLUTTER_ACTOR_IN_REPARENT = 1 << 2,
|
CLUTTER_ACTOR_IN_REPARENT = 1 << 2,
|
||||||
CLUTTER_ACTOR_SYNC_MATRICES = 1 << 3 /* Used by stage to indicate GL
|
CLUTTER_ACTOR_SYNC_MATRICES = 1 << 3, /* Used by stage to indicate GL
|
||||||
* viewport / perspective etc
|
* viewport / perspective etc
|
||||||
* needs (re)setting.
|
* needs (re)setting.
|
||||||
*/
|
*/
|
||||||
|
CLUTTER_ACTOR_IN_PAINT = 1 << 4 /* Used to avoid recursion */
|
||||||
} ClutterPrivateFlags;
|
} ClutterPrivateFlags;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -122,7 +124,6 @@ ClutterMainContext *clutter_context_get_default (void);
|
|||||||
#define I_(str) (g_intern_static_string ((str)))
|
#define I_(str) (g_intern_static_string ((str)))
|
||||||
|
|
||||||
/* stage manager */
|
/* stage manager */
|
||||||
|
|
||||||
struct _ClutterStageManager
|
struct _ClutterStageManager
|
||||||
{
|
{
|
||||||
GObject parent_instance;
|
GObject parent_instance;
|
||||||
@ -135,29 +136,31 @@ void _clutter_stage_manager_add_stage (ClutterStageManager *stage_manager,
|
|||||||
void _clutter_stage_manager_remove_stage (ClutterStageManager *stage_manager,
|
void _clutter_stage_manager_remove_stage (ClutterStageManager *stage_manager,
|
||||||
ClutterStage *stage);
|
ClutterStage *stage);
|
||||||
|
|
||||||
/* vfuncs implemnted by backend */
|
/* stage */
|
||||||
|
|
||||||
GType _clutter_backend_impl_get_type (void);
|
void _clutter_stage_set_window (ClutterStage *stage,
|
||||||
|
ClutterStageWindow *stage_window);
|
||||||
|
ClutterStageWindow *_clutter_stage_get_window (ClutterStage *stage);
|
||||||
|
ClutterStageWindow *_clutter_stage_get_default_window (void);
|
||||||
|
|
||||||
void _clutter_backend_redraw (ClutterBackend *backend,
|
/* vfuncs implemented by backend */
|
||||||
ClutterStage *stage);
|
GType _clutter_backend_impl_get_type (void);
|
||||||
|
|
||||||
ClutterActor* _clutter_backend_create_stage (ClutterBackend *backend,
|
void _clutter_backend_redraw (ClutterBackend *backend,
|
||||||
GError **error);
|
ClutterStage *stage);
|
||||||
|
ClutterActor *_clutter_backend_create_stage (ClutterBackend *backend,
|
||||||
|
ClutterStage *wrapper,
|
||||||
|
GError **error);
|
||||||
|
void _clutter_backend_ensure_context (ClutterBackend *backend,
|
||||||
|
ClutterStage *stage);
|
||||||
|
|
||||||
void _clutter_backend_redraw (ClutterBackend *backend,
|
void _clutter_backend_add_options (ClutterBackend *backend,
|
||||||
ClutterStage *stage);
|
GOptionGroup *group);
|
||||||
|
gboolean _clutter_backend_pre_parse (ClutterBackend *backend,
|
||||||
void _clutter_backend_add_options (ClutterBackend *backend,
|
GError **error);
|
||||||
GOptionGroup *group);
|
gboolean _clutter_backend_post_parse (ClutterBackend *backend,
|
||||||
gboolean _clutter_backend_pre_parse (ClutterBackend *backend,
|
GError **error);
|
||||||
GError **error);
|
void _clutter_backend_init_events (ClutterBackend *backend);
|
||||||
gboolean _clutter_backend_post_parse (ClutterBackend *backend,
|
|
||||||
GError **error);
|
|
||||||
void _clutter_backend_init_events (ClutterBackend *backend);
|
|
||||||
|
|
||||||
void _clutter_backend_ensure_context (ClutterBackend *backend,
|
|
||||||
ClutterStage *stage);
|
|
||||||
|
|
||||||
ClutterFeatureFlags _clutter_backend_get_features (ClutterBackend *backend);
|
ClutterFeatureFlags _clutter_backend_get_features (ClutterBackend *backend);
|
||||||
|
|
||||||
@ -172,10 +175,10 @@ ClutterActor *_clutter_do_pick (ClutterStage *stage,
|
|||||||
* a G_TYPE_BOOLEAN return value; this will stop the emission as
|
* a G_TYPE_BOOLEAN return value; this will stop the emission as
|
||||||
* soon as one handler returns TRUE
|
* soon as one handler returns TRUE
|
||||||
*/
|
*/
|
||||||
gboolean _clutter_boolean_handled_accumulator (GSignalInvocationHint *ihint,
|
gboolean _clutter_boolean_handled_accumulator (GSignalInvocationHint *ihint,
|
||||||
GValue *return_accu,
|
GValue *return_accu,
|
||||||
const GValue *handler_return,
|
const GValue *handler_return,
|
||||||
gpointer dummy);
|
gpointer dummy);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
@ -267,12 +267,11 @@ void
|
|||||||
_clutter_stage_manager_remove_stage (ClutterStageManager *stage_manager,
|
_clutter_stage_manager_remove_stage (ClutterStageManager *stage_manager,
|
||||||
ClutterStage *stage)
|
ClutterStage *stage)
|
||||||
{
|
{
|
||||||
|
/* this might be called multiple times from a ::dispose, so it
|
||||||
|
* needs to just return without warning
|
||||||
|
*/
|
||||||
if (!g_slist_find (stage_manager->stages, stage))
|
if (!g_slist_find (stage_manager->stages, stage))
|
||||||
{
|
return;
|
||||||
g_warning ("Trying to remove an unknown stage from the list "
|
|
||||||
"of managed stages, aborting.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
stage_manager->stages = g_slist_remove (stage_manager->stages, stage);
|
stage_manager->stages = g_slist_remove (stage_manager->stages, stage);
|
||||||
|
|
||||||
|
33
clutter/clutter-stage-window.c
Normal file
33
clutter/clutter-stage-window.c
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
|
||||||
|
#include "clutter-actor.h"
|
||||||
|
#include "clutter-stage-window.h"
|
||||||
|
#include "clutter-private.h"
|
||||||
|
|
||||||
|
GType
|
||||||
|
clutter_stage_window_get_type (void)
|
||||||
|
{
|
||||||
|
static GType stage_window_type = 0;
|
||||||
|
|
||||||
|
if (G_UNLIKELY (stage_window_type == 0))
|
||||||
|
{
|
||||||
|
const GTypeInfo stage_window_info = {
|
||||||
|
sizeof (ClutterStageWindowIface),
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
stage_window_type =
|
||||||
|
g_type_register_static (G_TYPE_INTERFACE, I_("ClutterStageWindow"),
|
||||||
|
&stage_window_info, 0);
|
||||||
|
|
||||||
|
g_type_interface_add_prerequisite (stage_window_type,
|
||||||
|
CLUTTER_TYPE_ACTOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
return stage_window_type;
|
||||||
|
}
|
43
clutter/clutter-stage-window.h
Normal file
43
clutter/clutter-stage-window.h
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#ifndef __CLUTTER_STAGE_WINDOW_H__
|
||||||
|
#define __CLUTTER_STAGE_WINDOW_H__
|
||||||
|
|
||||||
|
#include <clutter/clutter-actor.h>
|
||||||
|
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define CLUTTER_TYPE_STAGE_WINDOW (clutter_stage_window_get_type ())
|
||||||
|
#define CLUTTER_STAGE_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_STAGE_WINDOW, ClutterStageWindow))
|
||||||
|
#define CLUTTER_IS_STAGE_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_STAGE_WINDOW))
|
||||||
|
#define CLUTTER_STAGE_WINDOW_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), CLUTTER_TYPE_STAGE_WINDOW, ClutterStageWindowIface))
|
||||||
|
|
||||||
|
typedef struct _ClutterStageWindow ClutterStageWindow; /* dummy */
|
||||||
|
typedef struct _ClutterStageWindowIface ClutterStageWindowIface;
|
||||||
|
|
||||||
|
struct _ClutterStageWindowIface
|
||||||
|
{
|
||||||
|
GTypeInterface parent_iface;
|
||||||
|
|
||||||
|
ClutterActor *(* get_wrapper) (ClutterStageWindow *stage_window);
|
||||||
|
|
||||||
|
void (* set_title) (ClutterStageWindow *stage_window,
|
||||||
|
const gchar *title);
|
||||||
|
void (* set_fullscreen) (ClutterStageWindow *stage_window,
|
||||||
|
gboolean is_fullscreen);
|
||||||
|
void (* set_cursor_visible) (ClutterStageWindow *stage_window,
|
||||||
|
gboolean cursor_visible);
|
||||||
|
void (* set_user_resizable) (ClutterStageWindow *stage_window,
|
||||||
|
gboolean is_resizable);
|
||||||
|
|
||||||
|
GdkPixbuf * (* draw_to_pixbuf) (ClutterStageWindow *stage_window,
|
||||||
|
gint x,
|
||||||
|
gint y,
|
||||||
|
gint width,
|
||||||
|
gint height);
|
||||||
|
};
|
||||||
|
|
||||||
|
GType clutter_stage_window_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __CLUTTER_STAGE_WINDOW_H__ */
|
@ -29,6 +29,24 @@
|
|||||||
*
|
*
|
||||||
* #ClutterStage is a top level 'window' on which child actors are placed
|
* #ClutterStage is a top level 'window' on which child actors are placed
|
||||||
* and manipulated.
|
* and manipulated.
|
||||||
|
*
|
||||||
|
* Clutter creates a default stage upon initialization, which can be retrieved
|
||||||
|
* using clutter_stage_get_default(). Clutter always provides the default
|
||||||
|
* stage, unless the backend is unable to create one. The stage returned
|
||||||
|
* by clutter_stage_get_default() is guaranteed to always be the same.
|
||||||
|
*
|
||||||
|
* Backends might provide support for multiple stages. The support for this
|
||||||
|
* feature can be checked at run-time using the clutter_feature_available()
|
||||||
|
* function and the %CLUTTER_FEATURE_STAGE_MULTIPLE flag. If the backend used
|
||||||
|
* supports multiple stages, new #ClutterStage instances can be created
|
||||||
|
* using clutter_stage_new(). These stages must be managed by the developer
|
||||||
|
* using clutter_actor_destroy(), which will take care of destroying all the
|
||||||
|
* actors contained inside them.
|
||||||
|
*
|
||||||
|
* #ClutterStage is a proxy actor, wrapping the backend-specific
|
||||||
|
* implementation of the windowing system. It is possible to subclass
|
||||||
|
* #ClutterStage, as long as every overridden virtual function chains up to
|
||||||
|
* the parent class corresponding function.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
@ -45,32 +63,36 @@
|
|||||||
#include "clutter-private.h"
|
#include "clutter-private.h"
|
||||||
#include "clutter-debug.h"
|
#include "clutter-debug.h"
|
||||||
#include "clutter-stage-manager.h"
|
#include "clutter-stage-manager.h"
|
||||||
|
#include "clutter-stage-window.h"
|
||||||
#include "clutter-version.h" /* For flavour */
|
#include "clutter-version.h" /* For flavour */
|
||||||
#include "clutter-id-pool.h"
|
#include "clutter-id-pool.h"
|
||||||
|
|
||||||
#include "cogl.h"
|
#include "cogl.h"
|
||||||
|
|
||||||
G_DEFINE_ABSTRACT_TYPE (ClutterStage, clutter_stage, CLUTTER_TYPE_GROUP);
|
G_DEFINE_TYPE (ClutterStage, clutter_stage, CLUTTER_TYPE_GROUP);
|
||||||
|
|
||||||
#define CLUTTER_STAGE_GET_PRIVATE(obj) \
|
#define CLUTTER_STAGE_GET_PRIVATE(obj) \
|
||||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), CLUTTER_TYPE_STAGE, ClutterStagePrivate))
|
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), CLUTTER_TYPE_STAGE, ClutterStagePrivate))
|
||||||
|
|
||||||
struct _ClutterStagePrivate
|
struct _ClutterStagePrivate
|
||||||
{
|
{
|
||||||
|
/* the stage implementation */
|
||||||
|
ClutterActor *impl;
|
||||||
|
|
||||||
ClutterColor color;
|
ClutterColor color;
|
||||||
ClutterPerspective perspective;
|
ClutterPerspective perspective;
|
||||||
ClutterFog fog;
|
ClutterFog fog;
|
||||||
|
|
||||||
|
gchar *title;
|
||||||
|
ClutterActor *key_focused_actor;
|
||||||
|
|
||||||
|
guint update_idle; /* repaint idler id */
|
||||||
|
|
||||||
guint is_fullscreen : 1;
|
guint is_fullscreen : 1;
|
||||||
guint is_offscreen : 1;
|
guint is_offscreen : 1;
|
||||||
guint is_cursor_visible : 1;
|
guint is_cursor_visible : 1;
|
||||||
guint is_user_resizable : 1;
|
guint is_user_resizable : 1;
|
||||||
guint use_fog : 1;
|
guint use_fog : 1;
|
||||||
|
|
||||||
gchar *title;
|
|
||||||
ClutterActor *key_focused_actor;
|
|
||||||
|
|
||||||
guint update_idle; /* repaint idler id */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
@ -98,11 +120,37 @@ enum
|
|||||||
|
|
||||||
static guint stage_signals[LAST_SIGNAL] = { 0, };
|
static guint stage_signals[LAST_SIGNAL] = { 0, };
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_stage_request_coords (ClutterActor *self,
|
||||||
|
ClutterActorBox *box)
|
||||||
|
{
|
||||||
|
ClutterStagePrivate *priv = CLUTTER_STAGE (self)->priv;
|
||||||
|
|
||||||
|
g_assert (priv->impl != NULL);
|
||||||
|
CLUTTER_ACTOR_GET_CLASS (priv->impl)->request_coords (priv->impl, box);
|
||||||
|
|
||||||
|
CLUTTER_ACTOR_CLASS (clutter_stage_parent_class)->request_coords (self, box);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_stage_query_coords (ClutterActor *self,
|
||||||
|
ClutterActorBox *box)
|
||||||
|
{
|
||||||
|
ClutterStagePrivate *priv = CLUTTER_STAGE (self)->priv;
|
||||||
|
|
||||||
|
g_assert (priv->impl != NULL);
|
||||||
|
CLUTTER_ACTOR_GET_CLASS (priv->impl)->query_coords (priv->impl, box);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_stage_paint (ClutterActor *self)
|
clutter_stage_paint (ClutterActor *self)
|
||||||
{
|
{
|
||||||
ClutterStagePrivate *priv = CLUTTER_STAGE (self)->priv;
|
ClutterStagePrivate *priv = CLUTTER_STAGE (self)->priv;
|
||||||
|
|
||||||
|
CLUTTER_SET_PRIVATE_FLAGS (self, CLUTTER_ACTOR_IN_PAINT);
|
||||||
|
|
||||||
|
CLUTTER_NOTE (PAINT, "Initializing stage paint");
|
||||||
|
|
||||||
cogl_paint_init (&priv->color);
|
cogl_paint_init (&priv->color);
|
||||||
|
|
||||||
if (priv->use_fog)
|
if (priv->use_fog)
|
||||||
@ -113,6 +161,12 @@ clutter_stage_paint (ClutterActor *self)
|
|||||||
priv->fog.z_far);
|
priv->fog.z_far);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CLUTTER_NOTE (PAINT, "Proxying the paint to the stage implementation");
|
||||||
|
clutter_actor_paint (priv->impl);
|
||||||
|
|
||||||
|
CLUTTER_UNSET_PRIVATE_FLAGS (self, CLUTTER_ACTOR_IN_PAINT);
|
||||||
|
|
||||||
|
/* this will take care of painting every child */
|
||||||
CLUTTER_ACTOR_CLASS (clutter_stage_parent_class)->paint (self);
|
CLUTTER_ACTOR_CLASS (clutter_stage_parent_class)->paint (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,6 +182,53 @@ clutter_stage_pick (ClutterActor *self,
|
|||||||
CLUTTER_ACTOR_CLASS (clutter_stage_parent_class)->paint (self);
|
CLUTTER_ACTOR_CLASS (clutter_stage_parent_class)->paint (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_stage_realize (ClutterActor *self)
|
||||||
|
{
|
||||||
|
ClutterStagePrivate *priv = CLUTTER_STAGE (self)->priv;
|
||||||
|
|
||||||
|
/* then realize the implementation */
|
||||||
|
CLUTTER_ACTOR_GET_CLASS (priv->impl)->realize (priv->impl);
|
||||||
|
|
||||||
|
/* set the flag on the wrapper if the implementation was successful */
|
||||||
|
if (CLUTTER_ACTOR_IS_REALIZED (priv->impl))
|
||||||
|
CLUTTER_ACTOR_SET_FLAGS (self, CLUTTER_ACTOR_REALIZED);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_stage_unrealize (ClutterActor *self)
|
||||||
|
{
|
||||||
|
ClutterStagePrivate *priv = CLUTTER_STAGE (self)->priv;
|
||||||
|
|
||||||
|
/* unset the flag */
|
||||||
|
CLUTTER_ACTOR_UNSET_FLAGS (self, CLUTTER_ACTOR_REALIZED);
|
||||||
|
|
||||||
|
/* and then unrealize the implementation */
|
||||||
|
CLUTTER_ACTOR_GET_CLASS (priv->impl)->unrealize (priv->impl);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_stage_show (ClutterActor *self)
|
||||||
|
{
|
||||||
|
ClutterStagePrivate *priv = CLUTTER_STAGE (self)->priv;
|
||||||
|
|
||||||
|
g_assert (priv->impl != NULL);
|
||||||
|
clutter_actor_show (priv->impl);
|
||||||
|
|
||||||
|
CLUTTER_ACTOR_CLASS (clutter_stage_parent_class)->show (self);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_stage_hide (ClutterActor *self)
|
||||||
|
{
|
||||||
|
ClutterStagePrivate *priv = CLUTTER_STAGE (self)->priv;
|
||||||
|
|
||||||
|
g_assert (priv->impl != NULL);
|
||||||
|
clutter_actor_hide (priv->impl);
|
||||||
|
|
||||||
|
CLUTTER_ACTOR_CLASS (clutter_stage_parent_class)->hide (self);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_stage_set_property (GObject *object,
|
clutter_stage_set_property (GObject *object,
|
||||||
guint prop_id,
|
guint prop_id,
|
||||||
@ -248,6 +349,24 @@ clutter_stage_get_property (GObject *object,
|
|||||||
static void
|
static void
|
||||||
clutter_stage_dispose (GObject *object)
|
clutter_stage_dispose (GObject *object)
|
||||||
{
|
{
|
||||||
|
ClutterStage *stage = CLUTTER_STAGE (object);
|
||||||
|
ClutterStagePrivate *priv = stage->priv;
|
||||||
|
ClutterStageManager *stage_manager = clutter_stage_manager_get_default ();
|
||||||
|
|
||||||
|
if (priv->update_idle)
|
||||||
|
{
|
||||||
|
g_source_remove (priv->update_idle);
|
||||||
|
priv->update_idle = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
_clutter_stage_manager_remove_stage (stage_manager, stage);
|
||||||
|
|
||||||
|
if (priv->impl)
|
||||||
|
{
|
||||||
|
CLUTTER_NOTE (MISC, "Disposing of the stage implementation");
|
||||||
|
g_object_unref (priv->impl);
|
||||||
|
priv->impl = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
G_OBJECT_CLASS (clutter_stage_parent_class)->dispose (object);
|
G_OBJECT_CLASS (clutter_stage_parent_class)->dispose (object);
|
||||||
}
|
}
|
||||||
@ -255,11 +374,6 @@ clutter_stage_dispose (GObject *object)
|
|||||||
static void
|
static void
|
||||||
clutter_stage_finalize (GObject *object)
|
clutter_stage_finalize (GObject *object)
|
||||||
{
|
{
|
||||||
ClutterStage *stage = CLUTTER_STAGE(object);
|
|
||||||
ClutterStageManager *stage_manager = clutter_stage_manager_get_default ();
|
|
||||||
|
|
||||||
_clutter_stage_manager_remove_stage (stage_manager, stage);
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (clutter_stage_parent_class)->finalize (object);
|
G_OBJECT_CLASS (clutter_stage_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -275,8 +389,14 @@ clutter_stage_class_init (ClutterStageClass *klass)
|
|||||||
gobject_class->dispose = clutter_stage_dispose;
|
gobject_class->dispose = clutter_stage_dispose;
|
||||||
gobject_class->finalize = clutter_stage_finalize;
|
gobject_class->finalize = clutter_stage_finalize;
|
||||||
|
|
||||||
|
actor_class->request_coords = clutter_stage_request_coords;
|
||||||
|
actor_class->query_coords = clutter_stage_query_coords;
|
||||||
actor_class->paint = clutter_stage_paint;
|
actor_class->paint = clutter_stage_paint;
|
||||||
actor_class->pick = clutter_stage_pick;
|
actor_class->pick = clutter_stage_pick;
|
||||||
|
actor_class->realize = clutter_stage_realize;
|
||||||
|
actor_class->unrealize = clutter_stage_unrealize;
|
||||||
|
actor_class->show = clutter_stage_show;
|
||||||
|
actor_class->hide = clutter_stage_hide;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ClutterStage:fullscreen:
|
* ClutterStage:fullscreen:
|
||||||
@ -447,12 +567,28 @@ static void
|
|||||||
clutter_stage_init (ClutterStage *self)
|
clutter_stage_init (ClutterStage *self)
|
||||||
{
|
{
|
||||||
ClutterStagePrivate *priv;
|
ClutterStagePrivate *priv;
|
||||||
|
ClutterBackend *backend;
|
||||||
|
|
||||||
/* a stage is a top-level object */
|
/* a stage is a top-level object */
|
||||||
CLUTTER_SET_PRIVATE_FLAGS (self, CLUTTER_ACTOR_IS_TOPLEVEL);
|
CLUTTER_SET_PRIVATE_FLAGS (self, CLUTTER_ACTOR_IS_TOPLEVEL);
|
||||||
|
|
||||||
self->priv = priv = CLUTTER_STAGE_GET_PRIVATE (self);
|
self->priv = priv = CLUTTER_STAGE_GET_PRIVATE (self);
|
||||||
|
|
||||||
|
CLUTTER_NOTE (BACKEND, "Creating stage from the default backend");
|
||||||
|
backend = clutter_get_default_backend ();
|
||||||
|
priv->impl = _clutter_backend_create_stage (backend, self, NULL);
|
||||||
|
if (!priv->impl)
|
||||||
|
{
|
||||||
|
g_warning ("Unable to create a new stage, falling back to the "
|
||||||
|
"default stage.");
|
||||||
|
priv->impl = CLUTTER_ACTOR (_clutter_stage_get_default_window ());
|
||||||
|
|
||||||
|
/* at this point we must have a default stage, or we're screwed */
|
||||||
|
g_assert (priv->impl != NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
g_object_ref_sink (priv->impl);
|
||||||
|
|
||||||
priv->is_offscreen = FALSE;
|
priv->is_offscreen = FALSE;
|
||||||
priv->is_fullscreen = FALSE;
|
priv->is_fullscreen = FALSE;
|
||||||
priv->is_user_resizable = FALSE;
|
priv->is_user_resizable = FALSE;
|
||||||
@ -482,11 +618,12 @@ clutter_stage_init (ClutterStage *self)
|
|||||||
/**
|
/**
|
||||||
* clutter_stage_get_default:
|
* clutter_stage_get_default:
|
||||||
*
|
*
|
||||||
* Returns the main stage. #ClutterStage is a singleton, so
|
* Returns the main stage. The default #ClutterStage is a singleton,
|
||||||
* the stage will be created the first time this function is
|
* so the stage will be created the first time this function is
|
||||||
* called (typically, inside clutter_init()); all the subsequent
|
* called (typically, inside clutter_init()); all the subsequent
|
||||||
* calls to clutter_stage_get_default() will return the same
|
* calls to clutter_stage_get_default() will return the same instance.
|
||||||
* instance.
|
*
|
||||||
|
* Clutter guarantess the existence of the default stage.
|
||||||
*
|
*
|
||||||
* Return value: the main #ClutterStage. You should never
|
* Return value: the main #ClutterStage. You should never
|
||||||
* destroy or unref the returned actor.
|
* destroy or unref the returned actor.
|
||||||
@ -495,8 +632,19 @@ ClutterActor *
|
|||||||
clutter_stage_get_default (void)
|
clutter_stage_get_default (void)
|
||||||
{
|
{
|
||||||
ClutterStageManager *stage_manager = clutter_stage_manager_get_default ();
|
ClutterStageManager *stage_manager = clutter_stage_manager_get_default ();
|
||||||
|
ClutterStage *stage;
|
||||||
|
|
||||||
return CLUTTER_ACTOR(clutter_stage_manager_get_default_stage(stage_manager));
|
stage = clutter_stage_manager_get_default_stage (stage_manager);
|
||||||
|
if (G_UNLIKELY (stage == NULL))
|
||||||
|
{
|
||||||
|
/* this will take care of automatically adding the stage
|
||||||
|
* to the stage manager and setting it as the default
|
||||||
|
*/
|
||||||
|
stage = g_object_new (CLUTTER_TYPE_STAGE, NULL);
|
||||||
|
g_object_ref_sink (stage);
|
||||||
|
}
|
||||||
|
|
||||||
|
return CLUTTER_ACTOR (stage);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -516,10 +664,8 @@ clutter_stage_set_color (ClutterStage *stage,
|
|||||||
g_return_if_fail (color != NULL);
|
g_return_if_fail (color != NULL);
|
||||||
|
|
||||||
priv = stage->priv;
|
priv = stage->priv;
|
||||||
priv->color.red = color->red;
|
|
||||||
priv->color.green = color->green;
|
priv->color = *color;
|
||||||
priv->color.blue = color->blue;
|
|
||||||
priv->color.alpha = color->alpha;
|
|
||||||
|
|
||||||
if (CLUTTER_ACTOR_IS_VISIBLE (stage))
|
if (CLUTTER_ACTOR_IS_VISIBLE (stage))
|
||||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
|
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
|
||||||
@ -545,10 +691,7 @@ clutter_stage_get_color (ClutterStage *stage,
|
|||||||
|
|
||||||
priv = stage->priv;
|
priv = stage->priv;
|
||||||
|
|
||||||
color->red = priv->color.red;
|
*color = priv->color;
|
||||||
color->green = priv->color.green;
|
|
||||||
color->blue = priv->color.blue;
|
|
||||||
color->alpha = priv->color.alpha;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -572,6 +715,9 @@ clutter_stage_set_perspectivex (ClutterStage *stage,
|
|||||||
|
|
||||||
priv->perspective = *perspective;
|
priv->perspective = *perspective;
|
||||||
|
|
||||||
|
/* this will cause the viewport to be reset; see
|
||||||
|
* clutter_maybe_setup_viewport() inside clutter-main.c
|
||||||
|
*/
|
||||||
CLUTTER_SET_PRIVATE_FLAGS (stage, CLUTTER_ACTOR_SYNC_MATRICES);
|
CLUTTER_SET_PRIVATE_FLAGS (stage, CLUTTER_ACTOR_SYNC_MATRICES);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -604,7 +750,7 @@ clutter_stage_get_perspectivex (ClutterStage *stage,
|
|||||||
* @z_far: the distance from the viewer to the far clipping
|
* @z_far: the distance from the viewer to the far clipping
|
||||||
* plane (always positive)
|
* plane (always positive)
|
||||||
*
|
*
|
||||||
* Set the stage perspective.
|
* Sets the stage perspective.
|
||||||
*
|
*
|
||||||
* Since: 0.4
|
* Since: 0.4
|
||||||
*/
|
*/
|
||||||
@ -621,11 +767,14 @@ clutter_stage_set_perspective (ClutterStage *stage,
|
|||||||
|
|
||||||
priv = stage->priv;
|
priv = stage->priv;
|
||||||
|
|
||||||
priv->perspective.fovy = CLUTTER_FLOAT_TO_FIXED(fovy);
|
priv->perspective.fovy = CLUTTER_FLOAT_TO_FIXED (fovy);
|
||||||
priv->perspective.aspect = CLUTTER_FLOAT_TO_FIXED(aspect);
|
priv->perspective.aspect = CLUTTER_FLOAT_TO_FIXED (aspect);
|
||||||
priv->perspective.z_near = CLUTTER_FLOAT_TO_FIXED(z_near);
|
priv->perspective.z_near = CLUTTER_FLOAT_TO_FIXED (z_near);
|
||||||
priv->perspective.z_far = CLUTTER_FLOAT_TO_FIXED(z_far);
|
priv->perspective.z_far = CLUTTER_FLOAT_TO_FIXED (z_far);
|
||||||
|
|
||||||
|
/* this will cause the viewport to be reset; see
|
||||||
|
* clutter_maybe_setup_viewport() inside clutter-main.c
|
||||||
|
*/
|
||||||
CLUTTER_SET_PRIVATE_FLAGS (stage, CLUTTER_ACTOR_SYNC_MATRICES);
|
CLUTTER_SET_PRIVATE_FLAGS (stage, CLUTTER_ACTOR_SYNC_MATRICES);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -688,12 +837,17 @@ clutter_stage_fullscreen (ClutterStage *stage)
|
|||||||
priv = stage->priv;
|
priv = stage->priv;
|
||||||
if (!priv->is_fullscreen)
|
if (!priv->is_fullscreen)
|
||||||
{
|
{
|
||||||
|
ClutterStageWindow *impl = CLUTTER_STAGE_WINDOW (priv->impl);
|
||||||
|
ClutterStageWindowIface *iface;
|
||||||
|
|
||||||
|
iface = CLUTTER_STAGE_WINDOW_GET_IFACE (impl);
|
||||||
|
|
||||||
/* Only set if backend implements.
|
/* Only set if backend implements.
|
||||||
* Also see clutter_stage_event() for setting priv->is_fullscreen
|
* Also see clutter_stage_event() for setting priv->is_fullscreen
|
||||||
* on state change event.
|
* on state change event.
|
||||||
*/
|
*/
|
||||||
if (CLUTTER_STAGE_GET_CLASS (stage)->set_fullscreen)
|
if (iface->set_fullscreen)
|
||||||
CLUTTER_STAGE_GET_CLASS (stage)->set_fullscreen (stage, TRUE);
|
iface->set_fullscreen (impl, TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -717,9 +871,17 @@ clutter_stage_unfullscreen (ClutterStage *stage)
|
|||||||
priv = stage->priv;
|
priv = stage->priv;
|
||||||
if (priv->is_fullscreen)
|
if (priv->is_fullscreen)
|
||||||
{
|
{
|
||||||
/* Only set if backend implements */
|
ClutterStageWindow *impl = CLUTTER_STAGE_WINDOW (priv->impl);
|
||||||
if (CLUTTER_STAGE_GET_CLASS (stage)->set_fullscreen)
|
ClutterStageWindowIface *iface;
|
||||||
CLUTTER_STAGE_GET_CLASS (stage)->set_fullscreen (stage, FALSE);
|
|
||||||
|
iface = CLUTTER_STAGE_WINDOW_GET_IFACE (impl);
|
||||||
|
|
||||||
|
/* Only set if backend implements.
|
||||||
|
* Also see clutter_stage_event() for setting priv->is_fullscreen
|
||||||
|
* on state change event.
|
||||||
|
*/
|
||||||
|
if (iface->set_fullscreen)
|
||||||
|
iface->set_fullscreen (impl, FALSE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -744,14 +906,20 @@ clutter_stage_set_user_resizable (ClutterStage *stage,
|
|||||||
priv = stage->priv;
|
priv = stage->priv;
|
||||||
|
|
||||||
if (clutter_feature_available (CLUTTER_FEATURE_STAGE_USER_RESIZE)
|
if (clutter_feature_available (CLUTTER_FEATURE_STAGE_USER_RESIZE)
|
||||||
&& priv->is_user_resizable != resizable
|
&& priv->is_user_resizable != resizable)
|
||||||
&& CLUTTER_STAGE_GET_CLASS (stage)->set_user_resize)
|
|
||||||
{
|
{
|
||||||
priv->is_user_resizable = resizable;
|
ClutterStageWindow *impl = CLUTTER_STAGE_WINDOW (priv->impl);
|
||||||
|
ClutterStageWindowIface *iface;
|
||||||
|
|
||||||
CLUTTER_STAGE_GET_CLASS (stage)->set_user_resize (stage, resizable);
|
iface = CLUTTER_STAGE_WINDOW_GET_IFACE (impl);
|
||||||
|
if (iface->set_user_resizable)
|
||||||
|
{
|
||||||
|
priv->is_user_resizable = resizable;
|
||||||
|
|
||||||
g_object_notify (G_OBJECT (stage), "user-resizable");
|
iface->set_user_resizable (impl, resizable);
|
||||||
|
|
||||||
|
g_object_notify (G_OBJECT (stage), "user-resizable");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -789,12 +957,18 @@ clutter_stage_show_cursor (ClutterStage *stage)
|
|||||||
priv = stage->priv;
|
priv = stage->priv;
|
||||||
if (!priv->is_cursor_visible)
|
if (!priv->is_cursor_visible)
|
||||||
{
|
{
|
||||||
priv->is_cursor_visible = TRUE;
|
ClutterStageWindow *impl = CLUTTER_STAGE_WINDOW (priv->impl);
|
||||||
|
ClutterStageWindowIface *iface;
|
||||||
|
|
||||||
if (CLUTTER_STAGE_GET_CLASS (stage)->set_cursor_visible)
|
iface = CLUTTER_STAGE_WINDOW_GET_IFACE (impl);
|
||||||
CLUTTER_STAGE_GET_CLASS (stage)->set_cursor_visible (stage, TRUE);
|
if (iface->set_cursor_visible)
|
||||||
|
{
|
||||||
|
priv->is_cursor_visible = TRUE;
|
||||||
|
|
||||||
g_object_notify (G_OBJECT (stage), "cursor-visible");
|
iface->set_cursor_visible (impl, TRUE);
|
||||||
|
|
||||||
|
g_object_notify (G_OBJECT (stage), "cursor-visible");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -816,12 +990,18 @@ clutter_stage_hide_cursor (ClutterStage *stage)
|
|||||||
priv = stage->priv;
|
priv = stage->priv;
|
||||||
if (priv->is_cursor_visible)
|
if (priv->is_cursor_visible)
|
||||||
{
|
{
|
||||||
priv->is_cursor_visible = FALSE;
|
ClutterStageWindow *impl = CLUTTER_STAGE_WINDOW (priv->impl);
|
||||||
|
ClutterStageWindowIface *iface;
|
||||||
|
|
||||||
if (CLUTTER_STAGE_GET_CLASS (stage)->set_cursor_visible)
|
iface = CLUTTER_STAGE_WINDOW_GET_IFACE (impl);
|
||||||
CLUTTER_STAGE_GET_CLASS (stage)->set_cursor_visible (stage, FALSE);
|
if (iface->set_cursor_visible)
|
||||||
|
{
|
||||||
|
priv->is_cursor_visible = TRUE;
|
||||||
|
|
||||||
g_object_notify (G_OBJECT (stage), "cursor-visible");
|
iface->set_cursor_visible (impl, FALSE);
|
||||||
|
|
||||||
|
g_object_notify (G_OBJECT (stage), "cursor-visible");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -837,8 +1017,9 @@ clutter_stage_hide_cursor (ClutterStage *stage)
|
|||||||
*
|
*
|
||||||
* Gets a pixel based representation of the current rendered stage.
|
* Gets a pixel based representation of the current rendered stage.
|
||||||
*
|
*
|
||||||
* Return value: pixel representation as a #GdkPixbuf
|
* Return value: pixel representation as a #GdkPixbuf, or %NULL if
|
||||||
**/
|
* the backend does not support this operation
|
||||||
|
*/
|
||||||
GdkPixbuf *
|
GdkPixbuf *
|
||||||
clutter_stage_snapshot (ClutterStage *stage,
|
clutter_stage_snapshot (ClutterStage *stage,
|
||||||
gint x,
|
gint x,
|
||||||
@ -846,14 +1027,17 @@ clutter_stage_snapshot (ClutterStage *stage,
|
|||||||
gint width,
|
gint width,
|
||||||
gint height)
|
gint height)
|
||||||
{
|
{
|
||||||
ClutterStageClass *klass;
|
ClutterStageWindow *impl;
|
||||||
|
ClutterStageWindowIface *iface;
|
||||||
|
|
||||||
g_return_val_if_fail (CLUTTER_IS_STAGE (stage), NULL);
|
g_return_val_if_fail (CLUTTER_IS_STAGE (stage), NULL);
|
||||||
g_return_val_if_fail (x >= 0 && y >= 0, NULL);
|
g_return_val_if_fail (x >= 0 && y >= 0, NULL);
|
||||||
|
|
||||||
klass = CLUTTER_STAGE_GET_CLASS (stage);
|
impl = CLUTTER_STAGE_WINDOW (stage->priv->impl);
|
||||||
if (klass->draw_to_pixbuf)
|
iface = CLUTTER_STAGE_WINDOW_GET_IFACE (impl);
|
||||||
return klass->draw_to_pixbuf (stage, x, y, width, height);
|
|
||||||
|
if (iface->draw_to_pixbuf)
|
||||||
|
return iface->draw_to_pixbuf (impl, x, y, width, height);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -883,8 +1067,9 @@ clutter_stage_get_actor_at_pos (ClutterStage *stage,
|
|||||||
* @event: a #ClutterEvent
|
* @event: a #ClutterEvent
|
||||||
*
|
*
|
||||||
* This function is used to emit an event on the main stage.
|
* This function is used to emit an event on the main stage.
|
||||||
|
*
|
||||||
* You should rarely need to use this function, except for
|
* You should rarely need to use this function, except for
|
||||||
* synthetising events.
|
* synthetised events.
|
||||||
*
|
*
|
||||||
* Return value: the return value from the signal emission
|
* Return value: the return value from the signal emission
|
||||||
*
|
*
|
||||||
@ -960,6 +1145,7 @@ clutter_stage_set_title (ClutterStage *stage,
|
|||||||
const gchar *title)
|
const gchar *title)
|
||||||
{
|
{
|
||||||
ClutterStagePrivate *priv;
|
ClutterStagePrivate *priv;
|
||||||
|
ClutterStageWindow *impl;
|
||||||
|
|
||||||
g_return_if_fail (CLUTTER_IS_STAGE (stage));
|
g_return_if_fail (CLUTTER_IS_STAGE (stage));
|
||||||
|
|
||||||
@ -968,8 +1154,8 @@ clutter_stage_set_title (ClutterStage *stage,
|
|||||||
g_free (priv->title);
|
g_free (priv->title);
|
||||||
priv->title = g_strdup (title);
|
priv->title = g_strdup (title);
|
||||||
|
|
||||||
if (CLUTTER_STAGE_GET_CLASS (stage)->set_title)
|
impl = CLUTTER_STAGE_WINDOW (priv->impl);
|
||||||
CLUTTER_STAGE_GET_CLASS (stage)->set_title (stage, priv->title);
|
CLUTTER_STAGE_WINDOW_GET_IFACE (impl)->set_title (impl, priv->title);
|
||||||
|
|
||||||
g_object_notify (G_OBJECT (stage), "title");
|
g_object_notify (G_OBJECT (stage), "title");
|
||||||
}
|
}
|
||||||
@ -1373,7 +1559,7 @@ clutter_fog_get_type (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* clutter_stage_create_new:
|
* clutter_stage_new:
|
||||||
*
|
*
|
||||||
* Creates a new, non-default stage. A non-default stage is a new
|
* Creates a new, non-default stage. A non-default stage is a new
|
||||||
* top-level actor which can be used as another container. It works
|
* top-level actor which can be used as another container. It works
|
||||||
@ -1388,15 +1574,13 @@ clutter_fog_get_type (void)
|
|||||||
*
|
*
|
||||||
* Return value: a new stage, or %NULL if the default backend does
|
* Return value: a new stage, or %NULL if the default backend does
|
||||||
* not support multiple stages. Use clutter_actor_destroy() to
|
* not support multiple stages. Use clutter_actor_destroy() to
|
||||||
* close the returned stage.
|
* programmatically close the returned stage.
|
||||||
*
|
*
|
||||||
* Since: 0.8
|
* Since: 0.8
|
||||||
*/
|
*/
|
||||||
ClutterActor*
|
ClutterActor *
|
||||||
clutter_stage_create_new (void)
|
clutter_stage_new (void)
|
||||||
{
|
{
|
||||||
ClutterBackend *backend = clutter_get_default_backend ();
|
|
||||||
GError *error = NULL;
|
|
||||||
ClutterActor *retval;
|
ClutterActor *retval;
|
||||||
|
|
||||||
if (!clutter_feature_available (CLUTTER_FEATURE_STAGE_MULTIPLE))
|
if (!clutter_feature_available (CLUTTER_FEATURE_STAGE_MULTIPLE))
|
||||||
@ -1407,15 +1591,11 @@ clutter_stage_create_new (void)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
retval = _clutter_backend_create_stage (backend, &error);
|
retval = g_object_new (CLUTTER_TYPE_STAGE, NULL);
|
||||||
if (error)
|
if (retval)
|
||||||
{
|
return g_object_ref_sink (retval);
|
||||||
g_warning ("Unable to create a secondary stage: %s", error->message);
|
|
||||||
g_error_free (error);
|
|
||||||
retval = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return retval;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1431,24 +1611,23 @@ clutter_stage_create_new (void)
|
|||||||
void
|
void
|
||||||
clutter_stage_ensure_current (ClutterStage *stage)
|
clutter_stage_ensure_current (ClutterStage *stage)
|
||||||
{
|
{
|
||||||
ClutterMainContext *ctx;
|
ClutterMainContext *ctx = clutter_context_get_default ();
|
||||||
|
|
||||||
g_return_if_fail (CLUTTER_IS_STAGE (stage));
|
g_return_if_fail (CLUTTER_IS_STAGE (stage));
|
||||||
|
|
||||||
ctx = clutter_context_get_default ();
|
|
||||||
|
|
||||||
_clutter_backend_ensure_context (ctx->backend, stage);
|
_clutter_backend_ensure_context (ctx->backend, stage);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
redraw_update_idle (gpointer data)
|
redraw_update_idle (gpointer user_data)
|
||||||
{
|
{
|
||||||
ClutterStage *stage = CLUTTER_STAGE(data);
|
ClutterStage *stage = user_data;
|
||||||
|
ClutterStagePrivate *priv = stage->priv;
|
||||||
|
|
||||||
if (stage->priv->update_idle)
|
if (priv->update_idle)
|
||||||
{
|
{
|
||||||
g_source_remove (stage->priv->update_idle);
|
g_source_remove (priv->update_idle);
|
||||||
stage->priv->update_idle = 0;
|
priv->update_idle = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
CLUTTER_NOTE (MULTISTAGE, "redrawing via idle for stage:%p", stage);
|
CLUTTER_NOTE (MULTISTAGE, "redrawing via idle for stage:%p", stage);
|
||||||
@ -1461,8 +1640,10 @@ redraw_update_idle (gpointer data)
|
|||||||
* clutter_stage_queue_redraw:
|
* clutter_stage_queue_redraw:
|
||||||
* @stage: the #ClutterStage
|
* @stage: the #ClutterStage
|
||||||
*
|
*
|
||||||
* Queues a redraw for the passed stage. Note applications should call
|
* Queues a redraw for the passed stage.
|
||||||
* #clutter_actor_queue_redraw over this.
|
*
|
||||||
|
* <note>Applications should call clutter_actor_queue_redraw() and not
|
||||||
|
* this function.</note>
|
||||||
*
|
*
|
||||||
* Since: 0.8
|
* Since: 0.8
|
||||||
*/
|
*/
|
||||||
@ -1483,3 +1664,32 @@ clutter_stage_queue_redraw (ClutterStage *stage)
|
|||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_clutter_stage_set_window (ClutterStage *stage,
|
||||||
|
ClutterStageWindow *stage_window)
|
||||||
|
{
|
||||||
|
g_return_if_fail (CLUTTER_IS_STAGE (stage));
|
||||||
|
g_return_if_fail (CLUTTER_IS_STAGE_WINDOW (stage_window));
|
||||||
|
|
||||||
|
if (stage->priv->impl)
|
||||||
|
g_object_unref (stage->priv->impl);
|
||||||
|
|
||||||
|
stage->priv->impl = CLUTTER_ACTOR (stage_window);
|
||||||
|
}
|
||||||
|
|
||||||
|
ClutterStageWindow *
|
||||||
|
_clutter_stage_get_window (ClutterStage *stage)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (CLUTTER_IS_STAGE (stage), NULL);
|
||||||
|
|
||||||
|
return CLUTTER_STAGE_WINDOW (stage->priv->impl);
|
||||||
|
}
|
||||||
|
|
||||||
|
ClutterStageWindow *
|
||||||
|
_clutter_stage_get_default_window (void)
|
||||||
|
{
|
||||||
|
ClutterActor *stage = clutter_stage_get_default ();
|
||||||
|
|
||||||
|
return _clutter_stage_get_window (CLUTTER_STAGE (stage));
|
||||||
|
}
|
||||||
|
@ -99,26 +99,11 @@ struct _ClutterStageClass
|
|||||||
ClutterGroupClass parent_class;
|
ClutterGroupClass parent_class;
|
||||||
|
|
||||||
/*< public >*/
|
/*< public >*/
|
||||||
/* vfuncs, not signals */
|
/* signals */
|
||||||
void (* set_fullscreen) (ClutterStage *stage,
|
void (* fullscreen) (ClutterStage *stage);
|
||||||
gboolean fullscreen);
|
void (* unfullscreen) (ClutterStage *stage);
|
||||||
void (* set_cursor_visible) (ClutterStage *stage,
|
void (* activate) (ClutterStage *stage);
|
||||||
gboolean visible);
|
void (* deactivate) (ClutterStage *stage);
|
||||||
GdkPixbuf* (* draw_to_pixbuf) (ClutterStage *stage,
|
|
||||||
gint x,
|
|
||||||
gint y,
|
|
||||||
gint width,
|
|
||||||
gint height);
|
|
||||||
void (* set_title) (ClutterStage *stage,
|
|
||||||
const gchar *title);
|
|
||||||
void (* set_user_resize) (ClutterStage *stage,
|
|
||||||
gboolean value);
|
|
||||||
|
|
||||||
/* events */
|
|
||||||
void (* fullscreen) (ClutterStage *stage);
|
|
||||||
void (* unfullscreen) (ClutterStage *stage);
|
|
||||||
void (* activate) (ClutterStage *stage);
|
|
||||||
void (* deactivate) (ClutterStage *stage);
|
|
||||||
|
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
/* padding for future expansion */
|
/* padding for future expansion */
|
||||||
@ -175,6 +160,8 @@ GType clutter_fog_get_type (void) G_GNUC_CONST;
|
|||||||
GType clutter_stage_get_type (void) G_GNUC_CONST;
|
GType clutter_stage_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
ClutterActor *clutter_stage_get_default (void);
|
ClutterActor *clutter_stage_get_default (void);
|
||||||
|
ClutterActor *clutter_stage_new (void);
|
||||||
|
|
||||||
void clutter_stage_set_color (ClutterStage *stage,
|
void clutter_stage_set_color (ClutterStage *stage,
|
||||||
const ClutterColor *color);
|
const ClutterColor *color);
|
||||||
void clutter_stage_get_color (ClutterStage *stage,
|
void clutter_stage_get_color (ClutterStage *stage,
|
||||||
@ -233,15 +220,12 @@ void clutter_stage_get_fogx (ClutterStage *stage,
|
|||||||
gdouble clutter_stage_get_resolution (ClutterStage *stage);
|
gdouble clutter_stage_get_resolution (ClutterStage *stage);
|
||||||
ClutterFixed clutter_stage_get_resolutionx (ClutterStage *stage);
|
ClutterFixed clutter_stage_get_resolutionx (ClutterStage *stage);
|
||||||
|
|
||||||
/* New experiental calls */
|
|
||||||
void clutter_stage_set_key_focus (ClutterStage *stage,
|
void clutter_stage_set_key_focus (ClutterStage *stage,
|
||||||
ClutterActor *actor);
|
ClutterActor *actor);
|
||||||
ClutterActor * clutter_stage_get_key_focus (ClutterStage *stage);
|
ClutterActor * clutter_stage_get_key_focus (ClutterStage *stage);
|
||||||
|
|
||||||
ClutterActor* clutter_stage_create_new (void);
|
/* New experiental calls */
|
||||||
|
|
||||||
void clutter_stage_ensure_current (ClutterStage *stage);
|
void clutter_stage_ensure_current (ClutterStage *stage);
|
||||||
|
|
||||||
void clutter_stage_queue_redraw (ClutterStage *stage);
|
void clutter_stage_queue_redraw (ClutterStage *stage);
|
||||||
|
|
||||||
/* Commodity macro */
|
/* Commodity macro */
|
||||||
|
@ -23,11 +23,12 @@ clutter_backend_egl_post_parse (ClutterBackend *backend,
|
|||||||
{
|
{
|
||||||
EGLBoolean status;
|
EGLBoolean status;
|
||||||
|
|
||||||
backend_egl->edpy = eglGetDisplay((NativeDisplayType)backend_x11->xdpy);
|
backend_egl->edpy =
|
||||||
|
eglGetDisplay ((NativeDisplayType) backend_x11->xdpy);
|
||||||
|
|
||||||
status = eglInitialize(backend_egl->edpy,
|
status = eglInitialize (backend_egl->edpy,
|
||||||
&backend_egl->egl_version_major,
|
&backend_egl->egl_version_major,
|
||||||
&backend_egl->egl_version_minor);
|
&backend_egl->egl_version_minor);
|
||||||
|
|
||||||
if (status != EGL_TRUE)
|
if (status != EGL_TRUE)
|
||||||
{
|
{
|
||||||
@ -47,17 +48,80 @@ clutter_backend_egl_post_parse (ClutterBackend *backend,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_backend_egl_redraw (ClutterBackend *backend)
|
clutter_backend_egl_ensure_context (ClutterBackend *backend,
|
||||||
|
ClutterStage *stage)
|
||||||
{
|
{
|
||||||
ClutterBackendEGL *backend_egl = CLUTTER_BACKEND_EGL (backend);
|
ClutterBackendEGL *backend_egl = CLUTTER_BACKEND_EGL (backend);
|
||||||
ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend);
|
|
||||||
ClutterStageEGL *stage_egl;
|
|
||||||
ClutterStageX11 *stage_x11;
|
|
||||||
|
|
||||||
stage_x11 = CLUTTER_STAGE_X11(backend_x11->stage);
|
if (stage == NULL)
|
||||||
stage_egl = CLUTTER_STAGE_EGL(backend_x11->stage);
|
{
|
||||||
|
CLUTTER_NOTE (BACKEND, "Clearing EGL context");
|
||||||
|
eglMakeCurrent (backend_egl->edpy,
|
||||||
|
EGL_NO_SURFACE,
|
||||||
|
EGL_NO_SURFACE,
|
||||||
|
EGL_NO_CONTEXT);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ClutterStageWindow *impl;
|
||||||
|
ClutterStageEGL *stage_egl;
|
||||||
|
ClutterStageX11 *stage_x11;
|
||||||
|
|
||||||
clutter_actor_paint (CLUTTER_ACTOR(stage_egl));
|
impl = _clutter_stage_get_window (stage);
|
||||||
|
g_assert (impl != NULL);
|
||||||
|
|
||||||
|
CLUTTER_NOTE (MULTISTAGE, "Setting context for stage of type %s [%p]",
|
||||||
|
g_type_name (G_OBJECT_TYPE (impl)),
|
||||||
|
impl);
|
||||||
|
|
||||||
|
stage_egl = CLUTTER_STAGE_EGL (impl);
|
||||||
|
stage_x11 = CLUTTER_STAGE_X11 (impl);
|
||||||
|
|
||||||
|
g_return_if_fail (backend_egl->egl_context != NULL);
|
||||||
|
|
||||||
|
/* we might get here inside the final dispose cycle, so we
|
||||||
|
* need to handle this gracefully
|
||||||
|
*/
|
||||||
|
if (stage_x11->xwin == None ||
|
||||||
|
stage_egl->egl_surface == EGL_NO_SURFACE)
|
||||||
|
{
|
||||||
|
CLUTTER_NOTE (MULTISTAGE,
|
||||||
|
"Received a stale stage, clearing all context");
|
||||||
|
|
||||||
|
eglMakeCurrent (backend_egl->edpy,
|
||||||
|
EGL_NO_SURFACE,
|
||||||
|
EGL_NO_SURFACE,
|
||||||
|
EGL_NO_CONTEXT);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
eglMakeCurrent (backend_egl->edpy,
|
||||||
|
stage_egl->egl_surface,
|
||||||
|
stage_egl->egl_surface,
|
||||||
|
backend_egl->egl_context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_backend_egl_redraw (ClutterBackend *backend,
|
||||||
|
ClutterStage *stage)
|
||||||
|
{
|
||||||
|
ClutterBackendEGL *backend_egl = CLUTTER_BACKEND_EGL (backend);
|
||||||
|
ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend);
|
||||||
|
ClutterStageWindow *impl;
|
||||||
|
ClutterStageEGL *stage_egl;
|
||||||
|
ClutterStageX11 *stage_x11;
|
||||||
|
|
||||||
|
impl = _clutter_stage_get_window (stage);
|
||||||
|
if (!impl)
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_assert (CLUTTER_IS_STAGE_EGL (impl));
|
||||||
|
|
||||||
|
stage_x11 = CLUTTER_STAGE_X11 (impl);
|
||||||
|
stage_egl = CLUTTER_STAGE_EGL (impl);
|
||||||
|
|
||||||
|
/* this will cause the stage implementation to be painted as well */
|
||||||
|
clutter_actor_paint (CLUTTER_ACTOR (stage));
|
||||||
|
|
||||||
/* Why this paint is done in backend as likely GL windowing system
|
/* Why this paint is done in backend as likely GL windowing system
|
||||||
* specific calls, like swapping buffers.
|
* specific calls, like swapping buffers.
|
||||||
@ -88,6 +152,12 @@ clutter_backend_egl_dispose (GObject *gobject)
|
|||||||
{
|
{
|
||||||
ClutterBackendEGL *backend_egl = CLUTTER_BACKEND_EGL (gobject);
|
ClutterBackendEGL *backend_egl = CLUTTER_BACKEND_EGL (gobject);
|
||||||
|
|
||||||
|
if (backend_egl->egl_context)
|
||||||
|
{
|
||||||
|
eglDestroyContext (backend_egl->edpy, backend_egl->egl_context);
|
||||||
|
backend_egl->egl_context = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (backend_egl->edpy)
|
if (backend_egl->edpy)
|
||||||
{
|
{
|
||||||
eglTerminate (backend_egl->edpy);
|
eglTerminate (backend_egl->edpy);
|
||||||
@ -133,46 +203,46 @@ clutter_backend_egl_get_features (ClutterBackend *backend)
|
|||||||
"EGL_VENDOR: %s\n",
|
"EGL_VENDOR: %s\n",
|
||||||
"EGL_VERSION: %s\n",
|
"EGL_VERSION: %s\n",
|
||||||
"EGL_EXTENSIONS: %s\n",
|
"EGL_EXTENSIONS: %s\n",
|
||||||
glGetString(GL_VENDOR),
|
glGetString (GL_VENDOR),
|
||||||
glGetString(GL_RENDERER),
|
glGetString (GL_RENDERER),
|
||||||
glGetString(GL_VERSION),
|
glGetString (GL_VERSION),
|
||||||
eglQueryString(backend_egl->edpy, EGL_VENDOR),
|
eglQueryString (backend_egl->edpy, EGL_VENDOR),
|
||||||
eglQueryString(backend_egl->edpy, EGL_VERSION),
|
eglQueryString (backend_egl->edpy, EGL_VERSION),
|
||||||
eglQueryString(backend_egl->edpy, EGL_EXTENSIONS));
|
eglQueryString (backend_egl->edpy, EGL_EXTENSIONS));
|
||||||
|
|
||||||
/* We can actually resize too */
|
/* We can actually resize too */
|
||||||
return CLUTTER_FEATURE_STAGE_CURSOR|CLUTTER_FEATURE_STAGE_MULTIPLE;
|
return CLUTTER_FEATURE_STAGE_CURSOR|CLUTTER_FEATURE_STAGE_MULTIPLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static ClutterActor *
|
||||||
clutter_backend_egl_init_stage (ClutterBackend *backend,
|
clutter_backend_egl_create_stage (ClutterBackend *backend,
|
||||||
GError **error)
|
ClutterStage *wrapper,
|
||||||
|
GError **error)
|
||||||
{
|
{
|
||||||
ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend);
|
ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend);
|
||||||
|
|
||||||
if (!backend_x11->stage)
|
CLUTTER_NOTE (BACKEND, "Creating stage of type `%s'",
|
||||||
{
|
g_type_name (CLUTTER_STAGE_TYPE));
|
||||||
ClutterStageX11 *stage_x11;
|
|
||||||
ClutterActor *stage;
|
|
||||||
|
|
||||||
stage = g_object_new (CLUTTER_TYPE_STAGE_EGL, NULL);
|
stage = g_object_new (CLUTTER_STAGE_TYPE, NULL);
|
||||||
|
|
||||||
/* copy backend data into the stage */
|
/* copy backend data into the stage */
|
||||||
stage_x11 = CLUTTER_STAGE_X11 (stage);
|
stage_x11 = CLUTTER_STAGE_X11 (stage);
|
||||||
stage_x11->xdpy = backend_x11->xdpy;
|
stage_x11->xdpy = backend_x11->xdpy;
|
||||||
stage_x11->xwin_root = backend_x11->xwin_root;
|
stage_x11->xwin_root = backend_x11->xwin_root;
|
||||||
stage_x11->xscreen = backend_x11->xscreen_num;
|
stage_x11->xscreen = backend_x11->xscreen_num;
|
||||||
stage_x11->backend = backend_x11;
|
stage_x11->backend = backend_x11;
|
||||||
|
stage_x11->wrapper = wrapper;
|
||||||
|
|
||||||
CLUTTER_NOTE (MISC, "X11 stage created (display:%p, screen:%d, root:%u)",
|
/* set the pointer back into the wrapper */
|
||||||
stage_x11->xdpy,
|
_clutter_stage_set_window (wrapper, CLUTTER_STAGE_WINDOW (stage));
|
||||||
stage_x11->xscreen,
|
|
||||||
(unsigned int) stage_x11->xwin_root);
|
|
||||||
|
|
||||||
g_object_set_data (G_OBJECT (stage), "clutter-backend", backend);
|
CLUTTER_NOTE (MISC, "EGLX stage created (display:%p, screen:%d, root:%u)",
|
||||||
|
stage_x11->xdpy,
|
||||||
|
stage_x11->xscreen,
|
||||||
|
(unsigned int) stage_x11->xwin_root);
|
||||||
|
|
||||||
backend_x11->stage = g_object_ref_sink (stage);
|
g_object_set_data (G_OBJECT (stage), "clutter-backend", backend);
|
||||||
}
|
|
||||||
|
|
||||||
clutter_actor_realize (backend_x11->stage);
|
clutter_actor_realize (backend_x11->stage);
|
||||||
|
|
||||||
@ -181,10 +251,11 @@ clutter_backend_egl_init_stage (ClutterBackend *backend,
|
|||||||
g_set_error (error, CLUTTER_INIT_ERROR,
|
g_set_error (error, CLUTTER_INIT_ERROR,
|
||||||
CLUTTER_INIT_ERROR_INTERNAL,
|
CLUTTER_INIT_ERROR_INTERNAL,
|
||||||
"Unable to realize the main stage");
|
"Unable to realize the main stage");
|
||||||
return FALSE;
|
g_object_unref (stage);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return stage;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -194,19 +265,20 @@ clutter_backend_egl_class_init (ClutterBackendEGLClass *klass)
|
|||||||
ClutterBackendClass *backend_class = CLUTTER_BACKEND_CLASS (klass);
|
ClutterBackendClass *backend_class = CLUTTER_BACKEND_CLASS (klass);
|
||||||
|
|
||||||
gobject_class->constructor = clutter_backend_egl_constructor;
|
gobject_class->constructor = clutter_backend_egl_constructor;
|
||||||
gobject_class->dispose = clutter_backend_egl_dispose;
|
gobject_class->dispose = clutter_backend_egl_dispose;
|
||||||
gobject_class->finalize = clutter_backend_egl_finalize;
|
gobject_class->finalize = clutter_backend_egl_finalize;
|
||||||
|
|
||||||
backend_class->post_parse = clutter_backend_egl_post_parse;
|
backend_class->post_parse = clutter_backend_egl_post_parse;
|
||||||
backend_class->redraw = clutter_backend_egl_redraw;
|
backend_class->redraw = clutter_backend_egl_redraw;
|
||||||
backend_class->get_features = clutter_backend_egl_get_features;
|
backend_class->get_features = clutter_backend_egl_get_features;
|
||||||
backend_class->init_stage = clutter_backend_egl_init_stage;
|
backend_class->create_stage = clutter_backend_egl_create_stage;
|
||||||
|
backend_class->ensure_context = clutter_backend_egl_ensure_context;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_backend_egl_init (ClutterBackendEGL *backend_egl)
|
clutter_backend_egl_init (ClutterBackendEGL *backend_egl)
|
||||||
{
|
{
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GType
|
GType
|
||||||
|
@ -52,7 +52,11 @@ struct _ClutterBackendEGL
|
|||||||
|
|
||||||
/* EGL Specific */
|
/* EGL Specific */
|
||||||
EGLDisplay edpy;
|
EGLDisplay edpy;
|
||||||
gint egl_version_major, egl_version_minor;
|
EGLSurface egl_surface;
|
||||||
|
EGLContext egl_context;
|
||||||
|
|
||||||
|
gint egl_version_major;
|
||||||
|
gint egl_version_minor;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "clutter-backend-egl.h"
|
||||||
#include "clutter-stage-egl.h"
|
#include "clutter-stage-egl.h"
|
||||||
#include "clutter-eglx.h"
|
#include "clutter-eglx.h"
|
||||||
|
|
||||||
@ -14,8 +15,17 @@
|
|||||||
#include "../clutter-private.h"
|
#include "../clutter-private.h"
|
||||||
#include "../clutter-debug.h"
|
#include "../clutter-debug.h"
|
||||||
#include "../clutter-units.h"
|
#include "../clutter-units.h"
|
||||||
|
#include "../clutter-container.h"
|
||||||
|
#include "../clutter-stage.h"
|
||||||
|
#include "../clutter-stage-window.h"
|
||||||
|
|
||||||
G_DEFINE_TYPE (ClutterStageEGL, clutter_stage_egl, CLUTTER_TYPE_STAGE_X11);
|
static void clutter_stage_window_iface_init (ClutterStageWindowIface *iface);
|
||||||
|
|
||||||
|
G_DEFINE_TYPE_WITH_CODE (ClutterStageEGL,
|
||||||
|
clutter_stage_egl,
|
||||||
|
CLUTTER_TYPE_STAGE_X11,
|
||||||
|
G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_STAGE_WINDOW,
|
||||||
|
clutter_stage_window_iface_init));
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_stage_egl_unrealize (ClutterActor *actor)
|
clutter_stage_egl_unrealize (ClutterActor *actor)
|
||||||
@ -26,17 +36,19 @@ clutter_stage_egl_unrealize (ClutterActor *actor)
|
|||||||
|
|
||||||
CLUTTER_MARK();
|
CLUTTER_MARK();
|
||||||
|
|
||||||
g_object_get (actor, "offscreen", &was_offscreen, NULL);
|
g_object_get (stage_x11->wrapper, "offscreen", &was_offscreen, NULL);
|
||||||
|
|
||||||
|
CLUTTER_ACTOR_CLASS (clutter_stage_egl_parent_class)->unrealize (actor);
|
||||||
|
|
||||||
|
clutter_x11_trap_x_errors ()
|
||||||
|
|
||||||
if (G_UNLIKELY (was_offscreen))
|
if (G_UNLIKELY (was_offscreen))
|
||||||
{
|
{
|
||||||
/* No support as yet for this */
|
/* No support as yet for this */
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (stage_x11->xwin != None)
|
if (!stage_X11->is_foreign_xwin && stage_x11->xwin != None)
|
||||||
{
|
{
|
||||||
XDestroyWindow (stage_x11->xdpy, stage_x11->xwin);
|
XDestroyWindow (stage_x11->xdpy, stage_x11->xwin);
|
||||||
stage_x11->xwin = None;
|
stage_x11->xwin = None;
|
||||||
@ -46,134 +58,137 @@ clutter_stage_egl_unrealize (ClutterActor *actor)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (stage_egl->egl_surface)
|
if (stage_egl->egl_surface)
|
||||||
eglDestroySurface (clutter_eglx_display(), stage_egl->egl_surface);
|
{
|
||||||
stage_egl->egl_surface = NULL;
|
eglDestroySurface (clutter_eglx_display (), stage_egl->egl_surface);
|
||||||
|
stage_egl->egl_surface = EGL_NO_SURFACE;
|
||||||
|
}
|
||||||
|
|
||||||
if (stage_egl->egl_context)
|
clutter_stage_ensure_current (stage_x11->wrapper);
|
||||||
eglDestroyContext (clutter_eglx_display(), stage_egl->egl_context);
|
|
||||||
stage_egl->egl_context = NULL;
|
|
||||||
|
|
||||||
eglMakeCurrent (clutter_eglx_display(),
|
/* XSync (stage_x11->xdpy, False); */
|
||||||
EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
|
||||||
|
|
||||||
stage_egl->egl_context = None;
|
clutter_x11_untrap_x_errors ();
|
||||||
|
|
||||||
|
CLUTTER_MARK ();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_stage_egl_realize (ClutterActor *actor)
|
clutter_stage_egl_realize (ClutterActor *actor)
|
||||||
{
|
{
|
||||||
ClutterStageEGL *stage_egl = CLUTTER_STAGE_EGL (actor);
|
ClutterStageEGL *stage_egl = CLUTTER_STAGE_EGL (actor);
|
||||||
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (actor);
|
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (actor);
|
||||||
|
ClutterBackendEGL *backend_egl;
|
||||||
EGLConfig configs[2];
|
EGLConfig configs[2];
|
||||||
EGLint config_count;
|
EGLint config_count;
|
||||||
EGLBoolean status;
|
EGLBoolean status;
|
||||||
|
gboolean is_offscreen = FALSE;
|
||||||
gboolean is_offscreen;
|
|
||||||
|
|
||||||
CLUTTER_NOTE (BACKEND, "Realizing main stage");
|
CLUTTER_NOTE (BACKEND, "Realizing main stage");
|
||||||
|
|
||||||
g_object_get (actor, "offscreen", &is_offscreen, NULL);
|
g_object_get (stage_x11->wrapper, "offscreen", &is_offscreen, NULL);
|
||||||
|
|
||||||
|
backend_egl = CLUTTER_BACKEND_EGL (clutter_get_default_backend ());
|
||||||
|
|
||||||
if (G_LIKELY (!is_offscreen))
|
if (G_LIKELY (!is_offscreen))
|
||||||
{
|
{
|
||||||
EGLint cfg_attribs[] = { EGL_BUFFER_SIZE, EGL_DONT_CARE,
|
EGLint cfg_attribs[] = {
|
||||||
EGL_RED_SIZE, 5,
|
EGL_BUFFER_SIZE, EGL_DONT_CARE,
|
||||||
EGL_GREEN_SIZE, 6,
|
EGL_RED_SIZE, 5,
|
||||||
EGL_BLUE_SIZE, 5,
|
EGL_GREEN_SIZE, 6,
|
||||||
EGL_NONE };
|
EGL_BLUE_SIZE, 5,
|
||||||
|
EGL_NONE
|
||||||
|
};
|
||||||
|
|
||||||
status = eglGetConfigs (clutter_eglx_display(),
|
status = eglGetConfigs (backend_egl->edpy,
|
||||||
configs,
|
configs,
|
||||||
2,
|
2,
|
||||||
&config_count);
|
&config_count);
|
||||||
|
|
||||||
if (status != EGL_TRUE)
|
if (status != EGL_TRUE)
|
||||||
g_warning ("eglGetConfigs");
|
g_warning ("eglGetConfigs failed");
|
||||||
|
|
||||||
status = eglChooseConfig (clutter_eglx_display(),
|
status = eglChooseConfig (backend_egl->edpy,
|
||||||
cfg_attribs,
|
cfg_attribs,
|
||||||
configs,
|
configs,
|
||||||
sizeof configs / sizeof configs[0],
|
G_N_ELEMENTS (configs),
|
||||||
&config_count);
|
&config_count);
|
||||||
|
|
||||||
if (status != EGL_TRUE)
|
if (status != EGL_TRUE)
|
||||||
g_warning ("eglChooseConfig");
|
g_warning ("eglChooseConfig failed");
|
||||||
|
|
||||||
if (stage_x11->xwin == None)
|
if (stage_x11->xwin == None)
|
||||||
stage_x11->xwin
|
stage_x11->xwin =
|
||||||
= XCreateSimpleWindow(stage_x11->xdpy,
|
XCreateSimpleWindow (stage_x11->xdpy,
|
||||||
stage_x11->xwin_root,
|
stage_x11->xwin_root,
|
||||||
0, 0,
|
0, 0,
|
||||||
stage_x11->xwin_width,
|
stage_x11->xwin_width,
|
||||||
stage_x11->xwin_height,
|
stage_x11->xwin_height,
|
||||||
0, 0,
|
0, 0,
|
||||||
WhitePixel (stage_x11->xdpy,
|
WhitePixel (stage_x11->xdpy,
|
||||||
stage_x11->xscreen));
|
stage_x11->xscreen));
|
||||||
|
|
||||||
XSelectInput(stage_x11->xdpy,
|
XSelectInput (stage_x11->xdpy, stage_x11->xwin,
|
||||||
stage_x11->xwin,
|
StructureNotifyMask
|
||||||
StructureNotifyMask
|
| ExposureMask
|
||||||
|ExposureMask
|
/* FIXME: we may want to eplicity enable MotionMask */
|
||||||
/* FIXME: we may want to eplicity enable MotionMask */
|
| PointerMotionMask
|
||||||
|PointerMotionMask
|
| KeyPressMask
|
||||||
|KeyPressMask
|
| KeyReleaseMask
|
||||||
|KeyReleaseMask
|
| ButtonPressMask
|
||||||
|ButtonPressMask
|
| ButtonReleaseMask
|
||||||
|ButtonReleaseMask
|
| PropertyChangeMask);
|
||||||
|PropertyChangeMask);
|
|
||||||
|
|
||||||
if (stage_egl->egl_context)
|
if (stage_egl->egl_surface != EGL_NO_SURFACE)
|
||||||
eglDestroyContext (clutter_eglx_display(), stage_egl->egl_context);
|
{
|
||||||
|
eglDestroySurface (backend_egl->edpy, stage_egl->egl_surface);
|
||||||
|
stage_egl->egl_surface = EGL_NO_SURFACE;
|
||||||
|
}
|
||||||
|
|
||||||
if (stage_egl->egl_surface)
|
stage_egl->egl_surface =
|
||||||
eglDestroySurface (clutter_eglx_display(), stage_egl->egl_surface);
|
eglCreateWindowSurface (backend_egl->edpy,
|
||||||
|
configs[0],
|
||||||
stage_egl->egl_surface
|
(NativeWindowType) stage_x11->xwin,
|
||||||
= eglCreateWindowSurface (clutter_eglx_display(),
|
NULL);
|
||||||
configs[0],
|
|
||||||
(NativeWindowType)stage_x11->xwin,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (stage_egl->egl_surface == EGL_NO_SURFACE)
|
if (stage_egl->egl_surface == EGL_NO_SURFACE)
|
||||||
g_warning ("eglCreateWindowSurface");
|
{
|
||||||
|
g_critical ("Unable to create an EGL surface");
|
||||||
|
|
||||||
stage_egl->egl_context = eglCreateContext (clutter_eglx_display(),
|
CLUTTER_ACTOR_UNSET_FLAGS (stage_x11->wrapper, CLUTTER_ACTOR_REALIZED);
|
||||||
configs[0],
|
CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED);
|
||||||
EGL_NO_CONTEXT,
|
return;
|
||||||
NULL);
|
}
|
||||||
|
|
||||||
if (stage_egl->egl_context == EGL_NO_CONTEXT)
|
if (G_UNLIKELY (backend_egl->egl_context == None))
|
||||||
g_warning ("eglCreateContext");
|
{
|
||||||
|
CLUTTER_NOTE (GL, "Creating EGL Context");
|
||||||
|
|
||||||
status = eglMakeCurrent (clutter_eglx_display(),
|
backend_egl->egl_context = eglCreateContext (backend_egl->edpy,
|
||||||
stage_egl->egl_surface,
|
configs[0],
|
||||||
stage_egl->egl_surface,
|
EGL_NO_CONTEXT,
|
||||||
stage_egl->egl_context);
|
NULL);
|
||||||
|
|
||||||
if (status != EGL_TRUE)
|
if (backend_egl->egl_context == EGL_NO_CONTEXT)
|
||||||
g_warning ("eglMakeCurrent");
|
{
|
||||||
|
g_critical ("Unable to create a suitable EGL context");
|
||||||
|
|
||||||
|
CLUTTER_ACTOR_UNSET_FLAGS (stage_x11->wrapper, CLUTTER_ACTOR_REALIZED);
|
||||||
|
CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CLUTTER_ACTOR_SET_FLAGS (stage_x11->wrapper, CLUTTER_ACTOR_REALIZED);
|
||||||
|
clutter_stage_ensure_current (stage_x11->wrapper);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
g_warning("EGL Backend does not yet support offscreen rendering\n");
|
g_warning("EGLX Backend does not support offscreen rendering");
|
||||||
CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED);
|
CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CLUTTER_SET_PRIVATE_FLAGS(actor, CLUTTER_ACTOR_SYNC_MATRICES);
|
CLUTTER_SET_PRIVATE_FLAGS (stage_x11->wrapper, CLUTTER_ACTOR_SYNC_MATRICES);
|
||||||
}
|
|
||||||
|
|
||||||
static GdkPixbuf*
|
|
||||||
clutter_stage_egl_draw_to_pixbuf (ClutterStage *stage,
|
|
||||||
gint x,
|
|
||||||
gint y,
|
|
||||||
gint width,
|
|
||||||
gint height)
|
|
||||||
{
|
|
||||||
g_warning ("Stage of type `%s' do not support ClutterStage::draw_to_pixbuf",
|
|
||||||
G_OBJECT_TYPE_NAME (stage));
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -188,24 +203,40 @@ clutter_stage_egl_dispose (GObject *gobject)
|
|||||||
G_OBJECT_CLASS (clutter_stage_egl_parent_class)->dispose (gobject);
|
G_OBJECT_CLASS (clutter_stage_egl_parent_class)->dispose (gobject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GdkPixbuf *
|
||||||
|
clutter_stage_egl_draw_to_pixbuf (ClutterStageWindow *stage_window,
|
||||||
|
gint x,
|
||||||
|
gint y,
|
||||||
|
gint width,
|
||||||
|
gint height)
|
||||||
|
{
|
||||||
|
g_warning ("Stages of type `%s' do not support "
|
||||||
|
"ClutterStageWindow::draw_to_pixbuf",
|
||||||
|
G_OBJECT_TYPE_NAME (stage));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_stage_window_iface_init (ClutterStageWindowIface *iface)
|
||||||
|
{
|
||||||
|
iface->draw_to_pixbuf = clutter_stage_egl_draw_to_pixbuf;
|
||||||
|
|
||||||
|
/* the rest is inherited from ClutterStageX11 */
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_stage_egl_class_init (ClutterStageEGLClass *klass)
|
clutter_stage_egl_class_init (ClutterStageEGLClass *klass)
|
||||||
{
|
{
|
||||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
||||||
ClutterStageClass *stage_class = CLUTTER_STAGE_CLASS (klass);
|
|
||||||
|
|
||||||
gobject_class->dispose = clutter_stage_egl_dispose;
|
gobject_class->dispose = clutter_stage_egl_dispose;
|
||||||
|
|
||||||
actor_class->realize = clutter_stage_egl_realize;
|
actor_class->realize = clutter_stage_egl_realize;
|
||||||
actor_class->unrealize = clutter_stage_egl_unrealize;
|
actor_class->unrealize = clutter_stage_egl_unrealize;
|
||||||
stage_class->draw_to_pixbuf = clutter_stage_egl_draw_to_pixbuf;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_stage_egl_init (ClutterStageEGL *stage)
|
clutter_stage_egl_init (ClutterStageEGL *stage)
|
||||||
{
|
{
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -27,8 +27,7 @@ struct _ClutterStageEGL
|
|||||||
{
|
{
|
||||||
ClutterStageX11 parent_instance;
|
ClutterStageX11 parent_instance;
|
||||||
|
|
||||||
EGLSurface egl_surface;
|
EGLSurface egl_surface;
|
||||||
EGLContext egl_context;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _ClutterStageEGLClass
|
struct _ClutterStageEGLClass
|
||||||
|
@ -173,6 +173,15 @@ clutter_backend_glx_finalize (GObject *gobject)
|
|||||||
static void
|
static void
|
||||||
clutter_backend_glx_dispose (GObject *gobject)
|
clutter_backend_glx_dispose (GObject *gobject)
|
||||||
{
|
{
|
||||||
|
ClutterBackendGLX *backend_glx = CLUTTER_BACKEND_GLX (gobject);
|
||||||
|
ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (gobject);
|
||||||
|
|
||||||
|
if (backend_glx->gl_context)
|
||||||
|
{
|
||||||
|
glXDestroyContext (backend_x11->xdpy, backend_glx->gl_context);
|
||||||
|
backend_glx->gl_context = None;
|
||||||
|
}
|
||||||
|
|
||||||
G_OBJECT_CLASS (clutter_backend_glx_parent_class)->dispose (gobject);
|
G_OBJECT_CLASS (clutter_backend_glx_parent_class)->dispose (gobject);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,10 +223,13 @@ clutter_backend_glx_get_features (ClutterBackend *backend)
|
|||||||
{
|
{
|
||||||
ClutterBackendGLX *backend_glx = CLUTTER_BACKEND_GLX (backend);
|
ClutterBackendGLX *backend_glx = CLUTTER_BACKEND_GLX (backend);
|
||||||
const gchar *glx_extensions = NULL;
|
const gchar *glx_extensions = NULL;
|
||||||
ClutterFeatureFlags flags = CLUTTER_FEATURE_STAGE_MULTIPLE;
|
ClutterFeatureFlags flags;
|
||||||
|
|
||||||
/* this will make sure that the GL context exists and its
|
flags = clutter_backend_x11_get_features (backend);
|
||||||
* bound to a drawable
|
flags |= CLUTTER_FEATURE_STAGE_MULTIPLE;
|
||||||
|
|
||||||
|
/* this will make sure that the GL context exists and
|
||||||
|
* it's bound to a drawable
|
||||||
*/
|
*/
|
||||||
g_assert (backend_glx->gl_context != None);
|
g_assert (backend_glx->gl_context != None);
|
||||||
g_assert (glXGetCurrentDrawable () != None);
|
g_assert (glXGetCurrentDrawable () != None);
|
||||||
@ -344,59 +356,88 @@ clutter_backend_glx_get_features (ClutterBackend *backend)
|
|||||||
|
|
||||||
CLUTTER_NOTE (MISC, "backend features checked");
|
CLUTTER_NOTE (MISC, "backend features checked");
|
||||||
|
|
||||||
return flags|clutter_backend_x11_get_features (backend);
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_backend_glx_ensure_context (ClutterBackend *backend,
|
clutter_backend_glx_ensure_context (ClutterBackend *backend,
|
||||||
ClutterStage *stage)
|
ClutterStage *stage)
|
||||||
{
|
{
|
||||||
ClutterBackendGLX *backend_glx;
|
|
||||||
ClutterStageGLX *stage_glx;
|
|
||||||
ClutterStageX11 *stage_x11;
|
|
||||||
ClutterBackendX11 *backend_x11;
|
|
||||||
|
|
||||||
if (stage == NULL)
|
if (stage == NULL)
|
||||||
{
|
{
|
||||||
backend_x11 = CLUTTER_BACKEND_X11(backend);
|
ClutterBackendX11 *backend_x11;
|
||||||
|
|
||||||
|
backend_x11 = CLUTTER_BACKEND_X11 (backend);
|
||||||
CLUTTER_NOTE (MULTISTAGE, "Clearing all context");
|
CLUTTER_NOTE (MULTISTAGE, "Clearing all context");
|
||||||
|
|
||||||
glXMakeCurrent (backend_x11->xdpy, None, NULL);
|
glXMakeCurrent (backend_x11->xdpy, None, NULL);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
stage_glx = CLUTTER_STAGE_GLX(stage);
|
ClutterBackendGLX *backend_glx;
|
||||||
stage_x11 = CLUTTER_STAGE_X11(stage);
|
ClutterStageGLX *stage_glx;
|
||||||
backend_glx = CLUTTER_BACKEND_GLX(backend);
|
ClutterStageX11 *stage_x11;
|
||||||
|
ClutterStageWindow *impl;
|
||||||
|
|
||||||
|
impl = _clutter_stage_get_window (stage);
|
||||||
|
g_assert (impl != NULL);
|
||||||
|
|
||||||
|
CLUTTER_NOTE (MULTISTAGE, "Setting context for stage of type %s [%p]",
|
||||||
|
g_type_name (G_OBJECT_TYPE (impl)),
|
||||||
|
impl);
|
||||||
|
|
||||||
|
stage_glx = CLUTTER_STAGE_GLX (impl);
|
||||||
|
stage_x11 = CLUTTER_STAGE_X11 (impl);
|
||||||
|
backend_glx = CLUTTER_BACKEND_GLX (backend);
|
||||||
|
|
||||||
g_return_if_fail (stage_x11->xwin != None);
|
|
||||||
g_return_if_fail (backend_glx->gl_context != None);
|
g_return_if_fail (backend_glx->gl_context != None);
|
||||||
|
|
||||||
CLUTTER_NOTE (MULTISTAGE, "setting context for stage:%p", stage );
|
/* we might get here inside the final dispose cycle, so we
|
||||||
|
* need to handle this gracefully
|
||||||
|
*/
|
||||||
|
if (stage_x11->xwin == None)
|
||||||
|
{
|
||||||
|
ClutterBackendX11 *backend_x11;
|
||||||
|
|
||||||
glXMakeCurrent (stage_x11->xdpy,
|
backend_x11 = CLUTTER_BACKEND_X11 (backend);
|
||||||
stage_x11->xwin,
|
CLUTTER_NOTE (MULTISTAGE,
|
||||||
backend_glx->gl_context);
|
"Received a stale stage, clearing all context");
|
||||||
|
|
||||||
|
glXMakeCurrent (backend_x11->xdpy, None, NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
glXMakeCurrent (stage_x11->xdpy,
|
||||||
|
stage_x11->xwin,
|
||||||
|
backend_glx->gl_context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_backend_glx_redraw (ClutterBackend *backend, ClutterStage *stage)
|
clutter_backend_glx_redraw (ClutterBackend *backend,
|
||||||
|
ClutterStage *stage)
|
||||||
{
|
{
|
||||||
ClutterStageGLX *stage_glx;
|
ClutterStageGLX *stage_glx;
|
||||||
ClutterStageX11 *stage_x11;
|
ClutterStageX11 *stage_x11;
|
||||||
|
ClutterStageWindow *impl;
|
||||||
|
|
||||||
stage_x11 = CLUTTER_STAGE_X11(stage);
|
impl = _clutter_stage_get_window (stage);
|
||||||
stage_glx = CLUTTER_STAGE_GLX(stage);
|
if (!impl)
|
||||||
|
return;
|
||||||
|
|
||||||
clutter_actor_paint (CLUTTER_ACTOR (stage_glx));
|
g_assert (CLUTTER_IS_STAGE_GLX (impl));
|
||||||
|
|
||||||
|
stage_x11 = CLUTTER_STAGE_X11 (impl);
|
||||||
|
stage_glx = CLUTTER_STAGE_GLX (impl);
|
||||||
|
|
||||||
|
/* this will cause the stage implementation to be painted */
|
||||||
|
clutter_actor_paint (CLUTTER_ACTOR (stage));
|
||||||
|
|
||||||
/* Why this paint is done in backend as likely GL windowing system
|
/* Why this paint is done in backend as likely GL windowing system
|
||||||
* specific calls, like swapping buffers.
|
* specific calls, like swapping buffers.
|
||||||
*/
|
*/
|
||||||
if (stage_x11->xwin)
|
if (stage_x11->xwin)
|
||||||
{
|
{
|
||||||
clutter_backend_glx_wait_for_vblank (CLUTTER_BACKEND_GLX(backend));
|
clutter_backend_glx_wait_for_vblank (CLUTTER_BACKEND_GLX (backend));
|
||||||
glXSwapBuffers (stage_x11->xdpy, stage_x11->xwin);
|
glXSwapBuffers (stage_x11->xdpy, stage_x11->xwin);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -409,12 +450,16 @@ clutter_backend_glx_redraw (ClutterBackend *backend, ClutterStage *stage)
|
|||||||
|
|
||||||
static ClutterActor*
|
static ClutterActor*
|
||||||
clutter_backend_glx_create_stage (ClutterBackend *backend,
|
clutter_backend_glx_create_stage (ClutterBackend *backend,
|
||||||
|
ClutterStage *wrapper,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend);
|
ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend);
|
||||||
ClutterStageX11 *stage_x11;
|
ClutterStageX11 *stage_x11;
|
||||||
ClutterActor *stage;
|
ClutterActor *stage;
|
||||||
|
|
||||||
|
CLUTTER_NOTE (BACKEND, "Creating stage of type `%s'",
|
||||||
|
g_type_name (CLUTTER_STAGE_TYPE));
|
||||||
|
|
||||||
stage = g_object_new (CLUTTER_STAGE_TYPE, NULL);
|
stage = g_object_new (CLUTTER_STAGE_TYPE, NULL);
|
||||||
|
|
||||||
/* copy backend data into the stage */
|
/* copy backend data into the stage */
|
||||||
@ -423,8 +468,12 @@ clutter_backend_glx_create_stage (ClutterBackend *backend,
|
|||||||
stage_x11->xwin_root = backend_x11->xwin_root;
|
stage_x11->xwin_root = backend_x11->xwin_root;
|
||||||
stage_x11->xscreen = backend_x11->xscreen_num;
|
stage_x11->xscreen = backend_x11->xscreen_num;
|
||||||
stage_x11->backend = backend_x11;
|
stage_x11->backend = backend_x11;
|
||||||
|
stage_x11->wrapper = wrapper;
|
||||||
|
|
||||||
CLUTTER_NOTE (MISC, "X11 stage created (display:%p, screen:%d, root:%u)",
|
/* set the pointer back into the wrapper */
|
||||||
|
_clutter_stage_set_window (wrapper, CLUTTER_STAGE_WINDOW (stage));
|
||||||
|
|
||||||
|
CLUTTER_NOTE (BACKEND, "GLX stage created (display:%p, screen:%d, root:%u)",
|
||||||
stage_x11->xdpy,
|
stage_x11->xdpy,
|
||||||
stage_x11->xscreen,
|
stage_x11->xscreen,
|
||||||
(unsigned int) stage_x11->xwin_root);
|
(unsigned int) stage_x11->xwin_root);
|
||||||
@ -432,6 +481,10 @@ clutter_backend_glx_create_stage (ClutterBackend *backend,
|
|||||||
/* needed ? */
|
/* needed ? */
|
||||||
g_object_set_data (G_OBJECT (stage), "clutter-backend", backend);
|
g_object_set_data (G_OBJECT (stage), "clutter-backend", backend);
|
||||||
|
|
||||||
|
/* FIXME - is this needed? we should call realize inside the clutter
|
||||||
|
* init sequence for the default stage, and let the usual realization
|
||||||
|
* sequence be used for any other stage
|
||||||
|
*/
|
||||||
clutter_actor_realize (stage);
|
clutter_actor_realize (stage);
|
||||||
|
|
||||||
if (!CLUTTER_ACTOR_IS_REALIZED (stage))
|
if (!CLUTTER_ACTOR_IS_REALIZED (stage))
|
||||||
@ -445,7 +498,6 @@ clutter_backend_glx_create_stage (ClutterBackend *backend,
|
|||||||
return stage;
|
return stage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_backend_glx_class_init (ClutterBackendGLXClass *klass)
|
clutter_backend_glx_class_init (ClutterBackendGLXClass *klass)
|
||||||
{
|
{
|
||||||
@ -456,19 +508,19 @@ clutter_backend_glx_class_init (ClutterBackendGLXClass *klass)
|
|||||||
gobject_class->dispose = clutter_backend_glx_dispose;
|
gobject_class->dispose = clutter_backend_glx_dispose;
|
||||||
gobject_class->finalize = clutter_backend_glx_finalize;
|
gobject_class->finalize = clutter_backend_glx_finalize;
|
||||||
|
|
||||||
backend_class->pre_parse = clutter_backend_glx_pre_parse;
|
backend_class->pre_parse = clutter_backend_glx_pre_parse;
|
||||||
backend_class->post_parse = clutter_backend_glx_post_parse;
|
backend_class->post_parse = clutter_backend_glx_post_parse;
|
||||||
backend_class->create_stage = clutter_backend_glx_create_stage;
|
backend_class->create_stage = clutter_backend_glx_create_stage;
|
||||||
backend_class->add_options = clutter_backend_glx_add_options;
|
backend_class->add_options = clutter_backend_glx_add_options;
|
||||||
backend_class->get_features = clutter_backend_glx_get_features;
|
backend_class->get_features = clutter_backend_glx_get_features;
|
||||||
backend_class->redraw = clutter_backend_glx_redraw;
|
backend_class->redraw = clutter_backend_glx_redraw;
|
||||||
backend_class->ensure_context = clutter_backend_glx_ensure_context;
|
backend_class->ensure_context = clutter_backend_glx_ensure_context;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_backend_glx_init (ClutterBackendGLX *backend_glx)
|
clutter_backend_glx_init (ClutterBackendGLX *backend_glx)
|
||||||
{
|
{
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* every backend must implement this function */
|
/* every backend must implement this function */
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
#include "../clutter-group.h"
|
#include "../clutter-group.h"
|
||||||
#include "../clutter-container.h"
|
#include "../clutter-container.h"
|
||||||
#include "../clutter-stage.h"
|
#include "../clutter-stage.h"
|
||||||
|
#include "../clutter-stage-window.h"
|
||||||
|
|
||||||
#include "cogl.h"
|
#include "cogl.h"
|
||||||
|
|
||||||
@ -48,21 +49,25 @@
|
|||||||
|
|
||||||
#include <gdk-pixbuf-xlib/gdk-pixbuf-xlib.h>
|
#include <gdk-pixbuf-xlib/gdk-pixbuf-xlib.h>
|
||||||
|
|
||||||
G_DEFINE_TYPE (ClutterStageGLX, clutter_stage_glx, CLUTTER_TYPE_STAGE_X11);
|
static void clutter_stage_window_iface_init (ClutterStageWindowIface *iface);
|
||||||
|
|
||||||
|
G_DEFINE_TYPE_WITH_CODE (ClutterStageGLX,
|
||||||
|
clutter_stage_glx,
|
||||||
|
CLUTTER_TYPE_STAGE_X11,
|
||||||
|
G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_STAGE_WINDOW,
|
||||||
|
clutter_stage_window_iface_init));
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_stage_glx_unrealize (ClutterActor *actor)
|
clutter_stage_glx_unrealize (ClutterActor *actor)
|
||||||
{
|
{
|
||||||
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (actor);
|
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (actor);
|
||||||
ClutterStageGLX *stage_glx = CLUTTER_STAGE_GLX (actor);
|
ClutterStageGLX *stage_glx = CLUTTER_STAGE_GLX (actor);
|
||||||
|
|
||||||
/* Note unrealize should free up any backend stage related resources */
|
|
||||||
|
|
||||||
gboolean was_offscreen;
|
gboolean was_offscreen;
|
||||||
|
|
||||||
|
/* Note unrealize should free up any backend stage related resources */
|
||||||
CLUTTER_MARK();
|
CLUTTER_MARK();
|
||||||
|
|
||||||
g_object_get (actor, "offscreen", &was_offscreen, NULL);
|
g_object_get (stage_x11->wrapper, "offscreen", &was_offscreen, NULL);
|
||||||
|
|
||||||
/* Chain up so all children get unrealized, needed to move texture data
|
/* Chain up so all children get unrealized, needed to move texture data
|
||||||
* across contexts
|
* across contexts
|
||||||
@ -100,7 +105,7 @@ clutter_stage_glx_unrealize (ClutterActor *actor)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* As unrealised the context will now get cleared */
|
/* As unrealised the context will now get cleared */
|
||||||
clutter_stage_ensure_current (CLUTTER_STAGE(stage_glx));
|
clutter_stage_ensure_current (stage_x11->wrapper);
|
||||||
|
|
||||||
XSync (stage_x11->xdpy, False);
|
XSync (stage_x11->xdpy, False);
|
||||||
|
|
||||||
@ -119,9 +124,9 @@ clutter_stage_glx_realize (ClutterActor *actor)
|
|||||||
|
|
||||||
CLUTTER_NOTE (MISC, "Realizing main stage");
|
CLUTTER_NOTE (MISC, "Realizing main stage");
|
||||||
|
|
||||||
g_object_get (actor, "offscreen", &is_offscreen, NULL);
|
g_object_get (stage_x11->wrapper, "offscreen", &is_offscreen, NULL);
|
||||||
|
|
||||||
backend_glx = CLUTTER_BACKEND_GLX(clutter_get_default_backend());
|
backend_glx = CLUTTER_BACKEND_GLX (clutter_get_default_backend ());
|
||||||
|
|
||||||
if (G_LIKELY (!is_offscreen))
|
if (G_LIKELY (!is_offscreen))
|
||||||
{
|
{
|
||||||
@ -137,8 +142,10 @@ clutter_stage_glx_realize (ClutterActor *actor)
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (stage_x11->xvisinfo)
|
if (stage_x11->xvisinfo)
|
||||||
XFree (stage_x11->xvisinfo);
|
{
|
||||||
stage_x11->xvisinfo = NULL;
|
XFree (stage_x11->xvisinfo);
|
||||||
|
stage_x11->xvisinfo = None;
|
||||||
|
}
|
||||||
|
|
||||||
/* The following check seems strange */
|
/* The following check seems strange */
|
||||||
if (stage_x11->xvisinfo == None)
|
if (stage_x11->xvisinfo == None)
|
||||||
@ -148,6 +155,8 @@ clutter_stage_glx_realize (ClutterActor *actor)
|
|||||||
if (!stage_x11->xvisinfo)
|
if (!stage_x11->xvisinfo)
|
||||||
{
|
{
|
||||||
g_critical ("Unable to find suitable GL visual.");
|
g_critical ("Unable to find suitable GL visual.");
|
||||||
|
|
||||||
|
CLUTTER_ACTOR_UNSET_FLAGS (stage_x11->wrapper, CLUTTER_ACTOR_REALIZED);
|
||||||
CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED);
|
CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -169,15 +178,15 @@ clutter_stage_glx_realize (ClutterActor *actor)
|
|||||||
AllocNone);
|
AllocNone);
|
||||||
mask = CWBackPixel | CWBorderPixel | CWColormap;
|
mask = CWBackPixel | CWBorderPixel | CWColormap;
|
||||||
stage_x11->xwin = XCreateWindow (stage_x11->xdpy,
|
stage_x11->xwin = XCreateWindow (stage_x11->xdpy,
|
||||||
stage_x11->xwin_root,
|
stage_x11->xwin_root,
|
||||||
0, 0,
|
0, 0,
|
||||||
stage_x11->xwin_width,
|
stage_x11->xwin_width,
|
||||||
stage_x11->xwin_height,
|
stage_x11->xwin_height,
|
||||||
0,
|
0,
|
||||||
stage_x11->xvisinfo->depth,
|
stage_x11->xvisinfo->depth,
|
||||||
InputOutput,
|
InputOutput,
|
||||||
stage_x11->xvisinfo->visual,
|
stage_x11->xvisinfo->visual,
|
||||||
mask, &xattr);
|
mask, &xattr);
|
||||||
}
|
}
|
||||||
|
|
||||||
CLUTTER_NOTE (MISC, "XSelectInput");
|
CLUTTER_NOTE (MISC, "XSelectInput");
|
||||||
@ -193,7 +202,6 @@ clutter_stage_glx_realize (ClutterActor *actor)
|
|||||||
|
|
||||||
/* no user resize.. */
|
/* no user resize.. */
|
||||||
clutter_stage_x11_fix_window_size (stage_x11);
|
clutter_stage_x11_fix_window_size (stage_x11);
|
||||||
|
|
||||||
clutter_stage_x11_set_wm_protocols (stage_x11);
|
clutter_stage_x11_set_wm_protocols (stage_x11);
|
||||||
|
|
||||||
if (backend_glx->gl_context == None)
|
if (backend_glx->gl_context == None)
|
||||||
@ -208,6 +216,7 @@ clutter_stage_glx_realize (ClutterActor *actor)
|
|||||||
{
|
{
|
||||||
g_critical ("Unable to create suitable GL context.");
|
g_critical ("Unable to create suitable GL context.");
|
||||||
|
|
||||||
|
CLUTTER_ACTOR_UNSET_FLAGS (stage_x11->wrapper, CLUTTER_ACTOR_REALIZED);
|
||||||
CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED);
|
CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -215,8 +224,8 @@ clutter_stage_glx_realize (ClutterActor *actor)
|
|||||||
}
|
}
|
||||||
|
|
||||||
CLUTTER_NOTE (GL, "glXMakeCurrent");
|
CLUTTER_NOTE (GL, "glXMakeCurrent");
|
||||||
|
CLUTTER_ACTOR_SET_FLAGS (stage_x11->wrapper, CLUTTER_ACTOR_REALIZED);
|
||||||
clutter_stage_ensure_current (CLUTTER_STAGE(stage_glx));
|
clutter_stage_ensure_current (stage_x11->wrapper);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -276,6 +285,7 @@ clutter_stage_glx_realize (ClutterActor *actor)
|
|||||||
{
|
{
|
||||||
g_critical ("Unable to create suitable GL context.");
|
g_critical ("Unable to create suitable GL context.");
|
||||||
|
|
||||||
|
CLUTTER_ACTOR_UNSET_FLAGS (stage_x11->wrapper, CLUTTER_ACTOR_REALIZED);
|
||||||
CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED);
|
CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -285,7 +295,7 @@ clutter_stage_glx_realize (ClutterActor *actor)
|
|||||||
clutter_x11_trap_x_errors ();
|
clutter_x11_trap_x_errors ();
|
||||||
|
|
||||||
/* below will call glxMakeCurrent */
|
/* below will call glxMakeCurrent */
|
||||||
clutter_stage_ensure_current (CLUTTER_STAGE(stage_glx));
|
clutter_stage_ensure_current (stage_x11->wrapper);
|
||||||
|
|
||||||
if (clutter_x11_untrap_x_errors ())
|
if (clutter_x11_untrap_x_errors ())
|
||||||
{
|
{
|
||||||
@ -295,14 +305,13 @@ clutter_stage_glx_realize (ClutterActor *actor)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Make sure the viewport gets set up correctly */
|
/* Make sure the viewport gets set up correctly */
|
||||||
CLUTTER_SET_PRIVATE_FLAGS (actor, CLUTTER_ACTOR_SYNC_MATRICES);
|
CLUTTER_SET_PRIVATE_FLAGS (stage_x11->wrapper, CLUTTER_ACTOR_SYNC_MATRICES);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
|
||||||
/* For one reason or another we cant realize the stage.. */
|
/* For one reason or another we cant realize the stage.. */
|
||||||
|
CLUTTER_ACTOR_UNSET_FLAGS (stage_x11->wrapper, CLUTTER_ACTOR_REALIZED);
|
||||||
CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED);
|
CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -312,12 +321,12 @@ snapshot_pixbuf_free (guchar *pixels,
|
|||||||
g_free (pixels);
|
g_free (pixels);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GdkPixbuf*
|
static GdkPixbuf *
|
||||||
clutter_stage_glx_draw_to_pixbuf (ClutterStage *stage,
|
clutter_stage_glx_draw_to_pixbuf (ClutterStageWindow *stage_window,
|
||||||
gint x,
|
gint x,
|
||||||
gint y,
|
gint y,
|
||||||
gint width,
|
gint width,
|
||||||
gint height)
|
gint height)
|
||||||
{
|
{
|
||||||
guchar *data;
|
guchar *data;
|
||||||
GdkPixbuf *pixb;
|
GdkPixbuf *pixb;
|
||||||
@ -326,9 +335,9 @@ clutter_stage_glx_draw_to_pixbuf (ClutterStage *stage,
|
|||||||
ClutterStageX11 *stage_x11;
|
ClutterStageX11 *stage_x11;
|
||||||
gboolean is_offscreen = FALSE;
|
gboolean is_offscreen = FALSE;
|
||||||
|
|
||||||
stage_glx = CLUTTER_STAGE_GLX (stage);
|
stage_glx = CLUTTER_STAGE_GLX (stage_window);
|
||||||
stage_x11 = CLUTTER_STAGE_X11 (stage);
|
stage_x11 = CLUTTER_STAGE_X11 (stage_window);
|
||||||
actor = CLUTTER_ACTOR (stage);
|
actor = CLUTTER_ACTOR (stage_window);
|
||||||
|
|
||||||
if (width < 0)
|
if (width < 0)
|
||||||
width = clutter_actor_get_width (actor);
|
width = clutter_actor_get_width (actor);
|
||||||
@ -336,7 +345,7 @@ clutter_stage_glx_draw_to_pixbuf (ClutterStage *stage,
|
|||||||
if (height < 0)
|
if (height < 0)
|
||||||
height = clutter_actor_get_height (actor);
|
height = clutter_actor_get_height (actor);
|
||||||
|
|
||||||
g_object_get (stage, "offscreen", &is_offscreen, NULL);
|
g_object_get (stage_x11->wrapper, "offscreen", &is_offscreen, NULL);
|
||||||
|
|
||||||
if (G_UNLIKELY (is_offscreen))
|
if (G_UNLIKELY (is_offscreen))
|
||||||
{
|
{
|
||||||
@ -401,17 +410,22 @@ clutter_stage_glx_class_init (ClutterStageGLXClass *klass)
|
|||||||
{
|
{
|
||||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
||||||
ClutterStageClass *stage_class = CLUTTER_STAGE_CLASS (klass);
|
|
||||||
|
|
||||||
gobject_class->dispose = clutter_stage_glx_dispose;
|
gobject_class->dispose = clutter_stage_glx_dispose;
|
||||||
|
|
||||||
actor_class->realize = clutter_stage_glx_realize;
|
actor_class->realize = clutter_stage_glx_realize;
|
||||||
actor_class->unrealize = clutter_stage_glx_unrealize;
|
actor_class->unrealize = clutter_stage_glx_unrealize;
|
||||||
stage_class->draw_to_pixbuf = clutter_stage_glx_draw_to_pixbuf;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_stage_glx_init (ClutterStageGLX *stage)
|
clutter_stage_glx_init (ClutterStageGLX *stage)
|
||||||
{
|
{
|
||||||
;
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_stage_window_iface_init (ClutterStageWindowIface *iface)
|
||||||
|
{
|
||||||
|
iface->draw_to_pixbuf = clutter_stage_glx_draw_to_pixbuf;
|
||||||
|
|
||||||
|
/* the rest is inherited from ClutterStageX11 */
|
||||||
}
|
}
|
||||||
|
@ -328,11 +328,12 @@ event_translate (ClutterBackend *backend,
|
|||||||
ClutterEvent *event,
|
ClutterEvent *event,
|
||||||
XEvent *xevent)
|
XEvent *xevent)
|
||||||
{
|
{
|
||||||
ClutterBackendX11 *backend_x11;
|
ClutterBackendX11 *backend_x11;
|
||||||
ClutterStageX11 *stage_x11;
|
ClutterStageX11 *stage_x11;
|
||||||
ClutterStage *stage;
|
ClutterStage *stage;
|
||||||
gboolean res;
|
ClutterStageWindow *impl;
|
||||||
Window xwindow, stage_xwindow;
|
gboolean res;
|
||||||
|
Window xwindow, stage_xwindow;
|
||||||
|
|
||||||
backend_x11 = CLUTTER_BACKEND_X11 (backend);
|
backend_x11 = CLUTTER_BACKEND_X11 (backend);
|
||||||
|
|
||||||
@ -375,7 +376,8 @@ event_translate (ClutterBackend *backend,
|
|||||||
if (stage == NULL)
|
if (stage == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
stage_x11 = CLUTTER_STAGE_X11 (stage);
|
impl = _clutter_stage_get_window (stage);
|
||||||
|
stage_x11 = CLUTTER_STAGE_X11 (impl);
|
||||||
stage_xwindow = xwindow; /* clutter_x11_get_stage_window (stage); */
|
stage_xwindow = xwindow; /* clutter_x11_get_stage_window (stage); */
|
||||||
|
|
||||||
event->any.stage = stage;
|
event->any.stage = stage;
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "clutter-stage-x11.h"
|
#include "clutter-stage-x11.h"
|
||||||
#include "clutter-x11.h"
|
#include "clutter-x11.h"
|
||||||
|
|
||||||
|
#include "../clutter-stage-window.h"
|
||||||
#include "../clutter-main.h"
|
#include "../clutter-main.h"
|
||||||
#include "../clutter-feature.h"
|
#include "../clutter-feature.h"
|
||||||
#include "../clutter-color.h"
|
#include "../clutter-color.h"
|
||||||
@ -45,7 +46,13 @@
|
|||||||
|
|
||||||
#include <gdk-pixbuf-xlib/gdk-pixbuf-xlib.h>
|
#include <gdk-pixbuf-xlib/gdk-pixbuf-xlib.h>
|
||||||
|
|
||||||
G_DEFINE_TYPE (ClutterStageX11, clutter_stage_x11, CLUTTER_TYPE_STAGE);
|
static void clutter_stage_window_iface_init (ClutterStageWindowIface *iface);
|
||||||
|
|
||||||
|
G_DEFINE_TYPE_WITH_CODE (ClutterStageX11,
|
||||||
|
clutter_stage_x11,
|
||||||
|
CLUTTER_TYPE_GROUP,
|
||||||
|
G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_STAGE_WINDOW,
|
||||||
|
clutter_stage_window_iface_init));
|
||||||
|
|
||||||
#define _NET_WM_STATE_REMOVE 0 /* remove/unset property */
|
#define _NET_WM_STATE_REMOVE 0 /* remove/unset property */
|
||||||
#define _NET_WM_STATE_ADD 1 /* add/set property */
|
#define _NET_WM_STATE_ADD 1 /* add/set property */
|
||||||
@ -84,7 +91,7 @@ clutter_stage_x11_fix_window_size (ClutterStageX11 *stage_x11)
|
|||||||
{
|
{
|
||||||
gboolean resize;
|
gboolean resize;
|
||||||
|
|
||||||
resize = clutter_stage_get_user_resizable (CLUTTER_STAGE (stage_x11));
|
resize = clutter_stage_get_user_resizable (stage_x11->wrapper);
|
||||||
|
|
||||||
if (stage_x11->xwin != None && stage_x11->is_foreign_xwin == FALSE)
|
if (stage_x11->xwin != None && stage_x11->is_foreign_xwin == FALSE)
|
||||||
{
|
{
|
||||||
@ -117,7 +124,7 @@ clutter_stage_x11_show (ClutterActor *actor)
|
|||||||
/* Fire off a redraw to avoid flicker on first map.
|
/* Fire off a redraw to avoid flicker on first map.
|
||||||
* Appears not to work perfectly on intel drivers at least.
|
* Appears not to work perfectly on intel drivers at least.
|
||||||
*/
|
*/
|
||||||
clutter_redraw(CLUTTER_STAGE(actor));
|
clutter_redraw (stage_x11->wrapper);
|
||||||
|
|
||||||
XSync (stage_x11->xdpy, FALSE);
|
XSync (stage_x11->xdpy, FALSE);
|
||||||
XMapWindow (stage_x11->xdpy, stage_x11->xwin);
|
XMapWindow (stage_x11->xdpy, stage_x11->xwin);
|
||||||
@ -153,8 +160,8 @@ clutter_stage_x11_set_wm_protocols (ClutterStageX11 *stage_x11)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_stage_x11_query_coords (ClutterActor *self,
|
clutter_stage_x11_query_coords (ClutterActor *self,
|
||||||
ClutterActorBox *box)
|
ClutterActorBox *box)
|
||||||
{
|
{
|
||||||
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (self);
|
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (self);
|
||||||
|
|
||||||
@ -164,8 +171,8 @@ clutter_stage_x11_query_coords (ClutterActor *self,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_stage_x11_request_coords (ClutterActor *self,
|
clutter_stage_x11_request_coords (ClutterActor *self,
|
||||||
ClutterActorBox *box)
|
ClutterActorBox *box)
|
||||||
{
|
{
|
||||||
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (self);
|
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (self);
|
||||||
gint new_width, new_height;
|
gint new_width, new_height;
|
||||||
@ -208,7 +215,8 @@ clutter_stage_x11_request_coords (ClutterActor *self,
|
|||||||
clutter_actor_realize (self);
|
clutter_actor_realize (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
CLUTTER_SET_PRIVATE_FLAGS(self, CLUTTER_ACTOR_SYNC_MATRICES);
|
CLUTTER_SET_PRIVATE_FLAGS (CLUTTER_ACTOR (stage_x11->wrapper),
|
||||||
|
CLUTTER_ACTOR_SYNC_MATRICES);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stage_x11->xwin != None
|
if (stage_x11->xwin != None
|
||||||
@ -224,15 +232,18 @@ clutter_stage_x11_request_coords (ClutterActor *self,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_stage_x11_set_fullscreen (ClutterStage *stage,
|
clutter_stage_x11_set_fullscreen (ClutterStageWindow *stage_window,
|
||||||
gboolean fullscreen)
|
gboolean is_fullscreen)
|
||||||
{
|
{
|
||||||
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage);
|
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
|
||||||
ClutterBackendX11 *backend_x11 = stage_x11->backend;
|
ClutterBackendX11 *backend_x11 = stage_x11->backend;
|
||||||
|
ClutterStage *stage = stage_x11->wrapper;
|
||||||
static gboolean was_resizeable = FALSE;
|
static gboolean was_resizeable = FALSE;
|
||||||
|
|
||||||
if (fullscreen)
|
if (!stage)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (is_fullscreen)
|
||||||
{
|
{
|
||||||
if (stage_x11->xwin != None)
|
if (stage_x11->xwin != None)
|
||||||
{
|
{
|
||||||
@ -311,19 +322,19 @@ clutter_stage_x11_set_fullscreen (ClutterStage *stage,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_stage_x11_set_cursor_visible (ClutterStage *stage,
|
clutter_stage_x11_set_cursor_visible (ClutterStageWindow *stage_window,
|
||||||
gboolean show_cursor)
|
gboolean cursor_visible)
|
||||||
{
|
{
|
||||||
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage);
|
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
|
||||||
|
|
||||||
if (stage_x11->xwin == None)
|
if (stage_x11->xwin == None)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
CLUTTER_NOTE (BACKEND, "setting cursor state ('%s') over stage window (%u)",
|
CLUTTER_NOTE (BACKEND, "setting cursor state ('%s') over stage window (%u)",
|
||||||
show_cursor ? "visible" : "invisible",
|
cursor_visible ? "visible" : "invisible",
|
||||||
(unsigned int) stage_x11->xwin);
|
(unsigned int) stage_x11->xwin);
|
||||||
|
|
||||||
if (show_cursor)
|
if (cursor_visible)
|
||||||
{
|
{
|
||||||
#if 0 /* HAVE_XFIXES - seems buggy/unreliable */
|
#if 0 /* HAVE_XFIXES - seems buggy/unreliable */
|
||||||
XFixesShowCursor (stage_x11->xdpy, stage_x11->xwin);
|
XFixesShowCursor (stage_x11->xdpy, stage_x11->xwin);
|
||||||
@ -355,10 +366,10 @@ clutter_stage_x11_set_cursor_visible (ClutterStage *stage,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_stage_x11_set_title (ClutterStage *stage,
|
clutter_stage_x11_set_title (ClutterStageWindow *stage_window,
|
||||||
const gchar *title)
|
const gchar *title)
|
||||||
{
|
{
|
||||||
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage);
|
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
|
||||||
ClutterBackendX11 *backend_x11 = stage_x11->backend;
|
ClutterBackendX11 *backend_x11 = stage_x11->backend;
|
||||||
|
|
||||||
if (stage_x11->xwin == None)
|
if (stage_x11->xwin == None)
|
||||||
@ -384,14 +395,20 @@ clutter_stage_x11_set_title (ClutterStage *stage,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_stage_x11_set_user_resize (ClutterStage *stage,
|
clutter_stage_x11_set_user_resizable (ClutterStageWindow *stage_window,
|
||||||
gboolean value)
|
gboolean is_resizable)
|
||||||
{
|
{
|
||||||
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage);
|
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
|
||||||
|
|
||||||
clutter_stage_x11_fix_window_size (stage_x11);
|
clutter_stage_x11_fix_window_size (stage_x11);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ClutterActor *
|
||||||
|
clutter_stage_x11_get_wrapper (ClutterStageWindow *stage_window)
|
||||||
|
{
|
||||||
|
return CLUTTER_ACTOR (CLUTTER_STAGE_X11 (stage_window)->wrapper);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_stage_x11_dispose (GObject *gobject)
|
clutter_stage_x11_dispose (GObject *gobject)
|
||||||
{
|
{
|
||||||
@ -408,7 +425,6 @@ clutter_stage_x11_class_init (ClutterStageX11Class *klass)
|
|||||||
{
|
{
|
||||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
||||||
ClutterStageClass *stage_class = CLUTTER_STAGE_CLASS (klass);
|
|
||||||
|
|
||||||
gobject_class->dispose = clutter_stage_x11_dispose;
|
gobject_class->dispose = clutter_stage_x11_dispose;
|
||||||
|
|
||||||
@ -416,11 +432,6 @@ clutter_stage_x11_class_init (ClutterStageX11Class *klass)
|
|||||||
actor_class->hide = clutter_stage_x11_hide;
|
actor_class->hide = clutter_stage_x11_hide;
|
||||||
actor_class->request_coords = clutter_stage_x11_request_coords;
|
actor_class->request_coords = clutter_stage_x11_request_coords;
|
||||||
actor_class->query_coords = clutter_stage_x11_query_coords;
|
actor_class->query_coords = clutter_stage_x11_query_coords;
|
||||||
|
|
||||||
stage_class->set_fullscreen = clutter_stage_x11_set_fullscreen;
|
|
||||||
stage_class->set_cursor_visible = clutter_stage_x11_set_cursor_visible;
|
|
||||||
stage_class->set_title = clutter_stage_x11_set_title;
|
|
||||||
stage_class->set_user_resize = clutter_stage_x11_set_user_resize;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -439,7 +450,22 @@ clutter_stage_x11_init (ClutterStageX11 *stage)
|
|||||||
stage->fullscreen_on_map = FALSE;
|
stage->fullscreen_on_map = FALSE;
|
||||||
stage->handling_configure = FALSE;
|
stage->handling_configure = FALSE;
|
||||||
|
|
||||||
|
stage->wrapper = NULL;
|
||||||
|
|
||||||
|
CLUTTER_SET_PRIVATE_FLAGS (stage, CLUTTER_ACTOR_IS_TOPLEVEL);
|
||||||
|
#if 0
|
||||||
CLUTTER_SET_PRIVATE_FLAGS (stage, CLUTTER_ACTOR_SYNC_MATRICES);
|
CLUTTER_SET_PRIVATE_FLAGS (stage, CLUTTER_ACTOR_SYNC_MATRICES);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_stage_window_iface_init (ClutterStageWindowIface *iface)
|
||||||
|
{
|
||||||
|
iface->get_wrapper = clutter_stage_x11_get_wrapper;
|
||||||
|
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;
|
||||||
|
iface->set_user_resizable = clutter_stage_x11_set_user_resizable;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -455,9 +481,14 @@ clutter_stage_x11_init (ClutterStageX11 *stage)
|
|||||||
Window
|
Window
|
||||||
clutter_x11_get_stage_window (ClutterStage *stage)
|
clutter_x11_get_stage_window (ClutterStage *stage)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (CLUTTER_IS_STAGE_X11 (stage), None);
|
ClutterStageWindow *impl;
|
||||||
|
|
||||||
return CLUTTER_STAGE_X11 (stage)->xwin;
|
g_return_val_if_fail (CLUTTER_IS_STAGE (stage), None);
|
||||||
|
|
||||||
|
impl = _clutter_stage_get_window (stage);
|
||||||
|
g_assert (CLUTTER_IS_STAGE_X11 (impl));
|
||||||
|
|
||||||
|
return CLUTTER_STAGE_X11 (impl)->xwin;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -470,7 +501,7 @@ clutter_x11_get_stage_window (ClutterStage *stage)
|
|||||||
*
|
*
|
||||||
* Since: 0.8
|
* Since: 0.8
|
||||||
*/
|
*/
|
||||||
ClutterStage*
|
ClutterStage *
|
||||||
clutter_x11_get_stage_from_window (Window win)
|
clutter_x11_get_stage_from_window (Window win)
|
||||||
{
|
{
|
||||||
ClutterMainContext *context;
|
ClutterMainContext *context;
|
||||||
@ -484,10 +515,14 @@ clutter_x11_get_stage_from_window (Window win)
|
|||||||
/* FIXME: use a hash here for performance resaon */
|
/* FIXME: use a hash here for performance resaon */
|
||||||
for (l = stage_manager->stages; l; l = l->next)
|
for (l = stage_manager->stages; l; l = l->next)
|
||||||
{
|
{
|
||||||
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (l->data);
|
ClutterStage *stage = l->data;
|
||||||
|
ClutterStageWindow *impl;
|
||||||
|
|
||||||
if (stage_x11->xwin == win)
|
impl = _clutter_stage_get_window (stage);
|
||||||
return CLUTTER_STAGE(stage_x11);
|
g_assert (CLUTTER_IS_STAGE_X11 (impl));
|
||||||
|
|
||||||
|
if (CLUTTER_STAGE_X11 (impl)->xwin == win)
|
||||||
|
return stage;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -506,9 +541,14 @@ clutter_x11_get_stage_from_window (Window win)
|
|||||||
XVisualInfo *
|
XVisualInfo *
|
||||||
clutter_x11_get_stage_visual (ClutterStage *stage)
|
clutter_x11_get_stage_visual (ClutterStage *stage)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (CLUTTER_IS_STAGE_X11 (stage), NULL);
|
ClutterStageWindow *impl;
|
||||||
|
|
||||||
return CLUTTER_STAGE_X11 (stage)->xvisinfo;
|
g_return_val_if_fail (CLUTTER_IS_STAGE (stage), NULL);
|
||||||
|
|
||||||
|
impl = _clutter_stage_get_window (stage);
|
||||||
|
g_assert (CLUTTER_IS_STAGE_X11 (impl));
|
||||||
|
|
||||||
|
return CLUTTER_STAGE_X11 (impl)->xvisinfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -527,6 +567,7 @@ clutter_x11_set_stage_foreign (ClutterStage *stage,
|
|||||||
Window xwindow)
|
Window xwindow)
|
||||||
{
|
{
|
||||||
ClutterStageX11 *stage_x11;
|
ClutterStageX11 *stage_x11;
|
||||||
|
ClutterStageWindow *impl;
|
||||||
ClutterActor *actor;
|
ClutterActor *actor;
|
||||||
gint x, y;
|
gint x, y;
|
||||||
guint width, height, border, depth;
|
guint width, height, border, depth;
|
||||||
@ -534,11 +575,12 @@ clutter_x11_set_stage_foreign (ClutterStage *stage,
|
|||||||
Status status;
|
Status status;
|
||||||
ClutterGeometry geom;
|
ClutterGeometry geom;
|
||||||
|
|
||||||
g_return_val_if_fail (CLUTTER_IS_STAGE_X11 (stage), FALSE);
|
g_return_val_if_fail (CLUTTER_IS_STAGE (stage), FALSE);
|
||||||
g_return_val_if_fail (xwindow != None, FALSE);
|
g_return_val_if_fail (xwindow != None, FALSE);
|
||||||
|
|
||||||
stage_x11 = CLUTTER_STAGE_X11 (stage);
|
impl = _clutter_stage_get_window (stage);
|
||||||
actor = CLUTTER_ACTOR (stage);
|
stage_x11 = CLUTTER_STAGE_X11 (impl);
|
||||||
|
actor = CLUTTER_ACTOR (impl);
|
||||||
|
|
||||||
clutter_x11_trap_x_errors ();
|
clutter_x11_trap_x_errors ();
|
||||||
|
|
||||||
@ -577,19 +619,27 @@ clutter_x11_set_stage_foreign (ClutterStage *stage,
|
|||||||
void
|
void
|
||||||
clutter_stage_x11_map (ClutterStageX11 *stage_x11)
|
clutter_stage_x11_map (ClutterStageX11 *stage_x11)
|
||||||
{
|
{
|
||||||
|
/* set the mapped flag on the implementation */
|
||||||
CLUTTER_ACTOR_SET_FLAGS (stage_x11, CLUTTER_ACTOR_MAPPED);
|
CLUTTER_ACTOR_SET_FLAGS (stage_x11, CLUTTER_ACTOR_MAPPED);
|
||||||
|
|
||||||
if (stage_x11->fullscreen_on_map)
|
/* and on the wrapper itself */
|
||||||
clutter_stage_fullscreen (CLUTTER_STAGE (stage_x11));
|
CLUTTER_ACTOR_SET_FLAGS (stage_x11->wrapper, CLUTTER_ACTOR_MAPPED);
|
||||||
else
|
|
||||||
clutter_stage_unfullscreen (CLUTTER_STAGE (stage_x11));
|
|
||||||
|
|
||||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage_x11));
|
if (stage_x11->fullscreen_on_map)
|
||||||
|
clutter_stage_fullscreen (CLUTTER_STAGE (stage_x11->wrapper));
|
||||||
|
else
|
||||||
|
clutter_stage_unfullscreen (CLUTTER_STAGE (stage_x11->wrapper));
|
||||||
|
|
||||||
|
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage_x11->wrapper));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
clutter_stage_x11_unmap (ClutterStageX11 *stage_x11)
|
clutter_stage_x11_unmap (ClutterStageX11 *stage_x11)
|
||||||
{
|
{
|
||||||
|
/* like above, unset the MAPPED stage on both the implementation and
|
||||||
|
* the wrapper
|
||||||
|
*/
|
||||||
CLUTTER_ACTOR_UNSET_FLAGS (stage_x11, CLUTTER_ACTOR_MAPPED);
|
CLUTTER_ACTOR_UNSET_FLAGS (stage_x11, CLUTTER_ACTOR_MAPPED);
|
||||||
|
CLUTTER_ACTOR_UNSET_FLAGS (stage_x11->wrapper, CLUTTER_ACTOR_MAPPED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
#ifndef __CLUTTER_STAGE_X11_H__
|
#ifndef __CLUTTER_STAGE_X11_H__
|
||||||
#define __CLUTTER_STAGE_X11_H__
|
#define __CLUTTER_STAGE_X11_H__
|
||||||
|
|
||||||
#include <glib-object.h>
|
#include <clutter/clutter-group.h>
|
||||||
#include <clutter/clutter-stage.h>
|
#include <clutter/clutter-stage.h>
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <X11/Xatom.h>
|
#include <X11/Xatom.h>
|
||||||
@ -43,7 +43,7 @@ typedef struct _ClutterStageX11Class ClutterStageX11Class;
|
|||||||
|
|
||||||
struct _ClutterStageX11
|
struct _ClutterStageX11
|
||||||
{
|
{
|
||||||
ClutterStage parent_instance;
|
ClutterGroup parent_instance;
|
||||||
|
|
||||||
guint is_foreign_xwin : 1;
|
guint is_foreign_xwin : 1;
|
||||||
guint fullscreen_on_map : 1;
|
guint fullscreen_on_map : 1;
|
||||||
@ -60,11 +60,13 @@ struct _ClutterStageX11
|
|||||||
|
|
||||||
ClutterBackendX11 *backend;
|
ClutterBackendX11 *backend;
|
||||||
ClutterStageState state;
|
ClutterStageState state;
|
||||||
|
|
||||||
|
ClutterStage *wrapper;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _ClutterStageX11Class
|
struct _ClutterStageX11Class
|
||||||
{
|
{
|
||||||
ClutterStageClass parent_class;
|
ClutterGroupClass parent_class;
|
||||||
};
|
};
|
||||||
|
|
||||||
GType clutter_stage_x11_get_type (void) G_GNUC_CONST;
|
GType clutter_stage_x11_get_type (void) G_GNUC_CONST;
|
||||||
@ -72,9 +74,8 @@ GType clutter_stage_x11_get_type (void) G_GNUC_CONST;
|
|||||||
/* Private to subclasses */
|
/* Private to subclasses */
|
||||||
void clutter_stage_x11_fix_window_size (ClutterStageX11 *stage_x11);
|
void clutter_stage_x11_fix_window_size (ClutterStageX11 *stage_x11);
|
||||||
void clutter_stage_x11_set_wm_protocols (ClutterStageX11 *stage_x11);
|
void clutter_stage_x11_set_wm_protocols (ClutterStageX11 *stage_x11);
|
||||||
|
void clutter_stage_x11_map (ClutterStageX11 *stage_x11);
|
||||||
void clutter_stage_x11_map (ClutterStageX11 *stage_x11);
|
void clutter_stage_x11_unmap (ClutterStageX11 *stage_x11);
|
||||||
void clutter_stage_x11_unmap (ClutterStageX11 *stage_x11);
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ on_button_press (ClutterActor *actor,
|
|||||||
ClutterAlpha *alpha;
|
ClutterAlpha *alpha;
|
||||||
ClutterBehaviour *r_behave;
|
ClutterBehaviour *r_behave;
|
||||||
|
|
||||||
new_stage = clutter_stage_create_new ();
|
new_stage = clutter_stage_new ();
|
||||||
|
|
||||||
/* FIXME: below should really be automatic */
|
/* FIXME: below should really be automatic */
|
||||||
/* clutter_stage_ensure_cogl_context (CLUTTER_STAGE(new_stage)); */
|
/* clutter_stage_ensure_cogl_context (CLUTTER_STAGE(new_stage)); */
|
||||||
|
Loading…
Reference in New Issue
Block a user