mirror of
https://github.com/brl/mutter.git
synced 2024-11-30 03:50:47 -05:00
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.
This commit is contained in:
parent
bf48bd1f55
commit
0b8a500fca
23
ChangeLog
23
ChangeLog
@ -1,3 +1,26 @@
|
|||||||
|
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>
|
2008-04-11 Emmanuele Bassi <ebassi@openedhand.com>
|
||||||
|
|
||||||
* clutter/clutter-container.c:
|
* clutter/clutter-container.c:
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include "../clutter-main.h"
|
#include "../clutter-main.h"
|
||||||
#include "../clutter-debug.h"
|
#include "../clutter-debug.h"
|
||||||
#include "../clutter-private.h"
|
#include "../clutter-private.h"
|
||||||
|
#include "../clutter-version.h"
|
||||||
|
|
||||||
#include "cogl.h"
|
#include "cogl.h"
|
||||||
|
|
||||||
@ -100,22 +101,27 @@ clutter_backend_win32_dispose (GObject *gobject)
|
|||||||
ClutterBackendWin32 *backend_win32 = CLUTTER_BACKEND_WIN32 (gobject);
|
ClutterBackendWin32 *backend_win32 = CLUTTER_BACKEND_WIN32 (gobject);
|
||||||
ClutterMainContext *context;
|
ClutterMainContext *context;
|
||||||
ClutterStageManager *stage_manager;
|
ClutterStageManager *stage_manager;
|
||||||
GSList *l;
|
|
||||||
|
|
||||||
CLUTTER_NOTE (BACKEND, "Disposing the of stages");
|
CLUTTER_NOTE (BACKEND, "Disposing the of stages");
|
||||||
|
|
||||||
context = clutter_context_get_default ();
|
context = clutter_context_get_default ();
|
||||||
stage_manager = context->stage_manager;
|
stage_manager = context->stage_manager;
|
||||||
|
|
||||||
for (l = stage_manager->stages; l; l = l->next)
|
/* Destroy all of the stages. g_slist_foreach is used because the
|
||||||
{
|
finalizer for the stages will remove the stage from the
|
||||||
ClutterActor *stage = CLUTTER_ACTOR (l->data);
|
stage_manager's list and g_slist_foreach has some basic
|
||||||
clutter_actor_destroy (stage);
|
protection against this */
|
||||||
}
|
g_slist_foreach (stage_manager->stages, (GFunc) clutter_actor_destroy, NULL);
|
||||||
|
|
||||||
CLUTTER_NOTE (BACKEND, "Removing the event source");
|
CLUTTER_NOTE (BACKEND, "Removing the event source");
|
||||||
_clutter_backend_win32_events_uninit (CLUTTER_BACKEND (backend_win32));
|
_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);
|
G_OBJECT_CLASS (clutter_backend_win32_parent_class)->dispose (gobject);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,11 +161,18 @@ clutter_backend_win32_get_features (ClutterBackend *backend)
|
|||||||
ClutterFeatureFlags flags;
|
ClutterFeatureFlags flags;
|
||||||
const gchar *extensions;
|
const gchar *extensions;
|
||||||
SwapIntervalProc swap_interval;
|
SwapIntervalProc swap_interval;
|
||||||
|
ClutterBackendWin32 *backend_win32;
|
||||||
|
|
||||||
/* FIXME: we really need to check if gl context is set */
|
/* FIXME: we really need to check if gl context is set */
|
||||||
|
|
||||||
extensions = glGetString (GL_EXTENSIONS);
|
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"
|
CLUTTER_NOTE (BACKEND, "Checking features\n"
|
||||||
"GL_VENDOR: %s\n"
|
"GL_VENDOR: %s\n"
|
||||||
"GL_RENDERER: %s\n"
|
"GL_RENDERER: %s\n"
|
||||||
@ -217,24 +230,70 @@ static void
|
|||||||
clutter_backend_win32_ensure_context (ClutterBackend *backend,
|
clutter_backend_win32_ensure_context (ClutterBackend *backend,
|
||||||
ClutterStage *stage)
|
ClutterStage *stage)
|
||||||
{
|
{
|
||||||
|
if (stage == NULL)
|
||||||
|
{
|
||||||
|
CLUTTER_NOTE (MULTISTAGE, "Clearing all context");
|
||||||
|
|
||||||
|
wglMakeCurrent (NULL, NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
ClutterBackendWin32 *backend_win32;
|
ClutterBackendWin32 *backend_win32;
|
||||||
ClutterStageWin32 *stage_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);
|
||||||
|
|
||||||
stage_win32 = CLUTTER_STAGE_WIN32 (stage);
|
|
||||||
backend_win32 = CLUTTER_BACKEND_WIN32 (backend);
|
backend_win32 = CLUTTER_BACKEND_WIN32 (backend);
|
||||||
|
stage_win32 = CLUTTER_STAGE_WIN32 (impl);
|
||||||
|
|
||||||
CLUTTER_NOTE (MULTISTAGE, "setting context for stage:%p", stage );
|
/* 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,
|
wglMakeCurrent (stage_win32->client_dc,
|
||||||
backend_win32->gl_context);
|
backend_win32->gl_context);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_backend_win32_redraw (ClutterBackend *backend,
|
clutter_backend_win32_redraw (ClutterBackend *backend,
|
||||||
ClutterStage *stage)
|
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));
|
clutter_actor_paint (CLUTTER_ACTOR (stage));
|
||||||
|
|
||||||
if (stage_win32->client_dc)
|
if (stage_win32->client_dc)
|
||||||
@ -243,21 +302,33 @@ clutter_backend_win32_redraw (ClutterBackend *backend,
|
|||||||
|
|
||||||
static ClutterActor *
|
static ClutterActor *
|
||||||
clutter_backend_win32_create_stage (ClutterBackend *backend,
|
clutter_backend_win32_create_stage (ClutterBackend *backend,
|
||||||
|
ClutterStage *wrapper,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
ClutterBackendWin32 *backend_win32 = CLUTTER_BACKEND_WIN32 (backend);
|
ClutterBackendWin32 *backend_win32 = CLUTTER_BACKEND_WIN32 (backend);
|
||||||
ClutterStageWin32 *stage_win32;
|
ClutterStageWin32 *stage_win32;
|
||||||
ClutterActor *stage;
|
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 */
|
/* copy backend data into the stage */
|
||||||
stage_win32 = CLUTTER_STAGE_WIN32 (stage);
|
stage_win32 = CLUTTER_STAGE_WIN32 (stage);
|
||||||
stage_win32->backend = backend_win32;
|
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 ? */
|
/* 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))
|
||||||
|
@ -301,11 +301,13 @@ get_key_modifier_state (const BYTE *key_states)
|
|||||||
static gboolean
|
static gboolean
|
||||||
message_translate (ClutterBackend *backend,
|
message_translate (ClutterBackend *backend,
|
||||||
ClutterEvent *event,
|
ClutterEvent *event,
|
||||||
const MSG *msg)
|
const MSG *msg,
|
||||||
|
gboolean *call_def_window_proc)
|
||||||
{
|
{
|
||||||
ClutterBackendWin32 *backend_win32;
|
ClutterBackendWin32 *backend_win32;
|
||||||
ClutterStageWin32 *stage_win32;
|
ClutterStageWin32 *stage_win32;
|
||||||
ClutterStage *stage;
|
ClutterStage *stage;
|
||||||
|
ClutterStageWindow *impl;
|
||||||
gboolean res;
|
gboolean res;
|
||||||
|
|
||||||
backend_win32 = CLUTTER_BACKEND_WIN32 (backend);
|
backend_win32 = CLUTTER_BACKEND_WIN32 (backend);
|
||||||
@ -315,7 +317,8 @@ message_translate (ClutterBackend *backend,
|
|||||||
|
|
||||||
if (stage == NULL)
|
if (stage == NULL)
|
||||||
return FALSE;
|
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->any.stage = stage;
|
||||||
|
|
||||||
@ -404,6 +407,16 @@ message_translate (ClutterBackend *backend,
|
|||||||
event->type = CLUTTER_DESTROY_NOTIFY;
|
event->type = CLUTTER_DESTROY_NOTIFY;
|
||||||
break;
|
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:
|
case WM_LBUTTONDOWN:
|
||||||
make_button_event (msg, event, 1, 1, FALSE);
|
make_button_event (msg, event, 1, 1, FALSE);
|
||||||
break;
|
break;
|
||||||
@ -552,6 +565,15 @@ message_translate (ClutterBackend *backend,
|
|||||||
}
|
}
|
||||||
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:
|
default:
|
||||||
/* ignore every other message */
|
/* ignore every other message */
|
||||||
res = FALSE;
|
res = FALSE;
|
||||||
@ -567,6 +589,7 @@ _clutter_stage_win32_window_proc (HWND hwnd, UINT umsg,
|
|||||||
{
|
{
|
||||||
ClutterStageWin32 *stage_win32
|
ClutterStageWin32 *stage_win32
|
||||||
= (ClutterStageWin32 *) GetWindowLongPtrW (hwnd, 0);
|
= (ClutterStageWin32 *) GetWindowLongPtrW (hwnd, 0);
|
||||||
|
gboolean call_def_window_proc = TRUE;
|
||||||
|
|
||||||
/* Ignore any messages before SetWindowLongPtr has been called to
|
/* Ignore any messages before SetWindowLongPtr has been called to
|
||||||
set the stage */
|
set the stage */
|
||||||
@ -590,25 +613,18 @@ _clutter_stage_win32_window_proc (HWND hwnd, UINT umsg,
|
|||||||
msg.pt.x = (SHORT) LOWORD (message_pos);
|
msg.pt.x = (SHORT) LOWORD (message_pos);
|
||||||
msg.pt.y = (SHORT) HIWORD (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))
|
if (message_translate (CLUTTER_BACKEND (backend_win32), event,
|
||||||
|
&msg, &call_def_window_proc))
|
||||||
/* push directly here to avoid copy of queue_put */
|
/* push directly here to avoid copy of queue_put */
|
||||||
g_queue_push_head (clutter_context->events_queue, event);
|
g_queue_push_head (clutter_context->events_queue, event);
|
||||||
else
|
else
|
||||||
clutter_event_free (event);
|
clutter_event_free (event);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
if (call_def_window_proc)
|
||||||
return DefWindowProcW (hwnd, umsg, wparam, lparam);
|
return DefWindowProcW (hwnd, umsg, wparam, lparam);
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "clutter-stage-win32.h"
|
#include "clutter-stage-win32.h"
|
||||||
#include "clutter-win32.h"
|
#include "clutter-win32.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"
|
||||||
@ -36,13 +37,21 @@
|
|||||||
#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-shader.h"
|
||||||
#include "../clutter-stage.h"
|
#include "../clutter-stage.h"
|
||||||
|
|
||||||
#include "cogl.h"
|
#include "cogl.h"
|
||||||
|
|
||||||
#include <windows.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
|
static void
|
||||||
clutter_stage_win32_show (ClutterActor *actor)
|
clutter_stage_win32_show (ClutterActor *actor)
|
||||||
@ -122,7 +131,7 @@ get_full_window_pos (ClutterStageWin32 *stage_win32,
|
|||||||
int *xpos_out, int *ypos_out)
|
int *xpos_out, int *ypos_out)
|
||||||
{
|
{
|
||||||
gboolean resizable
|
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
|
/* The window position passed to CreateWindow includes the window
|
||||||
decorations */
|
decorations */
|
||||||
*xpos_out = xpos_in - GetSystemMetrics (resizable ? SM_CXSIZEFRAME
|
*xpos_out = xpos_in - GetSystemMetrics (resizable ? SM_CXSIZEFRAME
|
||||||
@ -138,7 +147,7 @@ get_full_window_size (ClutterStageWin32 *stage_win32,
|
|||||||
int *width_out, int *height_out)
|
int *width_out, int *height_out)
|
||||||
{
|
{
|
||||||
gboolean resizable
|
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
|
/* The window size passed to CreateWindow includes the window
|
||||||
decorations */
|
decorations */
|
||||||
*width_out = width_in + GetSystemMetrics (resizable ? SM_CXSIZEFRAME
|
*width_out = width_in + GetSystemMetrics (resizable ? SM_CXSIZEFRAME
|
||||||
@ -154,7 +163,7 @@ _clutter_stage_win32_get_min_max_info (ClutterStageWin32 *stage_win32,
|
|||||||
{
|
{
|
||||||
/* If the window isn't resizable then set the max and min size to
|
/* If the window isn't resizable then set the max and min size to
|
||||||
the current size */
|
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;
|
int full_width, full_height;
|
||||||
get_full_window_size (stage_win32,
|
get_full_window_size (stage_win32,
|
||||||
@ -214,7 +223,8 @@ clutter_stage_win32_request_coords (ClutterActor *self,
|
|||||||
change_flags);
|
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)
|
CLUTTER_ACTOR_CLASS (clutter_stage_win32_parent_class)
|
||||||
@ -222,10 +232,10 @@ clutter_stage_win32_request_coords (ClutterActor *self,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_stage_win32_set_title (ClutterStage *stage,
|
clutter_stage_win32_set_title (ClutterStageWindow *stage_window,
|
||||||
const gchar *title)
|
const gchar *title)
|
||||||
{
|
{
|
||||||
ClutterStageWin32 *stage_win32 = CLUTTER_STAGE_WIN32 (stage);
|
ClutterStageWin32 *stage_win32 = CLUTTER_STAGE_WIN32 (stage_window);
|
||||||
wchar_t *wtitle;
|
wchar_t *wtitle;
|
||||||
|
|
||||||
/* Empty window titles not allowed, so set it to just a period. */
|
/* Empty window titles not allowed, so set it to just a period. */
|
||||||
@ -240,36 +250,44 @@ clutter_stage_win32_set_title (ClutterStage *stage,
|
|||||||
static LONG
|
static LONG
|
||||||
get_window_style (ClutterStageWin32 *stage_win32)
|
get_window_style (ClutterStageWin32 *stage_win32)
|
||||||
{
|
{
|
||||||
|
ClutterStage *wrapper = stage_win32->wrapper;
|
||||||
|
|
||||||
/* Fullscreen mode shouldn't have any borders */
|
/* Fullscreen mode shouldn't have any borders */
|
||||||
if ((stage_win32->state & CLUTTER_STAGE_STATE_FULLSCREEN))
|
if ((stage_win32->state & CLUTTER_STAGE_STATE_FULLSCREEN))
|
||||||
return WS_POPUP;
|
return WS_POPUP;
|
||||||
/* Otherwise it's an overlapped window but if it isn't resizable
|
/* Otherwise it's an overlapped window but if it isn't resizable
|
||||||
then it shouldn't have a thick frame */
|
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;
|
return WS_OVERLAPPEDWINDOW;
|
||||||
else
|
else
|
||||||
return WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME;
|
return WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_stage_win32_set_user_resize (ClutterStage *stage,
|
clutter_stage_win32_set_user_resize (ClutterStageWindow *stage_window,
|
||||||
gboolean value)
|
gboolean value)
|
||||||
{
|
{
|
||||||
HWND hwnd = CLUTTER_STAGE_WIN32 (stage)->hwnd;
|
HWND hwnd = CLUTTER_STAGE_WIN32 (stage_window)->hwnd;
|
||||||
LONG old_style = GetWindowLongW (hwnd, GWL_STYLE);
|
LONG old_style = GetWindowLongW (hwnd, GWL_STYLE);
|
||||||
|
|
||||||
/* Update the window style but preserve the visibility */
|
/* Update the window style but preserve the visibility */
|
||||||
SetWindowLongW (hwnd, GWL_STYLE,
|
SetWindowLongW (hwnd, GWL_STYLE,
|
||||||
get_window_style (CLUTTER_STAGE_WIN32 (stage))
|
get_window_style (CLUTTER_STAGE_WIN32 (stage_window))
|
||||||
| (old_style & WS_VISIBLE));
|
| (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
|
static void
|
||||||
clutter_stage_win32_set_fullscreen (ClutterStage *stage,
|
clutter_stage_win32_set_fullscreen (ClutterStageWindow *stage_window,
|
||||||
gboolean value)
|
gboolean value)
|
||||||
{
|
{
|
||||||
ClutterStageWin32 *stage_win32 = CLUTTER_STAGE_WIN32 (stage);
|
ClutterStageWin32 *stage_win32 = CLUTTER_STAGE_WIN32 (stage_window);
|
||||||
HWND hwnd = CLUTTER_STAGE_WIN32 (stage)->hwnd;
|
HWND hwnd = CLUTTER_STAGE_WIN32 (stage_window)->hwnd;
|
||||||
LONG old_style = GetWindowLongW (hwnd, GWL_STYLE);
|
LONG old_style = GetWindowLongW (hwnd, GWL_STYLE);
|
||||||
ClutterStageStateEvent event;
|
ClutterStageStateEvent event;
|
||||||
|
|
||||||
@ -316,13 +334,14 @@ clutter_stage_win32_set_fullscreen (ClutterStage *stage,
|
|||||||
SWP_NOZORDER);
|
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 */
|
/* Report the state change */
|
||||||
memset (&event, 0, sizeof (event));
|
memset (&event, 0, sizeof (event));
|
||||||
event.type = CLUTTER_STAGE_STATE;
|
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.new_state = stage_win32->state;
|
||||||
event.changed_mask = CLUTTER_STAGE_STATE_FULLSCREEN;
|
event.changed_mask = CLUTTER_STAGE_STATE_FULLSCREEN;
|
||||||
clutter_event_put ((ClutterEvent *) &event);
|
clutter_event_put ((ClutterEvent *) &event);
|
||||||
@ -407,6 +426,8 @@ clutter_stage_win32_realize (ClutterActor *actor)
|
|||||||
if (window_class == 0)
|
if (window_class == 0)
|
||||||
{
|
{
|
||||||
g_critical ("Unable to register window class");
|
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);
|
CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -449,6 +470,8 @@ clutter_stage_win32_realize (ClutterActor *actor)
|
|||||||
if (stage_win32->hwnd == NULL)
|
if (stage_win32->hwnd == NULL)
|
||||||
{
|
{
|
||||||
g_critical ("Unable to create stage window");
|
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);
|
CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -490,6 +513,8 @@ clutter_stage_win32_realize (ClutterActor *actor)
|
|||||||
|| !SetPixelFormat (stage_win32->client_dc, pf, &pfd))
|
|| !SetPixelFormat (stage_win32->client_dc, pf, &pfd))
|
||||||
{
|
{
|
||||||
g_critical ("Unable to find suitable GL pixel format");
|
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);
|
CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -501,24 +526,30 @@ clutter_stage_win32_realize (ClutterActor *actor)
|
|||||||
if (backend_win32->gl_context == NULL)
|
if (backend_win32->gl_context == NULL)
|
||||||
{
|
{
|
||||||
g_critical ("Unable to create suitable GL context");
|
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);
|
CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CLUTTER_NOTE (GL, "wglMakeCurrent");
|
/* below will call wglMakeCurrent */
|
||||||
|
CLUTTER_ACTOR_SET_FLAGS (stage_win32->wrapper, CLUTTER_ACTOR_REALIZED);
|
||||||
clutter_stage_ensure_current (CLUTTER_STAGE (stage_win32));
|
CLUTTER_ACTOR_SET_FLAGS (stage_win32, CLUTTER_ACTOR_REALIZED);
|
||||||
|
clutter_stage_ensure_current (stage_win32->wrapper);
|
||||||
|
|
||||||
if (!clutter_stage_win32_check_gl_version ())
|
if (!clutter_stage_win32_check_gl_version ())
|
||||||
{
|
{
|
||||||
g_critical ("OpenGL version number is too low");
|
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);
|
CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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_win32->wrapper,
|
||||||
|
CLUTTER_ACTOR_SYNC_MATRICES);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -526,7 +557,18 @@ clutter_stage_win32_unrealize (ClutterActor *actor)
|
|||||||
{
|
{
|
||||||
ClutterStageWin32 *stage_win32 = CLUTTER_STAGE_WIN32 (actor);
|
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->client_dc)
|
||||||
{
|
{
|
||||||
@ -536,6 +578,11 @@ clutter_stage_win32_unrealize (ClutterActor *actor)
|
|||||||
|
|
||||||
if (stage_win32->hwnd)
|
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);
|
DestroyWindow (stage_win32->hwnd);
|
||||||
stage_win32->hwnd = NULL;
|
stage_win32->hwnd = NULL;
|
||||||
}
|
}
|
||||||
@ -557,7 +604,6 @@ clutter_stage_win32_class_init (ClutterStageWin32Class *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_win32_dispose;
|
gobject_class->dispose = clutter_stage_win32_dispose;
|
||||||
|
|
||||||
@ -567,10 +613,6 @@ clutter_stage_win32_class_init (ClutterStageWin32Class *klass)
|
|||||||
actor_class->query_coords = clutter_stage_win32_query_coords;
|
actor_class->query_coords = clutter_stage_win32_query_coords;
|
||||||
actor_class->realize = clutter_stage_win32_realize;
|
actor_class->realize = clutter_stage_win32_realize;
|
||||||
actor_class->unrealize = clutter_stage_win32_unrealize;
|
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
|
static void
|
||||||
@ -584,6 +626,19 @@ clutter_stage_win32_init (ClutterStageWin32 *stage)
|
|||||||
stage->win_height = 480;
|
stage->win_height = 480;
|
||||||
stage->backend = NULL;
|
stage->backend = NULL;
|
||||||
stage->scroll_pos = 0;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -599,9 +654,15 @@ clutter_stage_win32_init (ClutterStageWin32 *stage)
|
|||||||
HWND
|
HWND
|
||||||
clutter_win32_get_stage_window (ClutterStage *stage)
|
clutter_win32_get_stage_window (ClutterStage *stage)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (CLUTTER_IS_STAGE_WIN32 (stage), NULL);
|
ClutterStageWindow *impl;
|
||||||
|
|
||||||
return CLUTTER_STAGE_WIN32 (stage)->hwnd;
|
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 (impl)->hwnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -624,7 +685,7 @@ clutter_win32_get_stage_from_window (HWND hwnd)
|
|||||||
== clutter_stage_win32_get_window_class ())
|
== clutter_stage_win32_get_window_class ())
|
||||||
/* If it is there should be a pointer to the stage in the window
|
/* If it is there should be a pointer to the stage in the window
|
||||||
extra data */
|
extra data */
|
||||||
return (ClutterStage *) GetWindowLongPtrW (hwnd, 0);
|
return CLUTTER_STAGE_WIN32 (GetWindowLongPtrW (hwnd, 0))->wrapper;
|
||||||
else
|
else
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -633,12 +694,14 @@ void
|
|||||||
clutter_stage_win32_map (ClutterStageWin32 *stage_win32)
|
clutter_stage_win32_map (ClutterStageWin32 *stage_win32)
|
||||||
{
|
{
|
||||||
CLUTTER_ACTOR_SET_FLAGS (stage_win32, CLUTTER_ACTOR_MAPPED);
|
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
|
void
|
||||||
clutter_stage_win32_unmap (ClutterStageWin32 *stage_win32)
|
clutter_stage_win32_unmap (ClutterStageWin32 *stage_win32)
|
||||||
{
|
{
|
||||||
CLUTTER_ACTOR_UNSET_FLAGS (stage_win32, CLUTTER_ACTOR_MAPPED);
|
CLUTTER_ACTOR_UNSET_FLAGS (stage_win32, CLUTTER_ACTOR_MAPPED);
|
||||||
|
CLUTTER_ACTOR_UNSET_FLAGS (stage_win32->wrapper, CLUTTER_ACTOR_MAPPED);
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
#ifndef __CLUTTER_STAGE_WIN32_H__
|
#ifndef __CLUTTER_STAGE_WIN32_H__
|
||||||
#define __CLUTTER_STAGE_WIN32_H__
|
#define __CLUTTER_STAGE_WIN32_H__
|
||||||
|
|
||||||
#include <glib-object.h>
|
#include <clutter/clutter-group.h>
|
||||||
#include <clutter/clutter-stage.h>
|
#include <clutter/clutter-stage.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ typedef struct _ClutterStageWin32Class ClutterStageWin32Class;
|
|||||||
|
|
||||||
struct _ClutterStageWin32
|
struct _ClutterStageWin32
|
||||||
{
|
{
|
||||||
ClutterStage parent_instance;
|
ClutterGroup parent_instance;
|
||||||
|
|
||||||
HWND hwnd;
|
HWND hwnd;
|
||||||
HDC client_dc;
|
HDC client_dc;
|
||||||
@ -55,11 +55,13 @@ struct _ClutterStageWin32
|
|||||||
|
|
||||||
ClutterBackendWin32 *backend;
|
ClutterBackendWin32 *backend;
|
||||||
ClutterStageState state;
|
ClutterStageState state;
|
||||||
|
|
||||||
|
ClutterStage *wrapper;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _ClutterStageWin32Class
|
struct _ClutterStageWin32Class
|
||||||
{
|
{
|
||||||
ClutterStageClass parent_class;
|
ClutterGroupClass parent_class;
|
||||||
};
|
};
|
||||||
|
|
||||||
GType clutter_stage_win32_get_type (void) G_GNUC_CONST;
|
GType clutter_stage_win32_get_type (void) G_GNUC_CONST;
|
||||||
|
Loading…
Reference in New Issue
Block a user