win32: Use the Cogl WGL winsys
Cogl now has a full WGL winsys so Clutter doesn't need to directly deal with WGL itself.
This commit is contained in:
parent
36e3a19722
commit
f5ace7b2a5
@ -54,6 +54,15 @@ static HINSTANCE clutter_hinst = NULL;
|
|||||||
/* various flags corresponding to pre init setup calls */
|
/* various flags corresponding to pre init setup calls */
|
||||||
static gboolean _no_event_retrieval = FALSE;
|
static gboolean _no_event_retrieval = FALSE;
|
||||||
|
|
||||||
|
G_CONST_RETURN gchar *
|
||||||
|
_clutter_backend_win32_get_vblank (void)
|
||||||
|
{
|
||||||
|
if (clutter_vblank_name && strcmp (clutter_vblank_name, "0") == 0)
|
||||||
|
return "none";
|
||||||
|
else
|
||||||
|
return clutter_vblank_name;
|
||||||
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
clutter_backend_win32_pre_parse (ClutterBackend *backend,
|
clutter_backend_win32_pre_parse (ClutterBackend *backend,
|
||||||
GError **error)
|
GError **error)
|
||||||
@ -125,6 +134,7 @@ clutter_backend_win32_finalize (GObject *gobject)
|
|||||||
static void
|
static void
|
||||||
clutter_backend_win32_dispose (GObject *gobject)
|
clutter_backend_win32_dispose (GObject *gobject)
|
||||||
{
|
{
|
||||||
|
ClutterBackend *backend = CLUTTER_BACKEND (gobject);
|
||||||
ClutterBackendWin32 *backend_win32 = CLUTTER_BACKEND_WIN32 (gobject);
|
ClutterBackendWin32 *backend_win32 = CLUTTER_BACKEND_WIN32 (gobject);
|
||||||
ClutterStageManager *stage_manager;
|
ClutterStageManager *stage_manager;
|
||||||
|
|
||||||
@ -139,26 +149,13 @@ clutter_backend_win32_dispose (GObject *gobject)
|
|||||||
/* Unrealize all shaders, since the GL context is going away */
|
/* Unrealize all shaders, since the GL context is going away */
|
||||||
_clutter_shader_release_all ();
|
_clutter_shader_release_all ();
|
||||||
|
|
||||||
if (backend_win32->gl_context)
|
|
||||||
{
|
|
||||||
wglMakeCurrent (NULL, NULL);
|
|
||||||
wglDeleteContext (backend_win32->gl_context);
|
|
||||||
backend_win32->gl_context = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (backend_win32->dummy_dc)
|
|
||||||
{
|
|
||||||
ReleaseDC (backend_win32->dummy_hwnd, backend_win32->dummy_dc);
|
|
||||||
backend_win32->dummy_dc = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (backend_win32->dummy_hwnd)
|
|
||||||
{
|
|
||||||
DestroyWindow (backend_win32->dummy_hwnd);
|
|
||||||
backend_win32->dummy_hwnd = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (clutter_backend_win32_parent_class)->dispose (gobject);
|
G_OBJECT_CLASS (clutter_backend_win32_parent_class)->dispose (gobject);
|
||||||
|
|
||||||
|
if (backend->cogl_context)
|
||||||
|
{
|
||||||
|
cogl_object_unref (backend->cogl_context);
|
||||||
|
backend->cogl_context = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static GObject *
|
static GObject *
|
||||||
@ -185,296 +182,110 @@ clutter_backend_win32_constructor (GType gtype,
|
|||||||
return g_object_ref (backend_singleton);
|
return g_object_ref (backend_singleton);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
check_vblank_env (const char *name)
|
|
||||||
{
|
|
||||||
return clutter_vblank_name && !g_ascii_strcasecmp (clutter_vblank_name, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
ClutterFeatureFlags
|
ClutterFeatureFlags
|
||||||
clutter_backend_win32_get_features (ClutterBackend *backend)
|
clutter_backend_win32_get_features (ClutterBackend *backend)
|
||||||
{
|
{
|
||||||
ClutterFeatureFlags flags;
|
ClutterBackendClass *parent_class;
|
||||||
const gchar *extensions;
|
ClutterFeatureFlags flags;
|
||||||
SwapIntervalProc swap_interval;
|
|
||||||
ClutterBackendWin32 *backend_win32;
|
|
||||||
|
|
||||||
/* this will make sure that the GL context exists and is bound to a
|
parent_class = CLUTTER_BACKEND_CLASS (clutter_backend_win32_parent_class);
|
||||||
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);
|
|
||||||
|
|
||||||
extensions = (const gchar *) glGetString (GL_EXTENSIONS);
|
flags = CLUTTER_FEATURE_STAGE_USER_RESIZE | CLUTTER_FEATURE_STAGE_CURSOR;
|
||||||
|
|
||||||
CLUTTER_NOTE (BACKEND,
|
if (cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_MULTIPLE_ONSCREEN))
|
||||||
"Checking features\n"
|
|
||||||
" GL_VENDOR: %s\n"
|
|
||||||
" GL_RENDERER: %s\n"
|
|
||||||
" GL_VERSION: %s\n"
|
|
||||||
" GL_EXTENSIONS: %s\n",
|
|
||||||
glGetString (GL_VENDOR),
|
|
||||||
glGetString (GL_RENDERER),
|
|
||||||
glGetString (GL_VERSION),
|
|
||||||
extensions);
|
|
||||||
|
|
||||||
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
|
|
||||||
for the swap control extension */
|
|
||||||
if (getenv ("__GL_SYNC_TO_VBLANK") || check_vblank_env ("default"))
|
|
||||||
CLUTTER_NOTE (BACKEND, "vblank sync: left at default at user request");
|
|
||||||
else if (cogl_clutter_check_extension ("WGL_EXT_swap_control", extensions)
|
|
||||||
&& (swap_interval = (SwapIntervalProc)
|
|
||||||
wglGetProcAddress ((LPCSTR) "wglSwapIntervalEXT")))
|
|
||||||
{
|
{
|
||||||
/* According to the specification for the WGL_EXT_swap_control
|
CLUTTER_NOTE (BACKEND, "Cogl supports multiple onscreen framebuffers");
|
||||||
extension the default swap interval is 1 anyway, so if no
|
flags |= CLUTTER_FEATURE_STAGE_MULTIPLE;
|
||||||
vblank is requested then we should explicitly set it to
|
|
||||||
zero */
|
|
||||||
if (check_vblank_env ("none"))
|
|
||||||
{
|
|
||||||
if (swap_interval (0))
|
|
||||||
CLUTTER_NOTE (BACKEND, "vblank sync: successfully disabled");
|
|
||||||
else
|
|
||||||
CLUTTER_NOTE (BACKEND, "vblank sync: disabling failed");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (swap_interval (1))
|
|
||||||
{
|
|
||||||
flags |= CLUTTER_FEATURE_SYNC_TO_VBLANK;
|
|
||||||
CLUTTER_NOTE (BACKEND, "vblank sync: wglSwapIntervalEXT "
|
|
||||||
"vblank setup success");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
CLUTTER_NOTE (BACKEND, "vblank sync: wglSwapIntervalEXT "
|
|
||||||
"vblank setup failed");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
CLUTTER_NOTE (BACKEND, "no use-able vblank mechanism found");
|
{
|
||||||
|
CLUTTER_NOTE (BACKEND, "Cogl only supports one onscreen framebuffer");
|
||||||
|
flags |= CLUTTER_FEATURE_STAGE_STATIC;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_SWAP_THROTTLE))
|
||||||
|
{
|
||||||
|
CLUTTER_NOTE (BACKEND, "Cogl supports swap buffers throttling");
|
||||||
|
flags |= CLUTTER_FEATURE_SYNC_TO_VBLANK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
CLUTTER_NOTE (BACKEND, "Cogl doesn't support swap buffers throttling");
|
||||||
|
|
||||||
CLUTTER_NOTE (BACKEND, "backend features checked");
|
CLUTTER_NOTE (BACKEND, "backend features checked");
|
||||||
|
|
||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ATOM
|
|
||||||
clutter_backend_win32_get_dummy_window_class ()
|
|
||||||
{
|
|
||||||
static ATOM klass = 0;
|
|
||||||
|
|
||||||
if (klass == 0)
|
|
||||||
{
|
|
||||||
WNDCLASSW wndclass;
|
|
||||||
memset (&wndclass, 0, sizeof (wndclass));
|
|
||||||
wndclass.lpfnWndProc = DefWindowProc;
|
|
||||||
wndclass.hInstance = GetModuleHandleW (NULL);
|
|
||||||
wndclass.lpszClassName = L"ClutterBackendWin32DummyWindow";
|
|
||||||
klass = RegisterClassW (&wndclass);
|
|
||||||
}
|
|
||||||
|
|
||||||
return klass;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
clutter_backend_win32_pixel_format_is_better (const PIXELFORMATDESCRIPTOR *pfa,
|
|
||||||
const PIXELFORMATDESCRIPTOR *pfb)
|
|
||||||
{
|
|
||||||
/* Always prefer a format with a stencil buffer */
|
|
||||||
if (pfa->cStencilBits == 0)
|
|
||||||
{
|
|
||||||
if (pfb->cStencilBits > 0)
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
else if (pfb->cStencilBits == 0)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
/* Prefer a bigger color buffer */
|
|
||||||
if (pfb->cColorBits > pfa->cColorBits)
|
|
||||||
return TRUE;
|
|
||||||
else if (pfb->cColorBits < pfa->cColorBits)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
/* Prefer a bigger depth buffer */
|
|
||||||
return pfb->cDepthBits > pfa->cDepthBits;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
clutter_backend_win32_choose_pixel_format (HDC dc, PIXELFORMATDESCRIPTOR *pfd)
|
|
||||||
{
|
|
||||||
int i, num_formats, best_pf = 0;
|
|
||||||
PIXELFORMATDESCRIPTOR best_pfd;
|
|
||||||
|
|
||||||
num_formats = DescribePixelFormat (dc, 0, sizeof (best_pfd), NULL);
|
|
||||||
|
|
||||||
for (i = 1; i <= num_formats; i++)
|
|
||||||
{
|
|
||||||
memset (pfd, 0, sizeof (*pfd));
|
|
||||||
|
|
||||||
if (DescribePixelFormat (dc, i, sizeof (best_pfd), pfd)
|
|
||||||
/* Check whether this format is useable by Clutter */
|
|
||||||
&& ((pfd->dwFlags & (PFD_SUPPORT_OPENGL
|
|
||||||
| PFD_DRAW_TO_WINDOW
|
|
||||||
| PFD_DOUBLEBUFFER
|
|
||||||
| PFD_GENERIC_FORMAT))
|
|
||||||
== (PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_DRAW_TO_WINDOW))
|
|
||||||
&& pfd->iPixelType == PFD_TYPE_RGBA
|
|
||||||
&& pfd->cColorBits >= 16 && pfd->cColorBits <= 32
|
|
||||||
&& pfd->cDepthBits >= 16 && pfd->cDepthBits <= 32
|
|
||||||
/* Check whether this is a better format than one we've
|
|
||||||
already found */
|
|
||||||
&& (best_pf == 0
|
|
||||||
|| clutter_backend_win32_pixel_format_is_better (&best_pfd, pfd)))
|
|
||||||
{
|
|
||||||
best_pf = i;
|
|
||||||
best_pfd = *pfd;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*pfd = best_pfd;
|
|
||||||
|
|
||||||
return best_pf;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
clutter_backend_win32_create_context (ClutterBackend *backend,
|
clutter_backend_win32_create_context (ClutterBackend *backend,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
ClutterBackendWin32 *backend_win32 = CLUTTER_BACKEND_WIN32 (backend);
|
CoglSwapChain *swap_chain;
|
||||||
|
CoglOnscreenTemplate *onscreen_template;
|
||||||
|
|
||||||
/* COGL assumes that there is always a GL context selected; in order
|
if (backend->cogl_context)
|
||||||
* to make sure that a WGL context exists and is made current, we
|
return TRUE;
|
||||||
* use a small dummy window that never gets shown to which we can
|
|
||||||
* always fall back if no stage is available
|
|
||||||
*/
|
|
||||||
if (backend_win32->dummy_hwnd == NULL)
|
|
||||||
{
|
|
||||||
ATOM window_class = clutter_backend_win32_get_dummy_window_class ();
|
|
||||||
|
|
||||||
if (window_class == 0)
|
backend->cogl_renderer = cogl_renderer_new ();
|
||||||
{
|
if (!cogl_renderer_connect (backend->cogl_renderer, error))
|
||||||
g_critical ("Unable to register window class");
|
goto error;
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
backend_win32->dummy_hwnd =
|
swap_chain = cogl_swap_chain_new ();
|
||||||
CreateWindowW ((LPWSTR) MAKEINTATOM (window_class),
|
|
||||||
L".",
|
|
||||||
WS_OVERLAPPEDWINDOW,
|
|
||||||
CW_USEDEFAULT,
|
|
||||||
CW_USEDEFAULT,
|
|
||||||
1, 1,
|
|
||||||
NULL, NULL,
|
|
||||||
GetModuleHandle (NULL),
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (backend_win32->dummy_hwnd == NULL)
|
onscreen_template = cogl_onscreen_template_new (swap_chain);
|
||||||
{
|
cogl_object_unref (swap_chain);
|
||||||
g_critical ("Unable to create dummy window");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (backend_win32->dummy_dc == NULL)
|
if (!cogl_renderer_check_onscreen_template (backend->cogl_renderer,
|
||||||
{
|
onscreen_template,
|
||||||
PIXELFORMATDESCRIPTOR pfd;
|
error))
|
||||||
int pf;
|
goto error;
|
||||||
|
|
||||||
backend_win32->dummy_dc = GetDC (backend_win32->dummy_hwnd);
|
backend->cogl_display = cogl_display_new (backend->cogl_renderer,
|
||||||
|
onscreen_template);
|
||||||
|
cogl_object_unref (backend->cogl_renderer);
|
||||||
|
cogl_object_unref (onscreen_template);
|
||||||
|
|
||||||
pf = clutter_backend_win32_choose_pixel_format (backend_win32->dummy_dc,
|
if (!cogl_display_setup (backend->cogl_display, error))
|
||||||
&pfd);
|
goto error;
|
||||||
|
|
||||||
if (pf == 0 || !SetPixelFormat (backend_win32->dummy_dc, pf, &pfd))
|
backend->cogl_context = cogl_context_new (backend->cogl_display, error);
|
||||||
{
|
if (!backend->cogl_context)
|
||||||
g_critical ("Unable to find suitable GL pixel format");
|
goto error;
|
||||||
ReleaseDC (backend_win32->dummy_hwnd, backend_win32->dummy_dc);
|
|
||||||
backend_win32->dummy_dc = NULL;
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (backend_win32->gl_context == NULL)
|
/* XXX: eventually this should go away but a lot of Cogl code still
|
||||||
{
|
* depends on a global default context. */
|
||||||
backend_win32->gl_context = wglCreateContext (backend_win32->dummy_dc);
|
cogl_set_default_context (backend->cogl_context);
|
||||||
|
|
||||||
if (backend_win32->gl_context == NULL)
|
|
||||||
{
|
|
||||||
g_critical ("Unable to create suitable GL context");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CLUTTER_NOTE (BACKEND, "Selecting dummy 0x%x for the WGL context",
|
|
||||||
(unsigned int) backend_win32->dummy_hwnd);
|
|
||||||
|
|
||||||
wglMakeCurrent (backend_win32->dummy_dc, backend_win32->gl_context);
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
error:
|
||||||
|
if (backend->cogl_display)
|
||||||
|
{
|
||||||
|
cogl_object_unref (backend->cogl_display);
|
||||||
|
backend->cogl_display = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (onscreen_template)
|
||||||
|
cogl_object_unref (onscreen_template);
|
||||||
|
if (swap_chain)
|
||||||
|
cogl_object_unref (swap_chain);
|
||||||
|
|
||||||
|
if (backend->cogl_renderer)
|
||||||
|
{
|
||||||
|
cogl_object_unref (backend->cogl_renderer);
|
||||||
|
backend->cogl_renderer = NULL;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_backend_win32_ensure_context (ClutterBackend *backend,
|
clutter_backend_win32_ensure_context (ClutterBackend *backend,
|
||||||
ClutterStage *stage)
|
ClutterStage *stage)
|
||||||
{
|
{
|
||||||
ClutterStageWindow *impl;
|
ClutterStageWin32 *stage_win32 =
|
||||||
|
CLUTTER_STAGE_WIN32 (_clutter_stage_get_window (stage));
|
||||||
|
|
||||||
if (stage == NULL ||
|
cogl_set_framebuffer (COGL_FRAMEBUFFER (stage_win32->onscreen));
|
||||||
CLUTTER_ACTOR_IN_DESTRUCTION (stage) ||
|
|
||||||
((impl = _clutter_stage_get_window (stage)) == NULL))
|
|
||||||
{
|
|
||||||
CLUTTER_NOTE (MULTISTAGE, "Clearing all context");
|
|
||||||
|
|
||||||
wglMakeCurrent (NULL, NULL);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ClutterBackendWin32 *backend_win32;
|
|
||||||
ClutterStageWin32 *stage_win32;
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
backend_win32 = CLUTTER_BACKEND_WIN32 (backend);
|
|
||||||
stage_win32 = CLUTTER_STAGE_WIN32 (impl);
|
|
||||||
|
|
||||||
/* 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");
|
|
||||||
|
|
||||||
if (backend_win32->dummy_dc != NULL)
|
|
||||||
wglMakeCurrent (backend_win32->dummy_dc,
|
|
||||||
backend_win32->gl_context);
|
|
||||||
else
|
|
||||||
wglMakeCurrent (NULL, NULL);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CLUTTER_NOTE (BACKEND,
|
|
||||||
"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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static ClutterStageWindow *
|
static ClutterStageWindow *
|
||||||
@ -558,7 +369,6 @@ clutter_backend_win32_class_init (ClutterBackendWin32Class *klass)
|
|||||||
static void
|
static void
|
||||||
clutter_backend_win32_init (ClutterBackendWin32 *backend_win32)
|
clutter_backend_win32_init (ClutterBackendWin32 *backend_win32)
|
||||||
{
|
{
|
||||||
backend_win32->gl_context = NULL;
|
|
||||||
backend_win32->invisible_cursor = NULL;
|
backend_win32->invisible_cursor = NULL;
|
||||||
|
|
||||||
/* FIXME: get from GetSystemMetric?
|
/* FIXME: get from GetSystemMetric?
|
||||||
|
@ -46,10 +46,6 @@ struct _ClutterBackendWin32
|
|||||||
{
|
{
|
||||||
ClutterBackend parent_instance;
|
ClutterBackend parent_instance;
|
||||||
|
|
||||||
HGLRC gl_context;
|
|
||||||
HWND dummy_hwnd;
|
|
||||||
HDC dummy_dc;
|
|
||||||
|
|
||||||
HCURSOR invisible_cursor;
|
HCURSOR invisible_cursor;
|
||||||
|
|
||||||
GSource *event_source;
|
GSource *event_source;
|
||||||
@ -76,6 +72,8 @@ clutter_backend_win32_get_features (ClutterBackend *backend);
|
|||||||
|
|
||||||
HCURSOR _clutter_backend_win32_get_invisible_cursor (ClutterBackend *backend);
|
HCURSOR _clutter_backend_win32_get_invisible_cursor (ClutterBackend *backend);
|
||||||
|
|
||||||
|
G_CONST_RETURN gchar *_clutter_backend_win32_get_vblank (void);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __CLUTTER_BACKEND_WIN32_H__ */
|
#endif /* __CLUTTER_BACKEND_WIN32_H__ */
|
||||||
|
@ -348,6 +348,7 @@ get_key_modifier_state (const BYTE *key_states)
|
|||||||
gboolean
|
gboolean
|
||||||
clutter_win32_handle_event (const MSG *msg)
|
clutter_win32_handle_event (const MSG *msg)
|
||||||
{
|
{
|
||||||
|
ClutterBackend *backend;
|
||||||
ClutterBackendWin32 *backend_win32;
|
ClutterBackendWin32 *backend_win32;
|
||||||
ClutterStageWin32 *stage_win32;
|
ClutterStageWin32 *stage_win32;
|
||||||
ClutterDeviceManager *manager;
|
ClutterDeviceManager *manager;
|
||||||
@ -365,6 +366,13 @@ clutter_win32_handle_event (const MSG *msg)
|
|||||||
impl = _clutter_stage_get_window (stage);
|
impl = _clutter_stage_get_window (stage);
|
||||||
stage_win32 = CLUTTER_STAGE_WIN32 (impl);
|
stage_win32 = CLUTTER_STAGE_WIN32 (impl);
|
||||||
backend_win32 = stage_win32->backend;
|
backend_win32 = stage_win32->backend;
|
||||||
|
backend = CLUTTER_BACKEND (backend_win32);
|
||||||
|
|
||||||
|
/* Give Cogl a chance to handle the message first */
|
||||||
|
if (backend->cogl_renderer != NULL &&
|
||||||
|
cogl_renderer_handle_native_event (backend->cogl_renderer,
|
||||||
|
(void *) msg) == COGL_FILTER_REMOVE)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
manager = clutter_device_manager_get_default ();
|
manager = clutter_device_manager_get_default ();
|
||||||
core_pointer =
|
core_pointer =
|
||||||
|
@ -392,14 +392,24 @@ static gboolean
|
|||||||
clutter_stage_win32_realize (ClutterStageWindow *stage_window)
|
clutter_stage_win32_realize (ClutterStageWindow *stage_window)
|
||||||
{
|
{
|
||||||
ClutterStageWin32 *stage_win32 = CLUTTER_STAGE_WIN32 (stage_window);
|
ClutterStageWin32 *stage_win32 = CLUTTER_STAGE_WIN32 (stage_window);
|
||||||
|
ClutterBackend *backend;
|
||||||
ClutterBackendWin32 *backend_win32;
|
ClutterBackendWin32 *backend_win32;
|
||||||
PIXELFORMATDESCRIPTOR pfd;
|
CoglFramebuffer *framebuffer;
|
||||||
int pf;
|
gfloat width;
|
||||||
|
gfloat height;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
const char *clutter_vblank;
|
||||||
|
|
||||||
CLUTTER_NOTE (MISC, "Realizing main stage");
|
CLUTTER_NOTE (MISC, "Realizing main stage");
|
||||||
|
|
||||||
backend_win32 = CLUTTER_BACKEND_WIN32 (clutter_get_default_backend ());
|
backend = CLUTTER_BACKEND (stage_win32->backend);
|
||||||
|
backend_win32 = CLUTTER_BACKEND_WIN32 (backend);
|
||||||
|
|
||||||
|
clutter_actor_get_size (CLUTTER_ACTOR (stage_win32->wrapper),
|
||||||
|
&width, &height);
|
||||||
|
|
||||||
|
stage_win32->onscreen = cogl_onscreen_new (backend->cogl_context,
|
||||||
|
width, height);
|
||||||
|
|
||||||
if (stage_win32->hwnd == NULL)
|
if (stage_win32->hwnd == NULL)
|
||||||
{
|
{
|
||||||
@ -457,10 +467,22 @@ clutter_stage_win32_realize (ClutterStageWindow *stage_window)
|
|||||||
SetWindowLongPtrW (stage_win32->hwnd, 0, (LONG_PTR) stage_win32);
|
SetWindowLongPtrW (stage_win32->hwnd, 0, (LONG_PTR) stage_win32);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stage_win32->client_dc)
|
cogl_onscreen_win32_set_foreign_window (stage_win32->onscreen,
|
||||||
ReleaseDC (stage_win32->hwnd, stage_win32->client_dc);
|
stage_win32->hwnd);
|
||||||
|
|
||||||
stage_win32->client_dc = GetDC (stage_win32->hwnd);
|
clutter_vblank = _clutter_backend_win32_get_vblank ();
|
||||||
|
if (clutter_vblank && strcmp (clutter_vblank, "none") == 0)
|
||||||
|
cogl_onscreen_set_swap_throttled (stage_win32->onscreen, FALSE);
|
||||||
|
|
||||||
|
framebuffer = COGL_FRAMEBUFFER (stage_win32->onscreen);
|
||||||
|
if (!cogl_framebuffer_allocate (framebuffer, &error))
|
||||||
|
{
|
||||||
|
g_warning ("Failed to allocate stage: %s", error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
cogl_object_unref (stage_win32->onscreen);
|
||||||
|
stage_win32->onscreen = NULL;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
/* Create a context. This will be a no-op if we already have one */
|
/* Create a context. This will be a no-op if we already have one */
|
||||||
if (!_clutter_backend_create_context (CLUTTER_BACKEND (backend_win32),
|
if (!_clutter_backend_create_context (CLUTTER_BACKEND (backend_win32),
|
||||||
@ -471,15 +493,6 @@ clutter_stage_win32_realize (ClutterStageWindow *stage_window)
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Use the same pixel format as the dummy DC */
|
|
||||||
pf = GetPixelFormat (backend_win32->dummy_dc);
|
|
||||||
DescribePixelFormat (backend_win32->dummy_dc, pf, sizeof (pfd), &pfd);
|
|
||||||
if (!SetPixelFormat (stage_win32->client_dc, pf, &pfd))
|
|
||||||
{
|
|
||||||
g_critical ("Unable to find suitable GL pixel format");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
CLUTTER_NOTE (BACKEND, "Successfully realized stage");
|
CLUTTER_NOTE (BACKEND, "Successfully realized stage");
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -491,12 +504,6 @@ clutter_stage_win32_realize (ClutterStageWindow *stage_window)
|
|||||||
static void
|
static void
|
||||||
clutter_stage_win32_unprepare_window (ClutterStageWin32 *stage_win32)
|
clutter_stage_win32_unprepare_window (ClutterStageWin32 *stage_win32)
|
||||||
{
|
{
|
||||||
if (stage_win32->client_dc)
|
|
||||||
{
|
|
||||||
ReleaseDC (stage_win32->hwnd, stage_win32->client_dc);
|
|
||||||
stage_win32->client_dc = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!stage_win32->is_foreign_win && 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
|
||||||
@ -527,8 +534,8 @@ clutter_stage_win32_redraw (ClutterStageWindow *stage_window)
|
|||||||
_clutter_stage_do_paint (stage_win32->wrapper, NULL);
|
_clutter_stage_do_paint (stage_win32->wrapper, NULL);
|
||||||
cogl_flush ();
|
cogl_flush ();
|
||||||
|
|
||||||
if (stage_win32->client_dc)
|
if (stage_win32->onscreen)
|
||||||
SwapBuffers (stage_win32->client_dc);
|
cogl_framebuffer_swap_buffers (COGL_FRAMEBUFFER (stage_win32->onscreen));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -543,7 +550,10 @@ clutter_stage_win32_dispose (GObject *gobject)
|
|||||||
clutter_stage_win32_unprepare_window (stage_win32);
|
clutter_stage_win32_unprepare_window (stage_win32);
|
||||||
|
|
||||||
if (stage_win32->wtitle)
|
if (stage_win32->wtitle)
|
||||||
g_free (stage_win32->wtitle);
|
{
|
||||||
|
g_free (stage_win32->wtitle);
|
||||||
|
stage_win32->wtitle = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
G_OBJECT_CLASS (clutter_stage_win32_parent_class)->dispose (gobject);
|
G_OBJECT_CLASS (clutter_stage_win32_parent_class)->dispose (gobject);
|
||||||
}
|
}
|
||||||
@ -560,7 +570,6 @@ static void
|
|||||||
clutter_stage_win32_init (ClutterStageWin32 *stage)
|
clutter_stage_win32_init (ClutterStageWin32 *stage)
|
||||||
{
|
{
|
||||||
stage->hwnd = NULL;
|
stage->hwnd = NULL;
|
||||||
stage->client_dc = NULL;
|
|
||||||
stage->win_width = 640;
|
stage->win_width = 640;
|
||||||
stage->win_height = 480;
|
stage->win_height = 480;
|
||||||
stage->backend = NULL;
|
stage->backend = NULL;
|
||||||
|
@ -44,8 +44,9 @@ struct _ClutterStageWin32
|
|||||||
{
|
{
|
||||||
ClutterGroup parent_instance;
|
ClutterGroup parent_instance;
|
||||||
|
|
||||||
|
CoglOnscreen *onscreen;
|
||||||
|
|
||||||
HWND hwnd;
|
HWND hwnd;
|
||||||
HDC client_dc;
|
|
||||||
gint win_width;
|
gint win_width;
|
||||||
gint win_height;
|
gint win_height;
|
||||||
gint scroll_pos;
|
gint scroll_pos;
|
||||||
|
Loading…
Reference in New Issue
Block a user