2008-03-30 Neil Roberts <neil@o-hand.com>

* clutter/win32/clutter-win32.h: 
	* clutter/win32/clutter-stage-win32.h: 
	* clutter/win32/clutter-stage-win32.c: 
	* clutter/win32/clutter-event-win32.c: 
	* clutter/win32/clutter-backend-win32.h: 
	* clutter/win32/clutter-backend-win32.c:
	Upgraded for multi-stage support.

	* clutter/win32/clutter-stage-win32.c
	(clutter_stage_win32_request_coords): Fixed so that it doesn't set
	the position or size if it hasn't changed. This was causing
	problems when the window was resized using the top left corner. In
	that case the window receives resize and move messages separately
	which caused the window to flash at a different size or position
	while one message was handled before the other.
	(clutter_stage_win32_realize): Added PFD_GENERIC_ACCELERATED to
	the list of pixel format flags to force it to use hardware
	acceleration.

2008-03-30  Neil Roberts  <neil@o-hand.com>

	* clutter-sections.txt: Added clutter_win32_get_stage_from_window
This commit is contained in:
Neil Roberts 2008-03-30 16:51:01 +00:00
parent 8847bcd195
commit 1a263dca5c
9 changed files with 148 additions and 90 deletions

View File

@ -1,3 +1,24 @@
2008-03-30 Neil Roberts <neil@o-hand.com>
* clutter/win32/clutter-win32.h:
* clutter/win32/clutter-stage-win32.h:
* clutter/win32/clutter-stage-win32.c:
* clutter/win32/clutter-event-win32.c:
* clutter/win32/clutter-backend-win32.h:
* clutter/win32/clutter-backend-win32.c:
Upgraded for multi-stage support.
* clutter/win32/clutter-stage-win32.c
(clutter_stage_win32_request_coords): Fixed so that it doesn't set
the position or size if it hasn't changed. This was causing
problems when the window was resized using the top left corner. In
that case the window receives resize and move messages separately
which caused the window to flash at a different size or position
while one message was handled before the other.
(clutter_stage_win32_realize): Added PFD_GENERIC_ACCELERATED to
the list of pixel format flags to force it to use hardware
acceleration.
2008-03-28 Matthew Allum <mallum@openedhand.com> 2008-03-28 Matthew Allum <mallum@openedhand.com>
* clutter/Makefile.am: * clutter/Makefile.am:

View File

