diff --git a/clutter/Makefile.am b/clutter/Makefile.am index 3738aae2d..85aa046f8 100644 --- a/clutter/Makefile.am +++ b/clutter/Makefile.am @@ -89,6 +89,7 @@ source_h = \ $(srcdir)/clutter-shader-types.h \ $(srcdir)/clutter-stage.h \ $(srcdir)/clutter-stage-manager.h \ + $(srcdir)/clutter-stage-window.h \ $(srcdir)/clutter-texture.h \ $(srcdir)/clutter-text.h \ $(srcdir)/clutter-timeline.h \ @@ -202,7 +203,6 @@ source_h_priv = \ $(srcdir)/clutter-private.h \ $(srcdir)/clutter-id-pool.h \ $(srcdir)/clutter-script-private.h \ - $(srcdir)/clutter-stage-window.h \ $(srcdir)/clutter-timeout-interval.h \ $(NULL) diff --git a/clutter/clutter-backend.c b/clutter/clutter-backend.c index 6e8dac0a2..c95ac9bc7 100644 --- a/clutter/clutter-backend.c +++ b/clutter/clutter-backend.c @@ -258,14 +258,14 @@ _clutter_backend_post_parse (ClutterBackend *backend, return TRUE; } -ClutterActor * +ClutterStageWindow * _clutter_backend_create_stage (ClutterBackend *backend, ClutterStage *wrapper, GError **error) { ClutterBackendClass *klass; ClutterStageManager *stage_manager; - ClutterActor *stage = NULL; + ClutterStageWindow *stage_window; g_return_val_if_fail (CLUTTER_IS_BACKEND (backend), FALSE); g_return_val_if_fail (CLUTTER_IS_STAGE (wrapper), FALSE); @@ -274,16 +274,16 @@ _clutter_backend_create_stage (ClutterBackend *backend, klass = CLUTTER_BACKEND_GET_CLASS (backend); if (klass->create_stage) - stage = klass->create_stage (backend, wrapper, error); + stage_window = klass->create_stage (backend, wrapper, error); - if (!stage) + if (!stage_window) return NULL; - g_assert (CLUTTER_IS_STAGE_WINDOW (stage)); - _clutter_stage_set_window (wrapper, CLUTTER_STAGE_WINDOW (stage)); + g_assert (CLUTTER_IS_STAGE_WINDOW (stage_window)); + _clutter_stage_set_window (wrapper, stage_window); _clutter_stage_manager_add_stage (stage_manager, wrapper); - return stage; + return stage_window; } void diff --git a/clutter/clutter-backend.h b/clutter/clutter-backend.h index 6529100c4..f6bd519c6 100644 --- a/clutter/clutter-backend.h +++ b/clutter/clutter-backend.h @@ -33,9 +33,10 @@ #include #include -#include #include #include +#include +#include G_BEGIN_DECLS @@ -67,7 +68,7 @@ struct _ClutterBackendClass GError **error); gboolean (* post_parse) (ClutterBackend *backend, GError **error); - ClutterActor * (* create_stage) (ClutterBackend *backend, + ClutterStageWindow *(* create_stage) (ClutterBackend *backend, ClutterStage *wrapper, GError **error); void (* init_events) (ClutterBackend *backend); diff --git a/clutter/clutter-private.h b/clutter/clutter-private.h index f5d958780..bd6f5dbe2 100644 --- a/clutter/clutter-private.h +++ b/clutter/clutter-private.h @@ -188,7 +188,7 @@ GType _clutter_backend_impl_get_type (void); void _clutter_backend_redraw (ClutterBackend *backend, ClutterStage *stage); -ClutterActor *_clutter_backend_create_stage (ClutterBackend *backend, +ClutterStageWindow *_clutter_backend_create_stage (ClutterBackend *backend, ClutterStage *wrapper, GError **error); void _clutter_backend_ensure_context (ClutterBackend *backend, diff --git a/clutter/clutter-stage-window.c b/clutter/clutter-stage-window.c index e74810503..e413aee36 100644 --- a/clutter/clutter-stage-window.c +++ b/clutter/clutter-stage-window.c @@ -26,8 +26,85 @@ clutter_stage_window_get_type (void) &stage_window_info, 0); g_type_interface_add_prerequisite (stage_window_type, - CLUTTER_TYPE_ACTOR); + G_TYPE_OBJECT); } return stage_window_type; } + +ClutterActor * +_clutter_stage_window_get_wrapper (ClutterStageWindow *window) +{ + return CLUTTER_STAGE_WINDOW_GET_IFACE (window)->get_wrapper (window); +} + +void +_clutter_stage_window_set_title (ClutterStageWindow *window, + const gchar *title) +{ + CLUTTER_STAGE_WINDOW_GET_IFACE (window)->set_title (window, title); +} + +void +_clutter_stage_window_set_fullscreen (ClutterStageWindow *window, + gboolean is_fullscreen) +{ + CLUTTER_STAGE_WINDOW_GET_IFACE (window)->set_fullscreen (window, + is_fullscreen); +} + +void +_clutter_stage_window_set_cursor_visible (ClutterStageWindow *window, + gboolean is_visible) +{ + CLUTTER_STAGE_WINDOW_GET_IFACE (window)->set_cursor_visible (window, + is_visible); +} + +void +_clutter_stage_window_set_user_resizable (ClutterStageWindow *window, + gboolean is_resizable) +{ + CLUTTER_STAGE_WINDOW_GET_IFACE (window)->set_user_resizable (window, + is_resizable); +} + +gboolean +_clutter_stage_window_realize (ClutterStageWindow *window) +{ + return CLUTTER_STAGE_WINDOW_GET_IFACE (window)->realize (window); +} + +void +_clutter_stage_window_unrealize (ClutterStageWindow *window) +{ + CLUTTER_STAGE_WINDOW_GET_IFACE (window)->unrealize (window); +} + +void +_clutter_stage_window_show (ClutterStageWindow *window, + gboolean do_raise) +{ + CLUTTER_STAGE_WINDOW_GET_IFACE (window)->show (window, do_raise); +} + +void +_clutter_stage_window_hide (ClutterStageWindow *window) +{ + CLUTTER_STAGE_WINDOW_GET_IFACE (window)->hide (window); +} + +void +_clutter_stage_window_resize (ClutterStageWindow *window, + gint width, + gint height) +{ + CLUTTER_STAGE_WINDOW_GET_IFACE (window)->resize (window, width, height); +} + +void +_clutter_stage_window_get_geometry (ClutterStageWindow *window, + ClutterGeometry *geometry) +{ + CLUTTER_STAGE_WINDOW_GET_IFACE (window)->get_geometry (window, geometry); +} diff --git a/clutter/clutter-stage-window.h b/clutter/clutter-stage-window.h index a46662acd..c5a5e0426 100644 --- a/clutter/clutter-stage-window.h +++ b/clutter/clutter-stage-window.h @@ -28,13 +28,46 @@ struct _ClutterStageWindowIface void (* set_user_resizable) (ClutterStageWindow *stage_window, gboolean is_resizable); + gboolean (* realize) (ClutterStageWindow *stage_window); + void (* unrealize) (ClutterStageWindow *stage_window); + void (* show) (ClutterStageWindow *stage_window, gboolean do_raise); void (* hide) (ClutterStageWindow *stage_window); + + void (* resize) (ClutterStageWindow *stage_window, + gint width, + gint height); + void (* get_geometry) (ClutterStageWindow *stage_window, + ClutterGeometry *geometry); }; GType clutter_stage_window_get_type (void) G_GNUC_CONST; +ClutterActor *_clutter_stage_window_get_wrapper (ClutterStageWindow *window); + +void _clutter_stage_window_set_title (ClutterStageWindow *window, + const gchar *title); +void _clutter_stage_window_set_fullscreen (ClutterStageWindow *window, + gboolean is_fullscreen); +void _clutter_stage_window_set_cursor_visible (ClutterStageWindow *window, + gboolean is_visible); +void _clutter_stage_window_set_user_resizable (ClutterStageWindow *window, + gboolean is_resizable); + +gboolean _clutter_stage_window_realize (ClutterStageWindow *window); +void _clutter_stage_window_unrealize (ClutterStageWindow *window); + +void _clutter_stage_window_show (ClutterStageWindow *window, + gboolean do_raise); +void _clutter_stage_window_hide (ClutterStageWindow *window); + +void _clutter_stage_window_resize (ClutterStageWindow *window, + gint width, + gint height); +void _clutter_stage_window_get_geometry (ClutterStageWindow *window, + ClutterGeometry *geometry); + G_END_DECLS #endif /* __CLUTTER_STAGE_WINDOW_H__ */ diff --git a/clutter/clutter-stage.c b/clutter/clutter-stage.c index dd1c03832..f93ec786e 100644 --- a/clutter/clutter-stage.c +++ b/clutter/clutter-stage.c @@ -78,7 +78,7 @@ G_DEFINE_TYPE (ClutterStage, clutter_stage, CLUTTER_TYPE_GROUP); struct _ClutterStagePrivate { /* the stage implementation */ - ClutterActor *impl; + ClutterStageWindow *impl; ClutterColor color; ClutterPerspective perspective; @@ -134,14 +134,18 @@ clutter_stage_get_preferred_width (ClutterActor *self, gfloat *natural_width_p) { ClutterStagePrivate *priv = CLUTTER_STAGE (self)->priv; + ClutterGeometry geom = { 0, }; if (priv->impl == NULL) return; - CLUTTER_ACTOR_GET_CLASS (priv->impl)->get_preferred_width (priv->impl, - for_height, - min_width_p, - natural_width_p); + _clutter_stage_window_get_geometry (priv->impl, &geom); + + if (min_width_p) + *min_width_p = geom.width; + + if (natural_width_p) + *natural_width_p = geom.width; } static void @@ -151,14 +155,18 @@ clutter_stage_get_preferred_height (ClutterActor *self, gfloat *natural_height_p) { ClutterStagePrivate *priv = CLUTTER_STAGE (self)->priv; + ClutterGeometry geom = { 0, }; if (priv->impl == NULL) return; - CLUTTER_ACTOR_GET_CLASS (priv->impl)->get_preferred_height (priv->impl, - for_width, - min_height_p, - natural_height_p); + _clutter_stage_window_get_geometry (priv->impl, &geom); + + if (min_height_p) + *min_height_p = geom.height; + + if (natural_height_p) + *natural_height_p = geom.height; } static void clutter_stage_allocate (ClutterActor *self, @@ -167,12 +175,16 @@ clutter_stage_allocate (ClutterActor *self, { ClutterStagePrivate *priv = CLUTTER_STAGE (self)->priv; gboolean origin_changed; + gint width, height; origin_changed = (flags & CLUTTER_ABSOLUTE_ORIGIN_CHANGED) ? TRUE : FALSE; if (priv->impl == NULL) return; + width = clutter_actor_box_get_width (box); + height = clutter_actor_box_get_height (box); + /* if the stage is fixed size (for instance, it's using a frame-buffer) * then we simply ignore any allocation request and override the * allocation chain. @@ -183,41 +195,31 @@ clutter_stage_allocate (ClutterActor *self, CLUTTER_NOTE (LAYOUT, "Following allocation to %dx%d (origin %s)", - (int) (box->x2 - box->x1), - (int) (box->y2 - box->y1), + width, height, origin_changed ? "changed" : "not changed"); klass = CLUTTER_ACTOR_CLASS (clutter_stage_parent_class); klass->allocate (self, box, flags); - klass = CLUTTER_ACTOR_GET_CLASS (priv->impl); - klass->allocate (priv->impl, box, flags); + _clutter_stage_window_resize (priv->impl, width, height); } else { ClutterActorBox override = { 0, }; + ClutterGeometry geom = { 0, }; ClutterActorClass *klass; - gfloat natural_width, natural_height; - /* propagate the allocation */ - klass = CLUTTER_ACTOR_GET_CLASS (priv->impl); - klass->allocate (self, box, flags); - - /* get the preferred size from the backend */ - clutter_actor_get_preferred_size (priv->impl, - NULL, NULL, - &natural_width, &natural_height); + _clutter_stage_window_get_geometry (priv->impl, &geom); override.x1 = 0; override.y1 = 0; - override.x2 = natural_width; - override.y2 = natural_height; + override.x2 = geom.width; + override.y2 = geom.height; CLUTTER_NOTE (LAYOUT, "Overrigin original allocation of %dx%d " "with %dx%d (origin %s)", - (int) (box->x2 - box->x1), - (int) (box->y2 - box->y1), + width, height, (int) (override.x2), (int) (override.y2), origin_changed ? "changed" : "not changed"); @@ -260,8 +262,10 @@ clutter_stage_paint (ClutterActor *self) else cogl_disable_fog (); +#if 0 CLUTTER_NOTE (PAINT, "Proxying the paint to the stage implementation"); - clutter_actor_paint (priv->impl); + _clutter_stage_window_paint (priv->impl); +#endif /* this will take care of painting every child */ CLUTTER_ACTOR_CLASS (clutter_stage_parent_class)->paint (self); @@ -283,6 +287,7 @@ static void clutter_stage_realize (ClutterActor *self) { ClutterStagePrivate *priv = CLUTTER_STAGE (self)->priv; + gboolean is_realized; /* Make sure the viewport and projection matrix are valid for the * first paint (which will likely occur before the ConfigureNotify @@ -291,13 +296,16 @@ clutter_stage_realize (ClutterActor *self) CLUTTER_SET_PRIVATE_FLAGS (self, CLUTTER_ACTOR_SYNC_MATRICES); g_assert (priv->impl != NULL); - clutter_actor_realize (priv->impl); + is_realized = _clutter_stage_window_realize (priv->impl); /* ensure that the stage is using the context if the * realization sequence was successful */ - if (CLUTTER_ACTOR_IS_REALIZED (priv->impl)) - clutter_stage_ensure_current (CLUTTER_STAGE (self)); + if (is_realized) + { + CLUTTER_ACTOR_SET_FLAGS (self, CLUTTER_ACTOR_REALIZED); + clutter_stage_ensure_current (CLUTTER_STAGE (self)); + } else CLUTTER_ACTOR_UNSET_FLAGS (self, CLUTTER_ACTOR_REALIZED); } @@ -309,7 +317,9 @@ clutter_stage_unrealize (ClutterActor *self) /* and then unrealize the implementation */ g_assert (priv->impl != NULL); - clutter_actor_unrealize (priv->impl); + _clutter_stage_window_unrealize (priv->impl); + + CLUTTER_ACTOR_UNSET_FLAGS (self, CLUTTER_ACTOR_REALIZED); clutter_stage_ensure_current (CLUTTER_STAGE (self)); } @@ -318,7 +328,6 @@ static void clutter_stage_show (ClutterActor *self) { ClutterStagePrivate *priv = CLUTTER_STAGE (self)->priv; - ClutterStageWindow *impl; CLUTTER_ACTOR_CLASS (clutter_stage_parent_class)->show (self); @@ -327,19 +336,16 @@ clutter_stage_show (ClutterActor *self) _clutter_stage_maybe_relayout (self); g_assert (priv->impl != NULL); - impl = CLUTTER_STAGE_WINDOW (priv->impl); - CLUTTER_STAGE_WINDOW_GET_IFACE (impl)->show (impl, TRUE); + _clutter_stage_window_show (priv->impl, TRUE); } static void clutter_stage_hide (ClutterActor *self) { ClutterStagePrivate *priv = CLUTTER_STAGE (self)->priv; - ClutterStageWindow *impl; g_assert (priv->impl != NULL); - impl = CLUTTER_STAGE_WINDOW (priv->impl); - CLUTTER_STAGE_WINDOW_GET_IFACE (impl)->hide (impl); + _clutter_stage_window_hide (priv->impl); CLUTTER_ACTOR_CLASS (clutter_stage_parent_class)->hide (self); } @@ -375,7 +381,7 @@ static void clutter_stage_real_fullscreen (ClutterStage *stage) { ClutterStagePrivate *priv = stage->priv; - gfloat natural_width, natural_height; + ClutterGeometry geom; ClutterActorBox box; /* we need to force an allocation here because the size @@ -385,14 +391,12 @@ clutter_stage_real_fullscreen (ClutterStage *stage) * the fact that fullscreening the stage on the X11 backends * is really an asynchronous operation */ - clutter_actor_get_preferred_size (CLUTTER_ACTOR (priv->impl), - NULL, NULL, - &natural_width, &natural_height); + _clutter_stage_window_get_geometry (priv->impl, &geom); box.x1 = 0; box.y1 = 0; - box.x2 = natural_width; - box.y2 = natural_height; + box.x2 = geom.width; + box.y2 = geom.height; clutter_actor_allocate (CLUTTER_ACTOR (stage), &box, @@ -723,11 +727,11 @@ clutter_stage_dispose (GObject *object) _clutter_stage_manager_remove_stage (stage_manager, stage); - if (priv->impl) + if (priv->impl != NULL) { CLUTTER_NOTE (BACKEND, "Disposing of the stage implementation"); - clutter_actor_hide (priv->impl); - clutter_actor_destroy (priv->impl); + + g_object_unref (priv->impl); priv->impl = NULL; } @@ -1008,16 +1012,11 @@ clutter_stage_init (ClutterStage *self) { g_warning ("Unable to create a new stage, falling back to the " "default stage."); - priv->impl = CLUTTER_ACTOR (_clutter_stage_get_default_window ()); + priv->impl = _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); - - /* make sure that the implementation is considered a top level */ - CLUTTER_SET_PRIVATE_FLAGS (priv->impl, CLUTTER_ACTOR_IS_TOPLEVEL); priv->event_queue = g_queue_new (); @@ -2044,7 +2043,7 @@ _clutter_stage_set_window (ClutterStage *stage, if (stage->priv->impl) g_object_unref (stage->priv->impl); - stage->priv->impl = CLUTTER_ACTOR (stage_window); + stage->priv->impl = stage_window; } ClutterStageWindow * diff --git a/clutter/clutter.h b/clutter/clutter.h index 3ae479e2d..701cf3176 100644 --- a/clutter/clutter.h +++ b/clutter/clutter.h @@ -67,6 +67,7 @@ #include "clutter-shader-types.h" #include "clutter-stage.h" #include "clutter-stage-manager.h" +#include "clutter-stage-window.h" #include "clutter-texture.h" #include "clutter-text.h" #include "clutter-timeline.h" diff --git a/clutter/glx/clutter-backend-glx.c b/clutter/glx/clutter-backend-glx.c index 39d2c26c6..4b4e59610 100644 --- a/clutter/glx/clutter-backend-glx.c +++ b/clutter/glx/clutter-backend-glx.c @@ -585,22 +585,22 @@ clutter_backend_glx_redraw (ClutterBackend *backend, } } -static ClutterActor * +static ClutterStageWindow * clutter_backend_glx_create_stage (ClutterBackend *backend, ClutterStage *wrapper, GError **error) { ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend); - ClutterStageX11 *stage_x11; - ClutterActor *stage; + ClutterStageWindow *stage_window; + ClutterStageX11 *stage_x11; CLUTTER_NOTE (BACKEND, "Creating stage of type '%s'", g_type_name (CLUTTER_STAGE_TYPE)); - stage = g_object_new (CLUTTER_TYPE_STAGE_GLX, NULL); + stage_window = g_object_new (CLUTTER_TYPE_STAGE_GLX, NULL); /* copy backend data into the stage */ - stage_x11 = CLUTTER_STAGE_X11 (stage); + stage_x11 = CLUTTER_STAGE_X11 (stage_window); stage_x11->xdpy = backend_x11->xdpy; stage_x11->xwin_root = backend_x11->xwin_root; stage_x11->xscreen = backend_x11->xscreen_num; @@ -609,13 +609,13 @@ clutter_backend_glx_create_stage (ClutterBackend *backend, CLUTTER_NOTE (BACKEND, "GLX stage created[%p] (dpy:%p, screen:%d, root:%u, wrap:%p)", - stage, + stage_window, stage_x11->xdpy, stage_x11->xscreen, (unsigned int) stage_x11->xwin_root, wrapper); - return stage; + return stage_window; } static XVisualInfo * diff --git a/clutter/glx/clutter-stage-glx.c b/clutter/glx/clutter-stage-glx.c index f36a849b6..67d0afb4e 100644 --- a/clutter/glx/clutter-stage-glx.c +++ b/clutter/glx/clutter-stage-glx.c @@ -49,6 +49,8 @@ static void clutter_stage_window_iface_init (ClutterStageWindowIface *iface); +static ClutterStageWindowIface *clutter_stage_glx_parent_iface = NULL; + G_DEFINE_TYPE_WITH_CODE (ClutterStageGLX, clutter_stage_glx, CLUTTER_TYPE_STAGE_X11, @@ -56,10 +58,10 @@ G_DEFINE_TYPE_WITH_CODE (ClutterStageGLX, clutter_stage_window_iface_init)); static void -clutter_stage_glx_unrealize (ClutterActor *actor) +clutter_stage_glx_unrealize (ClutterStageWindow *stage_window) { - ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (actor); - ClutterStageGLX *stage_glx = CLUTTER_STAGE_GLX (actor); + ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window); + ClutterStageGLX *stage_glx = CLUTTER_STAGE_GLX (stage_window); gboolean was_offscreen; /* Note unrealize should free up any backend stage related resources */ @@ -67,9 +69,6 @@ clutter_stage_glx_unrealize (ClutterActor *actor) g_object_get (stage_x11->wrapper, "offscreen", &was_offscreen, NULL); - if (CLUTTER_ACTOR_CLASS (clutter_stage_glx_parent_class)->unrealize != NULL) - CLUTTER_ACTOR_CLASS (clutter_stage_glx_parent_class)->unrealize (actor); - clutter_x11_trap_x_errors (); if (G_UNLIKELY (was_offscreen)) @@ -110,19 +109,19 @@ clutter_stage_glx_unrealize (ClutterActor *actor) CLUTTER_MARK (); } -static void -clutter_stage_glx_realize (ClutterActor *actor) +static gboolean +clutter_stage_glx_realize (ClutterStageWindow *stage_window) { - ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (actor); - ClutterStageGLX *stage_glx = CLUTTER_STAGE_GLX (actor); + ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window); + ClutterStageGLX *stage_glx = CLUTTER_STAGE_GLX (stage_window); ClutterBackend *backend; ClutterBackendGLX *backend_glx; ClutterBackendX11 *backend_x11; gboolean is_offscreen; CLUTTER_NOTE (ACTOR, "Realizing stage '%s' [%p]", - G_OBJECT_TYPE_NAME (actor), - actor); + G_OBJECT_TYPE_NAME (stage_window), + stage_window); g_object_get (stage_x11->wrapper, "offscreen", &is_offscreen, NULL); @@ -140,7 +139,7 @@ clutter_stage_glx_realize (ClutterActor *actor) if (stage_x11->xvisinfo == None) { g_critical ("Unable to find suitable GL visual."); - goto fail; + return FALSE; } if (stage_x11->xwin == None) @@ -209,7 +208,7 @@ clutter_stage_glx_realize (ClutterActor *actor) { g_critical ("Unable to realize stage: %s", error->message); g_error_free (error); - goto fail; + return FALSE; } CLUTTER_NOTE (BACKEND, "Successfully realized stage"); @@ -230,7 +229,7 @@ clutter_stage_glx_realize (ClutterActor *actor) if (stage_x11->xvisinfo == None) { g_critical ("Unable to find suitable GL visual."); - goto fail; + return FALSE; } stage_x11->xpixmap = XCreatePixmap (stage_x11->xdpy, @@ -257,20 +256,14 @@ clutter_stage_glx_realize (ClutterActor *actor) { g_critical ("Unable to realize stage: %s", error->message); g_error_free (error); - goto fail; + return FALSE; } CLUTTER_NOTE (BACKEND, "Successfully realized stage"); } - /* we need to chain up to the X11 stage implementation in order to - * set the window state in case we set it before realizing the stage - */ - CLUTTER_ACTOR_CLASS (clutter_stage_glx_parent_class)->realize (actor); - return; - -fail: - CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED); + /* chain up to the StageX11 implementation */ + return clutter_stage_glx_parent_iface->realize (stage_window); } static void @@ -283,12 +276,8 @@ static void clutter_stage_glx_class_init (ClutterStageGLXClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); gobject_class->dispose = clutter_stage_glx_dispose; - - actor_class->realize = clutter_stage_glx_realize; - actor_class->unrealize = clutter_stage_glx_unrealize; } static void @@ -299,5 +288,10 @@ clutter_stage_glx_init (ClutterStageGLX *stage) static void clutter_stage_window_iface_init (ClutterStageWindowIface *iface) { + clutter_stage_glx_parent_iface = g_type_interface_peek_parent (iface); + + iface->realize = clutter_stage_glx_realize; + iface->unrealize = clutter_stage_glx_unrealize; + /* the rest is inherited from ClutterStageX11 */ } diff --git a/clutter/x11/clutter-event-x11.c b/clutter/x11/clutter-event-x11.c index 176fd2e72..b40c5b5a4 100644 --- a/clutter/x11/clutter-event-x11.c +++ b/clutter/x11/clutter-event-x11.c @@ -479,8 +479,9 @@ event_translate (ClutterBackend *backend, xevent->xconfigure.width, xevent->xconfigure.height); - stage_x11->xwin_width = xevent->xconfigure.width; - stage_x11->xwin_height = xevent->xconfigure.height; + clutter_actor_set_size (CLUTTER_ACTOR (stage), + xevent->xconfigure.width, + xevent->xconfigure.height); CLUTTER_UNSET_PRIVATE_FLAGS (stage_x11->wrapper, CLUTTER_STAGE_IN_RESIZE); @@ -489,8 +490,6 @@ event_translate (ClutterBackend *backend, * to set up the GL viewport with the new size */ clutter_stage_ensure_viewport (stage); - - clutter_actor_queue_relayout (CLUTTER_ACTOR (stage_x11->wrapper)); } res = FALSE; break; diff --git a/clutter/x11/clutter-stage-x11.c b/clutter/x11/clutter-stage-x11.c index 722998f66..02aec37f8 100644 --- a/clutter/x11/clutter-stage-x11.c +++ b/clutter/x11/clutter-stage-x11.c @@ -50,7 +50,7 @@ static void clutter_stage_window_iface_init (ClutterStageWindowIface *iface); G_DEFINE_TYPE_WITH_CODE (ClutterStageX11, clutter_stage_x11, - CLUTTER_TYPE_GROUP, + G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_STAGE_WINDOW, clutter_stage_window_iface_init)); @@ -95,24 +95,24 @@ clutter_stage_x11_fix_window_size (ClutterStageX11 *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) { + gint min_width, min_height; + ClutterGeometry min_size; XSizeHints *size_hints; - gfloat min_width, min_height; size_hints = XAllocSizeHints(); + _clutter_stage_window_get_geometry (CLUTTER_STAGE_WINDOW (stage_x11), + &min_size); + if (new_width < 0) - clutter_actor_get_preferred_width (CLUTTER_ACTOR (stage_x11), - -1, - &min_width, NULL); + min_width = min_size.width; else min_width = new_width; if (new_height < 0) - clutter_actor_get_preferred_height (CLUTTER_ACTOR (stage_x11), - min_width, - &min_height, NULL); + min_height = min_size.height; else min_height = new_height; @@ -122,8 +122,8 @@ clutter_stage_x11_fix_window_size (ClutterStageX11 *stage_x11, restrictions on the window size */ if (!stage_x11->fullscreen_on_map) { - size_hints->min_width = (int) min_width; - size_hints->min_height = (int) min_height; + size_hints->min_width = min_width; + size_hints->min_height = min_height; size_hints->flags = PMinSize; if (!resize) @@ -154,12 +154,10 @@ clutter_stage_x11_set_wm_protocols (ClutterStageX11 *stage_x11) } static void -clutter_stage_x11_get_preferred_width (ClutterActor *self, - gfloat for_height, - gfloat *min_width_p, - gfloat *natural_width_p) +clutter_stage_x11_get_geometry (ClutterStageWindow *stage_window, + ClutterGeometry *geometry) { - ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (self); + ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window); gboolean is_fullscreen, resize; is_fullscreen = FALSE; @@ -169,110 +167,56 @@ clutter_stage_x11_get_preferred_width (ClutterActor *self, if (is_fullscreen || stage_x11->fullscreen_on_map) { - int width; - - width = DisplayWidth (stage_x11->xdpy, stage_x11->xscreen); - - if (min_width_p) - *min_width_p = width; - - if (natural_width_p) - *natural_width_p = width; + geometry->width = DisplayWidth (stage_x11->xdpy, stage_x11->xscreen); + geometry->height = DisplayHeight (stage_x11->xdpy, stage_x11->xscreen); return; } resize = clutter_stage_get_user_resizable (stage_x11->wrapper); - if (min_width_p) + if (resize) { - if (resize) - *min_width_p = 1; /* FIXME need API to set this */ - else - *min_width_p = stage_x11->xwin_width; + /* FIXME need API to set this */ + geometry->width = 1; + geometry->height = 1; + } + else + { + geometry->width = stage_x11->xwin_width; + geometry->height = stage_x11->xwin_height; } - - if (natural_width_p) - *natural_width_p = stage_x11->xwin_width; } static void -clutter_stage_x11_get_preferred_height (ClutterActor *self, - gfloat for_width, - gfloat *min_height_p, - gfloat *natural_height_p) +clutter_stage_x11_resize (ClutterStageWindow *stage_window, + gint width, + gint height) { - ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (self); - gboolean is_fullscreen, resize; - - is_fullscreen = FALSE; - g_object_get (G_OBJECT (stage_x11->wrapper), - "fullscreen-set", &is_fullscreen, - NULL); - - if (is_fullscreen || stage_x11->fullscreen_on_map) - { - int height; - - height = DisplayHeight (stage_x11->xdpy, stage_x11->xscreen); - - if (min_height_p) - *min_height_p = height; - - if (natural_height_p) - *natural_height_p = height; - - return; - } + ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window); + gboolean resize; resize = clutter_stage_get_user_resizable (stage_x11->wrapper); - if (min_height_p) - { - if (resize) - *min_height_p = 1; /* FIXME need API to set this */ - else - *min_height_p = stage_x11->xwin_height; - } - - if (natural_height_p) - *natural_height_p = stage_x11->xwin_height; -} - -static void -clutter_stage_x11_allocate (ClutterActor *self, - const ClutterActorBox *box, - ClutterAllocationFlags flags) -{ - ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (self); - ClutterActorClass *parent_class; - gint new_width, new_height; - - new_width = ABS ((int) (box->x2 - box->x1)); - new_height = ABS ((int) (box->y2 - box->y1)); - - if (new_width == 0 || new_height == 0) + if (width == 0 || height == 0) { /* Should not happen, if this turns up we need to debug it and * determine the cleanest way to fix. */ g_warning ("X11 stage not allowed to have 0 width or height"); - new_width = 1; - new_height = 1; + width = 1; + height = 1; } - CLUTTER_NOTE (BACKEND, "New allocation received: (%d, %d)", - new_width, - new_height); + CLUTTER_NOTE (BACKEND, "New size received: (%d, %d)", width, height); - if (new_width != stage_x11->xwin_width || - new_height != stage_x11->xwin_height) + if (width != stage_x11->xwin_width || + height != stage_x11->xwin_height) { - stage_x11->xwin_width = new_width; - stage_x11->xwin_height = new_height; + stage_x11->xwin_width = width; + stage_x11->xwin_height = height; - if (stage_x11->xwin != None && - !stage_x11->is_foreign_xwin) + if (stage_x11->xwin != None && !stage_x11->is_foreign_xwin) { CLUTTER_NOTE (BACKEND, "%s: XResizeWindow[%x] (%d, %d)", G_STRLOC, @@ -289,18 +233,17 @@ clutter_stage_x11_allocate (ClutterActor *self, stage_x11->xwin_height); } - clutter_stage_x11_fix_window_size (stage_x11, new_width, new_height); + if (!resize) + clutter_stage_x11_fix_window_size (stage_x11, width, height); if (stage_x11->xpixmap != None) { /* Need to recreate to resize */ - _clutter_actor_rerealize (self, NULL, NULL); + _clutter_actor_rerealize (CLUTTER_ACTOR (stage_x11->wrapper), + NULL, + NULL); } } - - /* chain up to fill in actor->priv->allocation */ - parent_class = CLUTTER_ACTOR_CLASS (clutter_stage_x11_parent_class); - parent_class->allocate (self, box, flags); } static inline void @@ -395,14 +338,16 @@ set_cursor_visible (ClutterStageX11 *stage_x11) } } -static void -clutter_stage_x11_realize (ClutterActor *actor) +static gboolean +clutter_stage_x11_realize (ClutterStageWindow *stage_window) { - ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (actor); + ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window); set_wm_pid (stage_x11); set_wm_title (stage_x11); set_cursor_visible (stage_x11); + + return TRUE; } static void @@ -599,14 +544,8 @@ clutter_stage_x11_show (ClutterStageWindow *stage_window, g_assert (STAGE_X11_IS_MAPPED (stage_x11)); - clutter_actor_map (CLUTTER_ACTOR (stage_x11)); clutter_actor_map (CLUTTER_ACTOR (stage_x11->wrapper)); - /* we force a redraw here, so that by the time we have - * been mapped, the window has contents - */ - _clutter_do_redraw (CLUTTER_STAGE (stage_x11->wrapper)); - XMapWindow (stage_x11->xdpy, stage_x11->xwin); } } @@ -623,7 +562,6 @@ clutter_stage_x11_hide (ClutterStageWindow *stage_window) g_assert (!STAGE_X11_IS_MAPPED (stage_x11)); - clutter_actor_unmap (CLUTTER_ACTOR (stage_x11)); clutter_actor_unmap (CLUTTER_ACTOR (stage_x11->wrapper)); XWithdrawWindow (stage_x11->xdpy, @@ -658,16 +596,9 @@ static void clutter_stage_x11_class_init (ClutterStageX11Class *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); gobject_class->finalize = clutter_stage_x11_finalize; gobject_class->dispose = clutter_stage_x11_dispose; - - actor_class->realize = clutter_stage_x11_realize; - - actor_class->get_preferred_width = clutter_stage_x11_get_preferred_width; - actor_class->get_preferred_height = clutter_stage_x11_get_preferred_height; - actor_class->allocate = clutter_stage_x11_allocate; } static void @@ -705,6 +636,9 @@ clutter_stage_window_iface_init (ClutterStageWindowIface *iface) iface->set_user_resizable = clutter_stage_x11_set_user_resizable; iface->show = clutter_stage_x11_show; iface->hide = clutter_stage_x11_hide; + iface->resize = clutter_stage_x11_resize; + iface->get_geometry = clutter_stage_x11_get_geometry; + iface->realize = clutter_stage_x11_realize; } /** diff --git a/tests/interactive/test-actors.c b/tests/interactive/test-actors.c index ef2c56fd9..aba8be43d 100644 --- a/tests/interactive/test-actors.c +++ b/tests/interactive/test-actors.c @@ -159,6 +159,7 @@ test_actors_main (int argc, char *argv[]) clutter_stage_set_title (CLUTTER_STAGE (stage), "Clone Test"); clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color); + clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE); oh = g_new (SuperOH, 1); oh->stage = stage;