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>
* clutter/Makefile.am:

View File

@ -66,14 +66,6 @@ clutter_backend_win32_init_events (ClutterBackend *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[] =
{
{
@ -104,18 +96,19 @@ static void
clutter_backend_win32_dispose (GObject *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");
/* 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;
ClutterActor *stage = CLUTTER_ACTOR (l->data);
clutter_actor_destroy (stage);
}
CLUTTER_NOTE (BACKEND, "Removing the event source");
@ -175,7 +168,9 @@ clutter_backend_win32_get_features (ClutterBackend *backend)
glGetString (GL_VERSION),
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
disabled elsewhere (eg NVIDIA) then don't bother trying to check
@ -217,27 +212,38 @@ clutter_backend_win32_get_features (ClutterBackend *backend)
}
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;
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)
SwapBuffers (stage_win32->client_dc);
}
static gboolean
clutter_backend_win32_init_stage (ClutterBackend *backend,
static ClutterActor *
clutter_backend_win32_create_stage (ClutterBackend *backend,
GError **error)
{
ClutterBackendWin32 *backend_win32 = CLUTTER_BACKEND_WIN32 (backend);
if (!backend_win32->stage)
{
ClutterStageWin32 *stage_win32;
ClutterActor *stage;
@ -247,22 +253,20 @@ clutter_backend_win32_init_stage (ClutterBackend *backend,
stage_win32 = CLUTTER_STAGE_WIN32 (stage);
stage_win32->backend = backend_win32;
/* needed ? */
g_object_set_data (G_OBJECT (stage), "clutter-backend", backend);
backend_win32->stage = g_object_ref_sink (stage);
}
clutter_actor_realize (stage);
clutter_actor_realize (backend_win32->stage);
if (!CLUTTER_ACTOR_IS_REALIZED (backend_win32->stage))
if (!CLUTTER_ACTOR_IS_REALIZED (stage))
{
g_set_error (error, CLUTTER_INIT_ERROR,
CLUTTER_INIT_ERROR_INTERNAL,
"Unable to realize the main stage");
return FALSE;
return NULL;
}
return TRUE;
return stage;
}
static void
@ -277,11 +281,11 @@ clutter_backend_win32_class_init (ClutterBackendWin32Class *klass)
backend_class->pre_parse = clutter_backend_win32_pre_parse;
backend_class->init_events = clutter_backend_win32_init_events;
backend_class->init_stage = clutter_backend_win32_init_stage;
backend_class->get_stage = clutter_backend_win32_get_stage;
backend_class->create_stage = clutter_backend_win32_create_stage;
backend_class->add_options = clutter_backend_win32_add_options;
backend_class->get_features = clutter_backend_win32_get_features;
backend_class->redraw = clutter_backend_win32_redraw;
backend_class->ensure_context = clutter_backend_win32_ensure_context;
}
static void
@ -289,6 +293,8 @@ clutter_backend_win32_init (ClutterBackendWin32 *backend_win32)
{
ClutterBackend *backend = CLUTTER_BACKEND (backend_win32);
backend_win32->gl_context = NULL;
/* FIXME: get from GetSystemMetric? */
clutter_backend_set_double_click_time (backend, 250);
clutter_backend_set_double_click_distance (backend, 5);

View File

@ -45,8 +45,7 @@ struct _ClutterBackendWin32
{
ClutterBackend parent_instance;
/* main stage singleton */
ClutterActor *stage;
HGLRC gl_context;
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;
ClutterActor *
clutter_backend_win32_get_stage (ClutterBackend *backend);
void
clutter_backend_win32_add_options (ClutterBackend *backend,
GOptionGroup *group);

View File

@ -307,16 +307,17 @@ message_translate (ClutterBackend *backend,
ClutterStageWin32 *stage_win32;
ClutterStage *stage;
gboolean res;
HWND stage_hwnd;
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 */
if (stage_hwnd != msg->hwnd)
stage = clutter_win32_get_stage_from_window (msg->hwnd);
if (stage == NULL)
return FALSE;
stage_win32 = CLUTTER_STAGE_WIN32 (stage);
event->any.stage = stage;
res = TRUE;
@ -393,7 +394,8 @@ message_translate (ClutterBackend *backend,
break;
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;
break;

View File

@ -36,6 +36,7 @@
#include "../clutter-private.h"
#include "../clutter-debug.h"
#include "../clutter-units.h"
#include "../clutter-stage.h"
#include "cogl.h"
@ -171,18 +172,23 @@ clutter_stage_win32_request_coords (ClutterActor *self,
ClutterActorBox *box)
{
ClutterStageWin32 *stage_win32 = CLUTTER_STAGE_WIN32 (self);
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_ypos = CLUTTER_UNITS_TO_INT (MIN (box->y1, box->y2));
new_width = ABS (CLUTTER_UNITS_TO_INT (box->x2 - box->x1));
new_height = ABS (CLUTTER_UNITS_TO_INT (box->y2 - box->y1));
if ((new_width != stage_win32->win_width
|| new_height != stage_win32->win_height
|| new_xpos != stage_win32->win_xpos
if (new_width != stage_win32->win_width
|| new_height != stage_win32->win_height)
change_flags &= ~SWP_NOSIZE;
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 */
&& (stage_win32->state & CLUTTER_STAGE_STATE_FULLSCREEN) == 0)
{
@ -205,7 +211,7 @@ clutter_stage_win32_request_coords (ClutterActor *self,
SetWindowPos (stage_win32->hwnd, NULL,
full_xpos, full_ypos,
full_width, full_height,
SWP_NOZORDER);
change_flags);
}
CLUTTER_SET_PRIVATE_FLAGS (self, CLUTTER_ACTOR_SYNC_MATRICES);
@ -316,6 +322,7 @@ clutter_stage_win32_set_fullscreen (ClutterStage *stage,
/* Report the state change */
memset (&event, 0, sizeof (event));
event.type = CLUTTER_STAGE_STATE;
event.stage = CLUTTER_STAGE (stage_win32);
event.new_state = stage_win32->state;
event.changed_mask = CLUTTER_STAGE_STATE_FULLSCREEN;
clutter_event_put ((ClutterEvent *) &event);
@ -382,11 +389,14 @@ static void
clutter_stage_win32_realize (ClutterActor *actor)
{
ClutterStageWin32 *stage_win32 = CLUTTER_STAGE_WIN32 (actor);
ClutterBackendWin32 *backend_win32;
PIXELFORMATDESCRIPTOR pfd;
int pf;
CLUTTER_NOTE (MISC, "Realizing main stage");
backend_win32 = CLUTTER_BACKEND_WIN32 (clutter_get_default_backend ());
if (stage_win32->hwnd == NULL)
{
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);
}
if (stage_win32->gl_context)
wglDeleteContext (stage_win32->gl_context);
if (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));
pfd.nSize = sizeof (pfd);
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.cColorBits = 24;
pfd.cAlphaBits = 8;
@ -486,17 +494,21 @@ clutter_stage_win32_realize (ClutterActor *actor)
return;
}
stage_win32->gl_context = wglCreateContext (stage_win32->client_dc);
if (backend_win32->gl_context == NULL)
{
backend_win32->gl_context = wglCreateContext (stage_win32->client_dc);
if (stage_win32->gl_context == NULL)
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");
wglMakeCurrent (stage_win32->client_dc, stage_win32->gl_context);
clutter_stage_ensure_current (CLUTTER_STAGE (stage_win32));
if (!clutter_stage_win32_check_gl_version ())
{
@ -516,12 +528,6 @@ clutter_stage_win32_unrealize (ClutterActor *actor)
wglMakeCurrent (NULL, NULL);
if (stage_win32->gl_context != NULL)
{
wglDeleteContext (stage_win32->gl_context);
stage_win32->gl_context = NULL;
}
if (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->client_dc = NULL;
stage->gl_context = NULL;
stage->win_xpos = 0;
stage->win_ypos = 0;
stage->win_width = 640;
@ -599,6 +604,31 @@ clutter_win32_get_stage_window (ClutterStage *stage)
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
clutter_stage_win32_map (ClutterStageWin32 *stage_win32)
{

View File

@ -46,7 +46,6 @@ struct _ClutterStageWin32
HWND hwnd;
HDC client_dc;
HGLRC gl_context;
gint win_xpos;
gint win_ypos;
gint win_width;
@ -65,8 +64,6 @@ struct _ClutterStageWin32Class
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_unmap (ClutterStageWin32 *stage_win32);

View File

@ -44,6 +44,7 @@
G_BEGIN_DECLS
HWND clutter_win32_get_stage_window (ClutterStage *stage);
ClutterStage *clutter_win32_get_stage_from_window (HWND hwnd);
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>
* clutter-sections.txt: Added a section for the Win32 specific

View File

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