mirror of
https://github.com/brl/mutter.git
synced 2024-11-23 00:20:42 -05: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>
|
2008-04-15 Øyvind Kolås <pippin@o-hand.com>
|
||||||
|
|
||||||
* clutter/clutter-actor.c: (clutter_actor_set_shader_param): queue a
|
* clutter/clutter-actor.c: (clutter_actor_set_shader_param): queue a
|
||||||
|
@ -269,8 +269,9 @@ clutter_backend_win32_ensure_context (ClutterBackend *backend,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
CLUTTER_NOTE (BACKEND,
|
CLUTTER_NOTE (BACKEND,
|
||||||
"MakeCurrent window %p, context %p",
|
"MakeCurrent window %p (%s), context %p",
|
||||||
stage_win32->hwnd,
|
stage_win32->hwnd,
|
||||||
|
stage_win32->is_foreign_win ? "foreign" : "native",
|
||||||
backend_win32->gl_context);
|
backend_win32->gl_context);
|
||||||
wglMakeCurrent (stage_win32->client_dc,
|
wglMakeCurrent (stage_win32->client_dc,
|
||||||
backend_win32->gl_context);
|
backend_win32->gl_context);
|
||||||
@ -367,6 +368,7 @@ clutter_backend_win32_init (ClutterBackendWin32 *backend_win32)
|
|||||||
ClutterBackend *backend = CLUTTER_BACKEND (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? */
|
/* FIXME: get from GetSystemMetric? */
|
||||||
clutter_backend_set_double_click_time (backend, 250);
|
clutter_backend_set_double_click_time (backend, 250);
|
||||||
|
@ -46,6 +46,7 @@ struct _ClutterBackendWin32
|
|||||||
ClutterBackend parent_instance;
|
ClutterBackend parent_instance;
|
||||||
|
|
||||||
HGLRC gl_context;
|
HGLRC gl_context;
|
||||||
|
gboolean no_event_retrieval;
|
||||||
|
|
||||||
GSource *event_source;
|
GSource *event_source;
|
||||||
};
|
};
|
||||||
|
@ -212,6 +212,28 @@ make_button_event (const MSG *msg, ClutterEvent *event,
|
|||||||
event->button.click_count = click_count;
|
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
|
static gboolean
|
||||||
clutter_event_prepare (GSource *source,
|
clutter_event_prepare (GSource *source,
|
||||||
gint *timeout)
|
gint *timeout)
|
||||||
@ -327,6 +349,7 @@ message_translate (ClutterBackend *backend,
|
|||||||
switch (msg->message)
|
switch (msg->message)
|
||||||
{
|
{
|
||||||
case WM_SIZE:
|
case WM_SIZE:
|
||||||
|
if (!stage_win32->is_foreign_win)
|
||||||
{
|
{
|
||||||
WORD new_width = LOWORD (msg->lParam);
|
WORD new_width = LOWORD (msg->lParam);
|
||||||
WORD new_height = HIWORD (msg->lParam);
|
WORD new_height = HIWORD (msg->lParam);
|
||||||
@ -343,6 +366,7 @@ message_translate (ClutterBackend *backend,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case WM_MOVE:
|
case WM_MOVE:
|
||||||
|
if (!stage_win32->is_foreign_win)
|
||||||
{
|
{
|
||||||
WORD new_xpos = GET_X_LPARAM (msg->lParam);
|
WORD new_xpos = GET_X_LPARAM (msg->lParam);
|
||||||
WORD new_ypos = GET_Y_LPARAM (msg->lParam);
|
WORD new_ypos = GET_Y_LPARAM (msg->lParam);
|
||||||
|
@ -206,7 +206,7 @@ clutter_stage_win32_request_coords (ClutterActor *self,
|
|||||||
stage_win32->win_width = new_width;
|
stage_win32->win_width = new_width;
|
||||||
stage_win32->win_height = new_height;
|
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;
|
int full_xpos, full_ypos, full_width, full_height;
|
||||||
|
|
||||||
@ -576,7 +576,7 @@ clutter_stage_win32_unrealize (ClutterActor *actor)
|
|||||||
stage_win32->client_dc = NULL;
|
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
|
/* Drop the pointer to this stage in the window so that any
|
||||||
further messages won't be processed. The stage might be being
|
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->win_height = 480;
|
||||||
stage->backend = NULL;
|
stage->backend = NULL;
|
||||||
stage->scroll_pos = 0;
|
stage->scroll_pos = 0;
|
||||||
|
stage->is_foreign_win = FALSE;
|
||||||
|
|
||||||
stage->wrapper = NULL;
|
stage->wrapper = NULL;
|
||||||
|
|
||||||
@ -687,9 +688,86 @@ clutter_win32_get_stage_from_window (HWND hwnd)
|
|||||||
extra data */
|
extra data */
|
||||||
return CLUTTER_STAGE_WIN32 (GetWindowLongPtrW (hwnd, 0))->wrapper;
|
return CLUTTER_STAGE_WIN32 (GetWindowLongPtrW (hwnd, 0))->wrapper;
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
/* 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;
|
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
|
void
|
||||||
clutter_stage_win32_map (ClutterStageWin32 *stage_win32)
|
clutter_stage_win32_map (ClutterStageWin32 *stage_win32)
|
||||||
{
|
{
|
||||||
|
@ -52,6 +52,7 @@ struct _ClutterStageWin32
|
|||||||
gint win_height;
|
gint win_height;
|
||||||
gint scroll_pos;
|
gint scroll_pos;
|
||||||
RECT fullscreen_rect;
|
RECT fullscreen_rect;
|
||||||
|
gboolean is_foreign_win;
|
||||||
|
|
||||||
ClutterBackendWin32 *backend;
|
ClutterBackendWin32 *backend;
|
||||||
ClutterStageState state;
|
ClutterStageState state;
|
||||||
|
@ -46,6 +46,11 @@ 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);
|
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
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __CLUTTER_WIN32_H__ */
|
#endif /* __CLUTTER_WIN32_H__ */
|
||||||
|
Loading…
Reference in New Issue
Block a user