@ -66,14 +66,6 @@ clutter_backend_win32_init_events (ClutterBackend *backend)
_clutter_backend_win32_events_init (backend); _clutter_backend_win32_events_init (backend);
} }
ClutterActor *
clutter_backend_win32_get_stage (ClutterBackend *backend)
{
ClutterBackendWin32 *backend_win32 = CLUTTER_BACKEND_WIN32 (backend);
return backend_win32->stage;
}
static const GOptionEntry entries[] = static const GOptionEntry entries[] =
{ {
{ {
@ -104,18 +96,19 @@ static void
clutter_backend_win32_dispose (GObject *gobject) clutter_backend_win32_dispose (GObject *gobject)
{ {
ClutterBackendWin32 *backend_win32 = CLUTTER_BACKEND_WIN32 (gobject); ClutterBackendWin32 *backend_win32 = CLUTTER_BACKEND_WIN32 (gobject);
ClutterMainContext *context;
ClutterStageManager *stage_manager;
GSList *l;
if (backend_win32->stage) 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)
{ {
CLUTTER_NOTE (BACKEND, "Disposing the main stage"); ClutterActor *stage = CLUTTER_ACTOR (l->data);
clutter_actor_destroy (stage);
/* we unset the private flag on the stage so we can safely
* destroy it without a warning from clutter_actor_destroy()
*/
CLUTTER_UNSET_PRIVATE_FLAGS (backend_win32->stage,
CLUTTER_ACTOR_IS_TOPLEVEL);
clutter_actor_destroy (backend_win32->stage);
backend_win32->stage = NULL;
} }
CLUTTER_NOTE (BACKEND, "Removing the event source"); CLUTTER_NOTE (BACKEND, "Removing the event source");
@ -175,7 +168,9 @@ clutter_backend_win32_get_features (ClutterBackend *backend)
glGetString (GL_VERSION), glGetString (GL_VERSION),
extensions); extensions);
flags = CLUTTER_FEATURE_STAGE_USER_RESIZE | CLUTTER_FEATURE_STAGE_CURSOR; flags = CLUTTER_FEATURE_STAGE_USER_RESIZE
| CLUTTER_FEATURE_STAGE_CURSOR
| CLUTTER_FEATURE_STAGE_MULTIPLE;
/* If the VBlank should be left at the default or it has been /* If the VBlank should be left at the default or it has been
disabled elsewhere (eg NVIDIA) then don't bother trying to check disabled elsewhere (eg NVIDIA) then don't bother trying to check
@ -217,52 +212,61 @@ clutter_backend_win32_get_features (ClutterBackend *backend)
} }
static void static void
clutter_backend_win32_redraw (ClutterBackend *backend) clutter_backend_win32_ensure_context (ClutterBackend *backend,
ClutterStage *stage)
{ {
ClutterBackendWin32 *backend_win32 = CLUTTER_BACKEND_WIN32 (backend); ClutterBackendWin32 *backend_win32;
ClutterStageWin32 *stage_win32; ClutterStageWin32 *stage_win32;
stage_win32 = CLUTTER_STAGE_WIN32 (backend_win32->stage); stage_win32 = CLUTTER_STAGE_WIN32 (stage);
backend_win32 = CLUTTER_BACKEND_WIN32 (backend);
clutter_actor_paint (CLUTTER_ACTOR (stage_win32)); CLUTTER_NOTE (MULTISTAGE, "setting context for stage:%p", stage );
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);
clutter_actor_paint (CLUTTER_ACTOR (stage));
if (stage_win32->client_dc) if (stage_win32->client_dc)
SwapBuffers (stage_win32->client_dc); SwapBuffers (stage_win32->client_dc);
} }
static gboolean static ClutterActor *
clutter_backend_win32_init_stage (ClutterBackend *backend, clutter_backend_win32_create_stage (ClutterBackend *backend,
GError **error) GError **error)
{ {
ClutterBackendWin32 *backend_win32 = CLUTTER_BACKEND_WIN32 (backend); ClutterBackendWin32 *backend_win32 = CLUTTER_BACKEND_WIN32 (backend);
ClutterStageWin32 *stage_win32;
ClutterActor *stage;
if (!backend_win32->stage) stage = g_object_new (CLUTTER_TYPE_STAGE_WIN32, NULL);
{
ClutterStageWin32 *stage_win32;
ClutterActor *stage;
stage = g_object_new (CLUTTER_TYPE_STAGE_WIN32, NULL); /* copy backend data into the stage */
stage_win32 = CLUTTER_STAGE_WIN32 (stage);
stage_win32->backend = backend_win32;
/* copy backend data into the stage */ /* needed ? */
stage_win32 = CLUTTER_STAGE_WIN32 (stage); g_object_set_data (G_OBJECT (stage), "clutter-backend", backend);
stage_win32->backend = backend_win32;
g_object_set_data (G_OBJECT (stage), "clutter-backend", backend); clutter_actor_realize (stage);
backend_win32->stage = g_object_ref_sink (stage); if (!CLUTTER_ACTOR_IS_REALIZED (stage))
}
clutter_actor_realize (backend_win32->stage);
if (!CLUTTER_ACTOR_IS_REALIZED (backend_win32->stage))
{ {
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; return NULL;
} }
return TRUE; return stage;
} }
static void static void
@ -275,13 +279,13 @@ clutter_backend_win32_class_init (ClutterBackendWin32Class *klass)
gobject_class->dispose = clutter_backend_win32_dispose; gobject_class->dispose = clutter_backend_win32_dispose;
gobject_class->finalize = clutter_backend_win32_finalize; gobject_class->finalize = clutter_backend_win32_finalize;
backend_class->pre_parse = clutter_backend_win32_pre_parse; backend_class->pre_parse = clutter_backend_win32_pre_parse;
backend_class->init_events = clutter_backend_win32_init_events; backend_class->init_events = clutter_backend_win32_init_events;
backend_class->init_stage = clutter_backend_win32_init_stage; backend_class->create_stage = clutter_backend_win32_create_stage;
backend_class->get_stage = clutter_backend_win32_get_stage; backend_class->add_options = clutter_backend_win32_add_options;
backend_class->add_options = clutter_backend_win32_add_options; backend_class->get_features = clutter_backend_win32_get_features;
backend_class->get_features = clutter_backend_win32_get_features; backend_class->redraw = clutter_backend_win32_redraw;
backend_class->redraw = clutter_backend_win32_redraw; backend_class->ensure_context = clutter_backend_win32_ensure_context;
} }
static void static void
@ -289,6 +293,8 @@ clutter_backend_win32_init (ClutterBackendWin32 *backend_win32)
{ {
ClutterBackend *backend = CLUTTER_BACKEND (backend_win32); ClutterBackend *backend = CLUTTER_BACKEND (backend_win32);
backend_win32->gl_context = NULL;
/* FIXME: get from GetSystemMetric? */ /* FIXME: get from GetSystemMetric? */
clutter_backend_set_double_click_time (backend, 250); clutter_backend_set_double_click_time (backend, 250);
clutter_backend_set_double_click_distance (backend, 5); clutter_backend_set_double_click_distance (backend, 5);

View File

@ -45,8 +45,7 @@ struct _ClutterBackendWin32
{ {
ClutterBackend parent_instance; ClutterBackend parent_instance;
/* main stage singleton */ HGLRC gl_context;
ClutterActor *stage;
GSource *event_source; GSource *event_source;
}; };
@ -61,9 +60,6 @@ void _clutter_backend_win32_events_uninit (ClutterBackend *backend);
GType clutter_backend_win32_get_type (void) G_GNUC_CONST; GType clutter_backend_win32_get_type (void) G_GNUC_CONST;
ClutterActor *
clutter_backend_win32_get_stage (ClutterBackend *backend);
void void
clutter_backend_win32_add_options (ClutterBackend *backend, clutter_backend_win32_add_options (ClutterBackend *backend,
GOptionGroup *group); GOptionGroup *group);

View File

@ -307,16 +307,17 @@ message_translate (ClutterBackend *backend,
ClutterStageWin32 *stage_win32; ClutterStageWin32 *stage_win32;
ClutterStage *stage; ClutterStage *stage;
gboolean res; gboolean res;
HWND stage_hwnd;
backend_win32 = CLUTTER_BACKEND_WIN32 (backend); backend_win32 = CLUTTER_BACKEND_WIN32 (backend);
stage = CLUTTER_STAGE (_clutter_backend_get_stage (backend));
stage_win32 = CLUTTER_STAGE_WIN32 (stage);
stage_hwnd = clutter_win32_get_stage_window (stage);
/* Do further processing only on events for the stage window */ /* Do further processing only on events for the stage window */
if (stage_hwnd != msg->hwnd) stage = clutter_win32_get_stage_from_window (msg->hwnd);
if (stage == NULL)
return FALSE; return FALSE;
stage_win32 = CLUTTER_STAGE_WIN32 (stage);
event->any.stage = stage;
res = TRUE; res = TRUE;
@ -393,7 +394,8 @@ message_translate (ClutterBackend *backend,
break; break;
case WM_PAINT: case WM_PAINT:
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage_win32)); CLUTTER_NOTE (MULTISTAGE, "expose for stage:%p, redrawing", stage);
clutter_redraw (stage);
res = FALSE; res = FALSE;
break; break;

View File

@ -36,6 +36,7 @@
#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-stage.h"
#include "cogl.h" #include "cogl.h"
@ -171,18 +172,23 @@ clutter_stage_win32_request_coords (ClutterActor *self,
ClutterActorBox *box) ClutterActorBox *box)
{ {
ClutterStageWin32 *stage_win32 = CLUTTER_STAGE_WIN32 (self); ClutterStageWin32 *stage_win32 = CLUTTER_STAGE_WIN32 (self);
gint new_xpos, new_ypos, new_width, new_height; gint new_xpos, new_ypos, new_width, new_height;
int change_flags = SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE;
new_xpos = CLUTTER_UNITS_TO_INT (MIN (box->x1, box->x2)); new_xpos = CLUTTER_UNITS_TO_INT (MIN (box->x1, box->x2));
new_ypos = CLUTTER_UNITS_TO_INT (MIN (box->y1, box->y2)); new_ypos = CLUTTER_UNITS_TO_INT (MIN (box->y1, box->y2));
new_width = ABS (CLUTTER_UNITS_TO_INT (box->x2 - box->x1)); new_width = ABS (CLUTTER_UNITS_TO_INT (box->x2 - box->x1));
new_height = ABS (CLUTTER_UNITS_TO_INT (box->y2 - box->y1)); new_height = ABS (CLUTTER_UNITS_TO_INT (box->y2 - box->y1));
if ((new_width != stage_win32->win_width if (new_width != stage_win32->win_width
|| new_height != stage_win32->win_height || new_height != stage_win32->win_height)
|| new_xpos != stage_win32->win_xpos change_flags &= ~SWP_NOSIZE;
|| new_ypos != stage_win32->win_ypos)
if (new_xpos != stage_win32->win_xpos
|| new_ypos != stage_win32->win_ypos)
change_flags &= ~SWP_NOMOVE;
if ((change_flags & (SWP_NOSIZE | SWP_NOMOVE)) != (SWP_NOSIZE | SWP_NOMOVE)
/* Ignore size requests if we are in full screen mode */ /* Ignore size requests if we are in full screen mode */
&& (stage_win32->state & CLUTTER_STAGE_STATE_FULLSCREEN) == 0) && (stage_win32->state & CLUTTER_STAGE_STATE_FULLSCREEN) == 0)
{ {
@ -205,7 +211,7 @@ clutter_stage_win32_request_coords (ClutterActor *self,
SetWindowPos (stage_win32->hwnd, NULL, SetWindowPos (stage_win32->hwnd, NULL,
full_xpos, full_ypos, full_xpos, full_ypos,
full_width, full_height, full_width, full_height,
SWP_NOZORDER); change_flags);
} }
CLUTTER_SET_PRIVATE_FLAGS (self, CLUTTER_ACTOR_SYNC_MATRICES); CLUTTER_SET_PRIVATE_FLAGS (self, CLUTTER_ACTOR_SYNC_MATRICES);
@ -316,6 +322,7 @@ clutter_stage_win32_set_fullscreen (ClutterStage *stage,
/* 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.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);
@ -382,11 +389,14 @@ static void
clutter_stage_win32_realize (ClutterActor *actor) clutter_stage_win32_realize (ClutterActor *actor)
{ {
ClutterStageWin32 *stage_win32 = CLUTTER_STAGE_WIN32 (actor); ClutterStageWin32 *stage_win32 = CLUTTER_STAGE_WIN32 (actor);
ClutterBackendWin32 *backend_win32;
PIXELFORMATDESCRIPTOR pfd; PIXELFORMATDESCRIPTOR pfd;
int pf; int pf;
CLUTTER_NOTE (MISC, "Realizing main stage"); CLUTTER_NOTE (MISC, "Realizing main stage");
backend_win32 = CLUTTER_BACKEND_WIN32 (clutter_get_default_backend ());
if (stage_win32->hwnd == NULL) if (stage_win32->hwnd == NULL)
{ {
ATOM window_class = clutter_stage_win32_get_window_class (); ATOM window_class = clutter_stage_win32_get_window_class ();
@ -459,9 +469,6 @@ clutter_stage_win32_realize (ClutterActor *actor)
SetWindowLongPtrW (stage_win32->hwnd, 0, (LONG_PTR) stage_win32); SetWindowLongPtrW (stage_win32->hwnd, 0, (LONG_PTR) stage_win32);
} }
if (stage_win32->gl_context)
wglDeleteContext (stage_win32->gl_context);
if (stage_win32->client_dc) if (stage_win32->client_dc)
ReleaseDC (stage_win32->hwnd, stage_win32->client_dc); ReleaseDC (stage_win32->hwnd, stage_win32->client_dc);
@ -470,7 +477,8 @@ clutter_stage_win32_realize (ClutterActor *actor)
memset (&pfd, 0, sizeof (pfd)); memset (&pfd, 0, sizeof (pfd));
pfd.nSize = sizeof (pfd); pfd.nSize = sizeof (pfd);
pfd.nVersion = 1; pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL
| PFD_DOUBLEBUFFER | PFD_GENERIC_ACCELERATED;
pfd.iPixelType = PFD_TYPE_RGBA; pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24; pfd.cColorBits = 24;
pfd.cAlphaBits = 8; pfd.cAlphaBits = 8;
@ -486,17 +494,21 @@ clutter_stage_win32_realize (ClutterActor *actor)
return; return;
} }
stage_win32->gl_context = wglCreateContext (stage_win32->client_dc); if (backend_win32->gl_context == NULL)
if (stage_win32->gl_context == NULL)
{ {
g_critical ("Unable to create suitable GL context"); backend_win32->gl_context = wglCreateContext (stage_win32->client_dc);
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 (actor, CLUTTER_ACTOR_REALIZED);
return;
}
} }
CLUTTER_NOTE (GL, "wglMakeCurrent"); CLUTTER_NOTE (GL, "wglMakeCurrent");
wglMakeCurrent (stage_win32->client_dc, stage_win32->gl_context);
clutter_stage_ensure_current (CLUTTER_STAGE (stage_win32));
if (!clutter_stage_win32_check_gl_version ()) if (!clutter_stage_win32_check_gl_version ())
{ {
@ -516,12 +528,6 @@ clutter_stage_win32_unrealize (ClutterActor *actor)
wglMakeCurrent (NULL, NULL); wglMakeCurrent (NULL, NULL);
if (stage_win32->gl_context != NULL)
{
wglDeleteContext (stage_win32->gl_context);
stage_win32->gl_context = NULL;
}
if (stage_win32->client_dc) if (stage_win32->client_dc)
{ {
ReleaseDC (stage_win32->hwnd, stage_win32->client_dc); ReleaseDC (stage_win32->hwnd, stage_win32->client_dc);
@ -572,7 +578,6 @@ clutter_stage_win32_init (ClutterStageWin32 *stage)
{ {
stage->hwnd = NULL; stage->hwnd = NULL;
stage->client_dc = NULL; stage->client_dc = NULL;
stage->gl_context = NULL;
stage->win_xpos = 0; stage->win_xpos = 0;
stage->win_ypos = 0; stage->win_ypos = 0;
stage->win_width = 640; stage->win_width = 640;
@ -599,6 +604,31 @@ clutter_win32_get_stage_window (ClutterStage *stage)
return CLUTTER_STAGE_WIN32 (stage)->hwnd; return CLUTTER_STAGE_WIN32 (stage)->hwnd;
} }
/**
* clutter_win32_get_stage_from_window:
* @hwnd: a window handle
*
* Gets the stage for a particular window.
*
* Return value: The stage or NULL if a stage does not exist for the
* window.
*
* Since: 0.8
*/
ClutterStage *
clutter_win32_get_stage_from_window (HWND hwnd)
{
/* Check whether the window handle is an instance of the stage
window class */
if ((ATOM) GetClassLongPtrW (hwnd, GCW_ATOM)
== 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);
else
return NULL;
}
void void
clutter_stage_win32_map (ClutterStageWin32 *stage_win32) clutter_stage_win32_map (ClutterStageWin32 *stage_win32)
{ {

View File

@ -46,7 +46,6 @@ struct _ClutterStageWin32
HWND hwnd; HWND hwnd;
HDC client_dc; HDC client_dc;
HGLRC gl_context;
gint win_xpos; gint win_xpos;
gint win_ypos; gint win_ypos;
gint win_width; gint win_width;
@ -65,8 +64,6 @@ struct _ClutterStageWin32Class
GType clutter_stage_win32_get_type (void) G_GNUC_CONST; GType clutter_stage_win32_get_type (void) G_GNUC_CONST;
HWND clutter_win32_get_stage_window (ClutterStage *stage);
void clutter_stage_win32_map (ClutterStageWin32 *stage_win32); void clutter_stage_win32_map (ClutterStageWin32 *stage_win32);
void clutter_stage_win32_unmap (ClutterStageWin32 *stage_win32); void clutter_stage_win32_unmap (ClutterStageWin32 *stage_win32);

View File

@ -43,7 +43,8 @@
G_BEGIN_DECLS G_BEGIN_DECLS
HWND clutter_win32_get_stage_window (ClutterStage *stage); HWND clutter_win32_get_stage_window (ClutterStage *stage);
ClutterStage *clutter_win32_get_stage_from_window (HWND hwnd);
G_END_DECLS G_END_DECLS

View File

@ -1,3 +1,7 @@
2008-03-30 Neil Roberts <neil@o-hand.com>
* clutter-sections.txt: Added clutter_win32_get_stage_from_window
2008-03-26 Neil Roberts <neil@o-hand.com> 2008-03-26 Neil Roberts <neil@o-hand.com>
* clutter-sections.txt: Added a section for the Win32 specific * clutter-sections.txt: Added a section for the Win32 specific

View File

@ -1008,6 +1008,7 @@ clutter_x11_remove_filter
<SECTION> <SECTION>
<FILE>clutter-win32</FILE> <FILE>clutter-win32</FILE>
<TITLE>Win32 Specific Support</TITLE> <TITLE>Win32 Specific Support</TITLE>
clutter_win32_get_stage_from_window
clutter_win32_get_stage_window clutter_win32_get_stage_window
</SECTION> </SECTION>