subclassing code.
* clutter/win32/clutter-stage-win32.h:
* clutter/win32/clutter-stage-win32.c: Now inherits from
ClutterGroup and implements ClutterStageWindow instead of
inheriting directly from ClutterStage.
* clutter/win32/clutter-event-win32.c (message_translate): Now
takes an extra parameter to return whether DefWindowProc should be
called. This is needed to prevent the default WM_CLOSE handler
from destroying the window.
* clutter/win32/clutter-backend-win32.c
(clutter_backend_win32_dispose): Destroy all of the stages using
g_slist_foreach as per bug #871. Now also destroys the GL context.
(clutter_backend_win32_get_features): Added assertions to ensure
there is a valid GL context.
(clutter_backend_win32_ensure_context): Accepts NULL stage. Gets
implementation pointer from the stage.
+2008-04-13 Neil Roberts <neil@o-hand.com>
+
+ Upgraded the Win32 backend to work with the multi-stage
+ subclassing code.
+
+ * clutter/win32/clutter-stage-win32.h:
+ * clutter/win32/clutter-stage-win32.c: Now inherits from
+ ClutterGroup and implements ClutterStageWindow instead of
+ inheriting directly from ClutterStage.
+
+ * clutter/win32/clutter-event-win32.c (message_translate): Now
+ takes an extra parameter to return whether DefWindowProc should be
+ called. This is needed to prevent the default WM_CLOSE handler
+ from destroying the window.
+
+ * clutter/win32/clutter-backend-win32.c
+ (clutter_backend_win32_dispose): Destroy all of the stages using
+ g_slist_foreach as per bug #871. Now also destroys the GL context.
+ (clutter_backend_win32_get_features): Added assertions to ensure
+ there is a valid GL context.
+ (clutter_backend_win32_ensure_context): Accepts NULL stage. Gets
+ implementation pointer from the stage.
+
2008-04-11 Emmanuele Bassi <ebassi@openedhand.com>
* clutter/clutter-container.c:
#include "../clutter-main.h"
#include "../clutter-debug.h"
#include "../clutter-private.h"
+#include "../clutter-version.h"
#include "cogl.h"
ClutterBackendWin32 *backend_win32 = CLUTTER_BACKEND_WIN32 (gobject);
ClutterMainContext *context;
ClutterStageManager *stage_manager;
- GSList *l;
CLUTTER_NOTE (BACKEND, "Disposing the of stages");
context = clutter_context_get_default ();
stage_manager = context->stage_manager;
- for (l = stage_manager->stages; l; l = l->next)
- {
- ClutterActor *stage = CLUTTER_ACTOR (l->data);
- clutter_actor_destroy (stage);
- }
+ /* Destroy all of the stages. g_slist_foreach is used because the
+ finalizer for the stages will remove the stage from the
+ stage_manager's list and g_slist_foreach has some basic
+ protection against this */
+ g_slist_foreach (stage_manager->stages, (GFunc) clutter_actor_destroy, NULL);
CLUTTER_NOTE (BACKEND, "Removing the event source");
_clutter_backend_win32_events_uninit (CLUTTER_BACKEND (backend_win32));
+ if (backend_win32->gl_context)
+ {
+ wglDeleteContext (backend_win32->gl_context);
+ backend_win32->gl_context = NULL;
+ }
+
G_OBJECT_CLASS (clutter_backend_win32_parent_class)->dispose (gobject);
}
ClutterFeatureFlags
clutter_backend_win32_get_features (ClutterBackend *backend)
{
- ClutterFeatureFlags flags;
- const gchar *extensions;
- SwapIntervalProc swap_interval;
+ ClutterFeatureFlags flags;
+ const gchar *extensions;
+ SwapIntervalProc swap_interval;
+ ClutterBackendWin32 *backend_win32;
/* FIXME: we really need to check if gl context is set */
extensions = glGetString (GL_EXTENSIONS);
+ /* this will make sure that the GL context exists and is bound to a
+ drawable */
+ backend_win32 = CLUTTER_BACKEND_WIN32 (backend);
+ g_return_val_if_fail (backend_win32->gl_context != NULL, 0);
+ g_return_val_if_fail (wglGetCurrentDC () != NULL, 0);
+
CLUTTER_NOTE (BACKEND, "Checking features\n"
"GL_VENDOR: %s\n"
"GL_RENDERER: %s\n"
clutter_backend_win32_ensure_context (ClutterBackend *backend,
ClutterStage *stage)
{
- ClutterBackendWin32 *backend_win32;
- ClutterStageWin32 *stage_win32;
-
- stage_win32 = CLUTTER_STAGE_WIN32 (stage);
- backend_win32 = CLUTTER_BACKEND_WIN32 (backend);
-
- CLUTTER_NOTE (MULTISTAGE, "setting context for stage:%p", stage );
+ if (stage == NULL)
+ {
+ CLUTTER_NOTE (MULTISTAGE, "Clearing all context");
- wglMakeCurrent (stage_win32->client_dc,
- backend_win32->gl_context);
+ wglMakeCurrent (NULL, NULL);
+ }
+ else
+ {
+ ClutterBackendWin32 *backend_win32;
+ ClutterStageWin32 *stage_win32;
+ ClutterStageWindow *impl;
+
+ impl = _clutter_stage_get_window (stage);
+ g_return_if_fail (impl != NULL);
+
+ CLUTTER_NOTE (MULTISTAGE, "Setting context for stage of type %s [%p]",
+ g_type_name (G_OBJECT_TYPE (impl)),
+ impl);
+
+ backend_win32 = CLUTTER_BACKEND_WIN32 (backend);
+ stage_win32 = CLUTTER_STAGE_WIN32 (impl);
+
+ /* no GL context to set */
+ if (backend_win32->gl_context == NULL)
+ return;
+
+ /* we might get here inside the final dispose cycle, so we
+ * need to handle this gracefully
+ */
+ if (stage_win32->client_dc == NULL)
+ {
+ CLUTTER_NOTE (MULTISTAGE,
+ "Received a stale stage, clearing all context");
+
+ wglMakeCurrent (NULL, NULL);
+ }
+ else
+ {
+ CLUTTER_NOTE (BACKEND,
+ "MakeCurrent window %p, context %p",
+ stage_win32->hwnd,
+ backend_win32->gl_context);
+ wglMakeCurrent (stage_win32->client_dc,
+ backend_win32->gl_context);
+ }
+ }
}
static void
clutter_backend_win32_redraw (ClutterBackend *backend,
ClutterStage *stage)
{
- ClutterStageWin32 *stage_win32 = CLUTTER_STAGE_WIN32 (stage);
+ ClutterStageWin32 *stage_win32;
+ ClutterStageWindow *impl;
+
+ impl = _clutter_stage_get_window (stage);
+ if (impl == NULL)
+ return;
+
+ g_return_if_fail (CLUTTER_IS_STAGE_WIN32 (impl));
+ stage_win32 = CLUTTER_STAGE_WIN32 (impl);
+
+ /* this will cause the stage implementation to be painted */
clutter_actor_paint (CLUTTER_ACTOR (stage));
if (stage_win32->client_dc)
static ClutterActor *
clutter_backend_win32_create_stage (ClutterBackend *backend,
+ ClutterStage *wrapper,
GError **error)
{
ClutterBackendWin32 *backend_win32 = CLUTTER_BACKEND_WIN32 (backend);
ClutterStageWin32 *stage_win32;
ClutterActor *stage;
- stage = g_object_new (CLUTTER_TYPE_STAGE_WIN32, NULL);
+ CLUTTER_NOTE (BACKEND, "Creating stage of type `%s'",
+ g_type_name (CLUTTER_STAGE_TYPE));
+
+ stage = g_object_new (CLUTTER_STAGE_TYPE, NULL);
/* copy backend data into the stage */
stage_win32 = CLUTTER_STAGE_WIN32 (stage);
stage_win32->backend = backend_win32;
+ stage_win32->wrapper = wrapper;
+
+ /* set the pointer back into the wrapper */
+ _clutter_stage_set_window (wrapper, CLUTTER_STAGE_WINDOW (stage));
/* needed ? */
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);
if (!CLUTTER_ACTOR_IS_REALIZED (stage))
static gboolean
message_translate (ClutterBackend *backend,
ClutterEvent *event,
- const MSG *msg)
+ const MSG *msg,
+ gboolean *call_def_window_proc)
{
ClutterBackendWin32 *backend_win32;
ClutterStageWin32 *stage_win32;
ClutterStage *stage;
+ ClutterStageWindow *impl;
gboolean res;
backend_win32 = CLUTTER_BACKEND_WIN32 (backend);
if (stage == NULL)
return FALSE;
- stage_win32 = CLUTTER_STAGE_WIN32 (stage);
+ impl = _clutter_stage_get_window (stage);
+ stage_win32 = CLUTTER_STAGE_WIN32 (impl);
event->any.stage = stage;
event->type = CLUTTER_DESTROY_NOTIFY;
break;
+ case WM_CLOSE:
+ CLUTTER_NOTE (EVENT, "WM_CLOSE");
+ event->type = CLUTTER_DELETE;
+ /* The default window proc will destroy the window so we want to
+ prevent this to allow applications to optionally destroy the
+ window themselves */
+ if (call_def_window_proc)
+ *call_def_window_proc = FALSE;
+ break;
+
case WM_LBUTTONDOWN:
make_button_event (msg, event, 1, 1, FALSE);
break;
}
break;
+ case WM_GETMINMAXINFO:
+ {
+ MINMAXINFO *min_max_info = (MINMAXINFO *) msg->lParam;
+ _clutter_stage_win32_get_min_max_info (stage_win32, min_max_info);
+ if (call_def_window_proc)
+ *call_def_window_proc = FALSE;
+ }
+ break;
+
default:
/* ignore every other message */
res = FALSE;
{
ClutterStageWin32 *stage_win32
= (ClutterStageWin32 *) GetWindowLongPtrW (hwnd, 0);
+ gboolean call_def_window_proc = TRUE;
/* Ignore any messages before SetWindowLongPtr has been called to
set the stage */
msg.pt.x = (SHORT) LOWORD (message_pos);
msg.pt.y = (SHORT) HIWORD (message_pos);
- /* Some messages are handled here specially outside of
- message_translate so that DefWindowProc can be overridden */
- if (umsg == WM_GETMINMAXINFO)
- {
- MINMAXINFO *min_max_info = (MINMAXINFO *) lparam;
- _clutter_stage_win32_get_min_max_info (stage_win32, min_max_info);
- return 0;
- }
- else
- {
- event = clutter_event_new (CLUTTER_NOTHING);
+ event = clutter_event_new (CLUTTER_NOTHING);
- if (message_translate (CLUTTER_BACKEND (backend_win32), event, &msg))
- /* push directly here to avoid copy of queue_put */
- g_queue_push_head (clutter_context->events_queue, event);
- else
- clutter_event_free (event);
- }
+ if (message_translate (CLUTTER_BACKEND (backend_win32), event,
+ &msg, &call_def_window_proc))
+ /* push directly here to avoid copy of queue_put */
+ g_queue_push_head (clutter_context->events_queue, event);
+ else
+ clutter_event_free (event);
}
- return DefWindowProcW (hwnd, umsg, wparam, lparam);
+ if (call_def_window_proc)
+ return DefWindowProcW (hwnd, umsg, wparam, lparam);
+ else
+ return 0;
}
#include "clutter-stage-win32.h"
#include "clutter-win32.h"
+#include "../clutter-stage-window.h"
#include "../clutter-main.h"
#include "../clutter-feature.h"
#include "../clutter-color.h"
#include "../clutter-private.h"
#include "../clutter-debug.h"
#include "../clutter-units.h"
+#include "../clutter-shader.h"
#include "../clutter-stage.h"
#include "cogl.h"
#include <windows.h>
-G_DEFINE_TYPE (ClutterStageWin32, clutter_stage_win32, CLUTTER_TYPE_STAGE);
+static void clutter_stage_window_iface_init (ClutterStageWindowIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (ClutterStageWin32,
+ clutter_stage_win32,
+ CLUTTER_TYPE_GROUP,
+ G_IMPLEMENT_INTERFACE
+ (CLUTTER_TYPE_STAGE_WINDOW,
+ clutter_stage_window_iface_init));
static void
clutter_stage_win32_show (ClutterActor *actor)
int *xpos_out, int *ypos_out)
{
gboolean resizable
- = clutter_stage_get_user_resizable (CLUTTER_STAGE (stage_win32));
+ = clutter_stage_get_user_resizable (stage_win32->wrapper);
/* The window position passed to CreateWindow includes the window
decorations */
*xpos_out = xpos_in - GetSystemMetrics (resizable ? SM_CXSIZEFRAME
int *width_out, int *height_out)
{
gboolean resizable
- = clutter_stage_get_user_resizable (CLUTTER_STAGE (stage_win32));
+ = clutter_stage_get_user_resizable (stage_win32->wrapper);
/* The window size passed to CreateWindow includes the window
decorations */
*width_out = width_in + GetSystemMetrics (resizable ? SM_CXSIZEFRAME
{
/* If the window isn't resizable then set the max and min size to
the current size */
- if (!clutter_stage_get_user_resizable (CLUTTER_STAGE (stage_win32)))
+ if (!clutter_stage_get_user_resizable (CLUTTER_STAGE (stage_win32->wrapper)))
{
int full_width, full_height;
get_full_window_size (stage_win32,
change_flags);
}
- CLUTTER_SET_PRIVATE_FLAGS (self, CLUTTER_ACTOR_SYNC_MATRICES);
+ CLUTTER_SET_PRIVATE_FLAGS (stage_win32->wrapper,
+ CLUTTER_ACTOR_SYNC_MATRICES);
}
CLUTTER_ACTOR_CLASS (clutter_stage_win32_parent_class)
}
static void
-clutter_stage_win32_set_title (ClutterStage *stage,
- const gchar *title)
+clutter_stage_win32_set_title (ClutterStageWindow *stage_window,
+ const gchar *title)
{
- ClutterStageWin32 *stage_win32 = CLUTTER_STAGE_WIN32 (stage);
+ ClutterStageWin32 *stage_win32 = CLUTTER_STAGE_WIN32 (stage_window);
wchar_t *wtitle;
/* Empty window titles not allowed, so set it to just a period. */
static LONG
get_window_style (ClutterStageWin32 *stage_win32)
{
+ ClutterStage *wrapper = stage_win32->wrapper;
+
/* Fullscreen mode shouldn't have any borders */
if ((stage_win32->state & CLUTTER_STAGE_STATE_FULLSCREEN))
return WS_POPUP;
/* Otherwise it's an overlapped window but if it isn't resizable
then it shouldn't have a thick frame */
- else if (clutter_stage_get_user_resizable (CLUTTER_STAGE (stage_win32)))
+ else if (clutter_stage_get_user_resizable (wrapper))
return WS_OVERLAPPEDWINDOW;
else
return WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME;
}
static void
-clutter_stage_win32_set_user_resize (ClutterStage *stage,
- gboolean value)
+clutter_stage_win32_set_user_resize (ClutterStageWindow *stage_window,
+ gboolean value)
{
- HWND hwnd = CLUTTER_STAGE_WIN32 (stage)->hwnd;
+ HWND hwnd = CLUTTER_STAGE_WIN32 (stage_window)->hwnd;
LONG old_style = GetWindowLongW (hwnd, GWL_STYLE);
/* Update the window style but preserve the visibility */
SetWindowLongW (hwnd, GWL_STYLE,
- get_window_style (CLUTTER_STAGE_WIN32 (stage))
+ get_window_style (CLUTTER_STAGE_WIN32 (stage_window))
| (old_style & WS_VISIBLE));
}
+static ClutterActor *
+clutter_stage_win32_get_wrapper (ClutterStageWindow *stage_window)
+{
+ return CLUTTER_ACTOR (CLUTTER_STAGE_WIN32 (stage_window)->wrapper);
+}
+
static void
-clutter_stage_win32_set_fullscreen (ClutterStage *stage,
- gboolean value)
+clutter_stage_win32_set_fullscreen (ClutterStageWindow *stage_window,
+ gboolean value)
{
- ClutterStageWin32 *stage_win32 = CLUTTER_STAGE_WIN32 (stage);
- HWND hwnd = CLUTTER_STAGE_WIN32 (stage)->hwnd;
+ ClutterStageWin32 *stage_win32 = CLUTTER_STAGE_WIN32 (stage_window);
+ HWND hwnd = CLUTTER_STAGE_WIN32 (stage_window)->hwnd;
LONG old_style = GetWindowLongW (hwnd, GWL_STYLE);
ClutterStageStateEvent event;
SWP_NOZORDER);
}
- CLUTTER_SET_PRIVATE_FLAGS (stage, CLUTTER_ACTOR_SYNC_MATRICES);
+ CLUTTER_SET_PRIVATE_FLAGS (stage_win32->wrapper,
+ CLUTTER_ACTOR_SYNC_MATRICES);
}
/* Report the state change */
memset (&event, 0, sizeof (event));
event.type = CLUTTER_STAGE_STATE;
- event.stage = CLUTTER_STAGE (stage_win32);
+ event.stage = CLUTTER_STAGE (stage_win32->wrapper);
event.new_state = stage_win32->state;
event.changed_mask = CLUTTER_STAGE_STATE_FULLSCREEN;
clutter_event_put ((ClutterEvent *) &event);
if (window_class == 0)
{
g_critical ("Unable to register window class");
+ CLUTTER_ACTOR_UNSET_FLAGS (stage_win32->wrapper,
+ CLUTTER_ACTOR_REALIZED);
CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED);
return;
}
if (stage_win32->hwnd == NULL)
{
g_critical ("Unable to create stage window");
+ CLUTTER_ACTOR_UNSET_FLAGS (stage_win32->wrapper,
+ CLUTTER_ACTOR_REALIZED);
CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED);
return;
}
|| !SetPixelFormat (stage_win32->client_dc, pf, &pfd))
{
g_critical ("Unable to find suitable GL pixel format");
+ CLUTTER_ACTOR_UNSET_FLAGS (stage_win32->wrapper,
+ CLUTTER_ACTOR_REALIZED);
CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED);
return;
}
if (backend_win32->gl_context == NULL)
{
g_critical ("Unable to create suitable GL context");
+ CLUTTER_ACTOR_UNSET_FLAGS (stage_win32->wrapper,
+ CLUTTER_ACTOR_REALIZED);
CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED);
return;
}
}
- CLUTTER_NOTE (GL, "wglMakeCurrent");
-
- clutter_stage_ensure_current (CLUTTER_STAGE (stage_win32));
+ /* below will call wglMakeCurrent */
+ CLUTTER_ACTOR_SET_FLAGS (stage_win32->wrapper, CLUTTER_ACTOR_REALIZED);
+ CLUTTER_ACTOR_SET_FLAGS (stage_win32, CLUTTER_ACTOR_REALIZED);
+ clutter_stage_ensure_current (stage_win32->wrapper);
if (!clutter_stage_win32_check_gl_version ())
{
g_critical ("OpenGL version number is too low");
+ CLUTTER_ACTOR_UNSET_FLAGS (stage_win32->wrapper,
+ CLUTTER_ACTOR_REALIZED);
CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED);
return;
}
/* Make sure the viewport gets set up correctly */
- CLUTTER_SET_PRIVATE_FLAGS (actor, CLUTTER_ACTOR_SYNC_MATRICES);
+ CLUTTER_SET_PRIVATE_FLAGS (stage_win32->wrapper,
+ CLUTTER_ACTOR_SYNC_MATRICES);
}
static void
{
ClutterStageWin32 *stage_win32 = CLUTTER_STAGE_WIN32 (actor);
- wglMakeCurrent (NULL, NULL);
+ CLUTTER_NOTE (BACKEND, "Unrealizing stage");
+
+ /* Chain up so all children get unrealized, needed to move texture
+ * data across contexts
+ */
+ CLUTTER_ACTOR_CLASS (clutter_stage_win32_parent_class)->unrealize (actor);
+
+ /* Unrealize all shaders, since the GL context is going away */
+ _clutter_shader_release_all ();
+
+ /* As unrealised the context will now get cleared */
+ clutter_stage_ensure_current (stage_win32->wrapper);
if (stage_win32->client_dc)
{
if (stage_win32->hwnd)
{
+ /* Drop the pointer to this stage in the window so that any
+ further messages won't be processed. The stage might be being
+ destroyed so otherwise the messages would be handled with an
+ invalid stage instance */
+ SetWindowLongPtrW (stage_win32->hwnd, 0, (LONG_PTR) 0);
DestroyWindow (stage_win32->hwnd);
stage_win32->hwnd = NULL;
}
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
- ClutterStageClass *stage_class = CLUTTER_STAGE_CLASS (klass);
gobject_class->dispose = clutter_stage_win32_dispose;
actor_class->query_coords = clutter_stage_win32_query_coords;
actor_class->realize = clutter_stage_win32_realize;
actor_class->unrealize = clutter_stage_win32_unrealize;
-
- stage_class->set_title = clutter_stage_win32_set_title;
- stage_class->set_user_resize = clutter_stage_win32_set_user_resize;
- stage_class->set_fullscreen = clutter_stage_win32_set_fullscreen;
}
static void
stage->win_height = 480;
stage->backend = NULL;
stage->scroll_pos = 0;
+
+ stage->wrapper = NULL;
+
+ CLUTTER_SET_PRIVATE_FLAGS (stage, CLUTTER_ACTOR_IS_TOPLEVEL);
+}
+
+static void
+clutter_stage_window_iface_init (ClutterStageWindowIface *iface)
+{
+ iface->get_wrapper = clutter_stage_win32_get_wrapper;
+ iface->set_title = clutter_stage_win32_set_title;
+ iface->set_fullscreen = clutter_stage_win32_set_fullscreen;
+ iface->set_user_resizable = clutter_stage_win32_set_user_resize;
}
/**
HWND
clutter_win32_get_stage_window (ClutterStage *stage)
{
- g_return_val_if_fail (CLUTTER_IS_STAGE_WIN32 (stage), NULL);
+ ClutterStageWindow *impl;
+
+ g_return_val_if_fail (CLUTTER_IS_STAGE (stage), NULL);
+
+ impl = _clutter_stage_get_window (stage);
+
+ g_return_val_if_fail (CLUTTER_IS_STAGE_WIN32 (impl), NULL);
- return CLUTTER_STAGE_WIN32 (stage)->hwnd;
+ return CLUTTER_STAGE_WIN32 (impl)->hwnd;
}
/**
== clutter_stage_win32_get_window_class ())
/* If it is there should be a pointer to the stage in the window
extra data */
- return (ClutterStage *) GetWindowLongPtrW (hwnd, 0);
+ return CLUTTER_STAGE_WIN32 (GetWindowLongPtrW (hwnd, 0))->wrapper;
else
return NULL;
}
clutter_stage_win32_map (ClutterStageWin32 *stage_win32)
{
CLUTTER_ACTOR_SET_FLAGS (stage_win32, CLUTTER_ACTOR_MAPPED);
+ CLUTTER_ACTOR_SET_FLAGS (stage_win32->wrapper, CLUTTER_ACTOR_MAPPED);
- clutter_actor_queue_redraw (CLUTTER_ACTOR (stage_win32));
+ clutter_actor_queue_redraw (CLUTTER_ACTOR (stage_win32->wrapper));
}
void
clutter_stage_win32_unmap (ClutterStageWin32 *stage_win32)
{
CLUTTER_ACTOR_UNSET_FLAGS (stage_win32, CLUTTER_ACTOR_MAPPED);
+ CLUTTER_ACTOR_UNSET_FLAGS (stage_win32->wrapper, CLUTTER_ACTOR_MAPPED);
}
#ifndef __CLUTTER_STAGE_WIN32_H__
#define __CLUTTER_STAGE_WIN32_H__
-#include <glib-object.h>
+#include <clutter/clutter-group.h>
#include <clutter/clutter-stage.h>
#include <windows.h>
struct _ClutterStageWin32
{
- ClutterStage parent_instance;
+ ClutterGroup parent_instance;
HWND hwnd;
HDC client_dc;
ClutterBackendWin32 *backend;
ClutterStageState state;
+
+ ClutterStage *wrapper;
};
struct _ClutterStageWin32Class
{
- ClutterStageClass parent_class;
+ ClutterGroupClass parent_class;
};
GType clutter_stage_win32_get_type (void) G_GNUC_CONST;