mirror of
https://github.com/brl/mutter.git
synced 2024-12-23 03:22:04 +00:00
Added support for foreign windows to the Win32 backend.
* clutter/win32/clutter-stage-win32.c (clutter_stage_win32_request_coords): Don't resize foreign windows. (clutter_stage_win32_unrealize): Don't destroy foreign windows. (clutter_stage_win32_init): Added initialiser for is_foreign_win. (clutter_win32_get_stage_from_window): Resort to looking in the stage list if the window isn't the right window class so that it can still find stages with foreign windows. (clutter_win32_set_stage_foreign): New public function to set a foreign window for a stage. * clutter/win32/clutter-event-win32.c (clutter_win32_disable_event_retrieval): New public function to disable event retrieval. (message_translate): Don't handle WM_SIZE or WM_MOVE for foreign windows. * clutter/win32/clutter-backend-win32.h (struct _ClutterBackendWin32): Added a flag to disable event retrieval * clutter/win32/clutter-backend-win32.c (clutter_backend_win32_ensure_context): Update debug note to include whether the stage is foreign or not.
This commit is contained in:
parent
429f7e64ca
commit
3d1f2a0859
28
ChangeLog
28
ChangeLog
@ -1,3 +1,31 @@
|
||||
2008-04-15 Neil Roberts <neil@o-hand.com>
|
||||
|
||||
Added support for foreign windows to the Win32 backend.
|
||||
|
||||
* clutter/win32/clutter-stage-win32.c
|
||||
(clutter_stage_win32_request_coords): Don't resize foreign
|
||||
windows.
|
||||
(clutter_stage_win32_unrealize): Don't destroy foreign windows.
|
||||
(clutter_stage_win32_init): Added initialiser for is_foreign_win.
|
||||
(clutter_win32_get_stage_from_window): Resort to looking in the
|
||||
stage list if the window isn't the right window class so that it
|
||||
can still find stages with foreign windows.
|
||||
(clutter_win32_set_stage_foreign): New public function to set a
|
||||
foreign window for a stage.
|
||||
|
||||
* clutter/win32/clutter-event-win32.c
|
||||
(clutter_win32_disable_event_retrieval): New public function to
|
||||
disable event retrieval.
|
||||
(message_translate): Don't handle WM_SIZE or WM_MOVE for foreign
|
||||
windows.
|
||||
|
||||
* clutter/win32/clutter-backend-win32.h (struct
|
||||
_ClutterBackendWin32): Added a flag to disable event retrieval
|
||||
|
||||
* clutter/win32/clutter-backend-win32.c
|
||||
(clutter_backend_win32_ensure_context): Update debug note to
|
||||
include whether the stage is foreign or not.
|
||||
|
||||
2008-04-15 Øyvind Kolås <pippin@o-hand.com>
|
||||
|
||||
* clutter/clutter-actor.c: (clutter_actor_set_shader_param): queue a
|
||||
|
@ -269,8 +269,9 @@ clutter_backend_win32_ensure_context (ClutterBackend *backend,
|
||||
else
|
||||
{
|
||||
CLUTTER_NOTE (BACKEND,
|
||||
"MakeCurrent window %p, context %p",
|
||||
"MakeCurrent window %p (%s), context %p",
|
||||
stage_win32->hwnd,
|
||||
stage_win32->is_foreign_win ? "foreign" : "native",
|
||||
backend_win32->gl_context);
|
||||
wglMakeCurrent (stage_win32->client_dc,
|
||||
backend_win32->gl_context);
|
||||
@ -366,7 +367,8 @@ clutter_backend_win32_init (ClutterBackendWin32 *backend_win32)
|
||||
{
|
||||
ClutterBackend *backend = CLUTTER_BACKEND (backend_win32);
|
||||
|
||||
backend_win32->gl_context = NULL;
|
||||
backend_win32->gl_context = NULL;
|
||||
backend_win32->no_event_retrieval = FALSE;
|
||||
|
||||
/* FIXME: get from GetSystemMetric? */
|
||||
clutter_backend_set_double_click_time (backend, 250);
|
||||
|
@ -45,9 +45,10 @@ struct _ClutterBackendWin32
|
||||
{
|
||||
ClutterBackend parent_instance;
|
||||
|
||||
HGLRC gl_context;
|
||||
HGLRC gl_context;
|
||||
gboolean no_event_retrieval;
|
||||
|
||||
GSource *event_source;
|
||||
GSource *event_source;
|
||||
};
|
||||
|
||||
struct _ClutterBackendWin32Class
|
||||
|
@ -212,6 +212,28 @@ make_button_event (const MSG *msg, ClutterEvent *event,
|
||||
event->button.click_count = click_count;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_win32_disable_event_retrieval
|
||||
*
|
||||
* Disables retrieval of Windows messages in the main loop. Use to
|
||||
* create event-less canvas.
|
||||
*
|
||||
* This function can only be called before calling clutter_init().
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
void
|
||||
clutter_win32_disable_event_retrieval (void)
|
||||
{
|
||||
ClutterBackendWin32 *backend;
|
||||
ClutterMainContext *clutter_context;
|
||||
|
||||
clutter_context = clutter_context_get_default ();
|
||||
backend = CLUTTER_BACKEND_WIN32 (clutter_context->backend);
|
||||
|
||||
backend->no_event_retrieval = TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clutter_event_prepare (GSource *source,
|
||||
gint *timeout)
|
||||
@ -327,34 +349,36 @@ message_translate (ClutterBackend *backend,
|
||||
switch (msg->message)
|
||||
{
|
||||
case WM_SIZE:
|
||||
{
|
||||
WORD new_width = LOWORD (msg->lParam);
|
||||
WORD new_height = HIWORD (msg->lParam);
|
||||
guint old_width, old_height;
|
||||
if (!stage_win32->is_foreign_win)
|
||||
{
|
||||
WORD new_width = LOWORD (msg->lParam);
|
||||
WORD new_height = HIWORD (msg->lParam);
|
||||
guint old_width, old_height;
|
||||
|
||||
clutter_actor_get_size (CLUTTER_ACTOR (stage),
|
||||
&old_width, &old_height);
|
||||
clutter_actor_get_size (CLUTTER_ACTOR (stage),
|
||||
&old_width, &old_height);
|
||||
|
||||
if (new_width != old_width || new_height != old_height)
|
||||
clutter_actor_set_size (CLUTTER_ACTOR (stage),
|
||||
new_width, new_height);
|
||||
}
|
||||
if (new_width != old_width || new_height != old_height)
|
||||
clutter_actor_set_size (CLUTTER_ACTOR (stage),
|
||||
new_width, new_height);
|
||||
}
|
||||
res = FALSE;
|
||||
break;
|
||||
|
||||
case WM_MOVE:
|
||||
{
|
||||
WORD new_xpos = GET_X_LPARAM (msg->lParam);
|
||||
WORD new_ypos = GET_Y_LPARAM (msg->lParam);
|
||||
guint old_xpos, old_ypos;
|
||||
if (!stage_win32->is_foreign_win)
|
||||
{
|
||||
WORD new_xpos = GET_X_LPARAM (msg->lParam);
|
||||
WORD new_ypos = GET_Y_LPARAM (msg->lParam);
|
||||
guint old_xpos, old_ypos;
|
||||
|
||||
clutter_actor_get_position (CLUTTER_ACTOR (stage),
|
||||
&old_xpos, &old_ypos);
|
||||
clutter_actor_get_position (CLUTTER_ACTOR (stage),
|
||||
&old_xpos, &old_ypos);
|
||||
|
||||
if (new_xpos != old_xpos || new_ypos != old_ypos)
|
||||
clutter_actor_set_position (CLUTTER_ACTOR (stage),
|
||||
new_xpos, new_ypos);
|
||||
}
|
||||
if (new_xpos != old_xpos || new_ypos != old_ypos)
|
||||
clutter_actor_set_position (CLUTTER_ACTOR (stage),
|
||||
new_xpos, new_ypos);
|
||||
}
|
||||
res = FALSE;
|
||||
break;
|
||||
|
||||
|
@ -206,7 +206,7 @@ clutter_stage_win32_request_coords (ClutterActor *self,
|
||||
stage_win32->win_width = new_width;
|
||||
stage_win32->win_height = new_height;
|
||||
|
||||
if (stage_win32->hwnd != NULL)
|
||||
if (stage_win32->hwnd != NULL && !stage_win32->is_foreign_win)
|
||||
{
|
||||
int full_xpos, full_ypos, full_width, full_height;
|
||||
|
||||
@ -576,7 +576,7 @@ clutter_stage_win32_unrealize (ClutterActor *actor)
|
||||
stage_win32->client_dc = NULL;
|
||||
}
|
||||
|
||||
if (stage_win32->hwnd)
|
||||
if (!stage_win32->is_foreign_win && 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
|
||||
@ -626,6 +626,7 @@ clutter_stage_win32_init (ClutterStageWin32 *stage)
|
||||
stage->win_height = 480;
|
||||
stage->backend = NULL;
|
||||
stage->scroll_pos = 0;
|
||||
stage->is_foreign_win = FALSE;
|
||||
|
||||
stage->wrapper = NULL;
|
||||
|
||||
@ -687,9 +688,86 @@ clutter_win32_get_stage_from_window (HWND hwnd)
|
||||
extra data */
|
||||
return CLUTTER_STAGE_WIN32 (GetWindowLongPtrW (hwnd, 0))->wrapper;
|
||||
else
|
||||
return NULL;
|
||||
{
|
||||
/* Otherwise it might be a foreign window so we should check the
|
||||
stage list */
|
||||
ClutterMainContext *context = clutter_context_get_default ();
|
||||
ClutterStageManager *stage_manager = context->stage_manager;
|
||||
GSList *l;
|
||||
|
||||
for (l = stage_manager->stages; l; l = l->next)
|
||||
{
|
||||
ClutterStage *stage = l->data;
|
||||
ClutterStageWindow *impl;
|
||||
|
||||
impl = _clutter_stage_get_window (stage);
|
||||
g_assert (CLUTTER_IS_STAGE_WIN32 (impl));
|
||||
|
||||
if (CLUTTER_STAGE_WIN32 (impl)->hwnd == hwnd)
|
||||
return stage;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_win32_set_stage_foreign:
|
||||
* @stage: a #ClutterStage
|
||||
* @hwnd: an existing window handle
|
||||
*
|
||||
* Target the #ClutterStage to use an existing external window handle.
|
||||
*
|
||||
* Return value: %TRUE if foreign window is valid
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
gboolean
|
||||
clutter_win32_set_stage_foreign (ClutterStage *stage,
|
||||
HWND hwnd)
|
||||
{
|
||||
ClutterStageWin32 *stage_win32;
|
||||
ClutterStageWindow *impl;
|
||||
ClutterActor *actor;
|
||||
RECT client_rect;
|
||||
POINT window_pos;
|
||||
ClutterGeometry geom;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_STAGE (stage), FALSE);
|
||||
g_return_val_if_fail (hwnd != NULL, FALSE);
|
||||
|
||||
actor = CLUTTER_ACTOR (stage);
|
||||
|
||||
impl = _clutter_stage_get_window (stage);
|
||||
stage_win32 = CLUTTER_STAGE_WIN32 (impl);
|
||||
|
||||
clutter_actor_unrealize (actor);
|
||||
|
||||
if (!GetClientRect (hwnd, &client_rect))
|
||||
{
|
||||
g_warning ("Unable to retrieve the new window geometry");
|
||||
return FALSE;
|
||||
}
|
||||
window_pos.x = client_rect.left;
|
||||
window_pos.y = client_rect.right;
|
||||
ClientToScreen (hwnd, &window_pos);
|
||||
|
||||
CLUTTER_NOTE (BACKEND, "Setting foreign window (0x%x)", (int) hwnd);
|
||||
|
||||
stage_win32->hwnd = hwnd;
|
||||
stage_win32->is_foreign_win = TRUE;
|
||||
|
||||
geom.x = window_pos.x;
|
||||
geom.y = window_pos.y;
|
||||
geom.width = client_rect.right - client_rect.left;
|
||||
geom.height = client_rect.bottom - client_rect.top;
|
||||
|
||||
clutter_actor_set_geometry (actor, &geom);
|
||||
clutter_actor_realize (actor);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
clutter_stage_win32_map (ClutterStageWin32 *stage_win32)
|
||||
{
|
||||
|
@ -52,6 +52,7 @@ struct _ClutterStageWin32
|
||||
gint win_height;
|
||||
gint scroll_pos;
|
||||
RECT fullscreen_rect;
|
||||
gboolean is_foreign_win;
|
||||
|
||||
ClutterBackendWin32 *backend;
|
||||
ClutterStageState state;
|
||||
|
@ -43,8 +43,13 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
HWND clutter_win32_get_stage_window (ClutterStage *stage);
|
||||
ClutterStage *clutter_win32_get_stage_from_window (HWND hwnd);
|
||||
HWND clutter_win32_get_stage_window (ClutterStage *stage);
|
||||
ClutterStage *clutter_win32_get_stage_from_window (HWND hwnd);
|
||||
|
||||
gboolean clutter_win32_set_stage_foreign (ClutterStage *stage,
|
||||
HWND hwnd);
|
||||
|
||||
void clutter_win32_disable_event_retrieval (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user