diff --git a/cogl/cogl-renderer-private.h b/cogl/cogl-renderer-private.h index e71e8b9b7..62aca7e3c 100644 --- a/cogl/cogl-renderer-private.h +++ b/cogl/cogl-renderer-private.h @@ -65,6 +65,10 @@ struct _CoglRenderer CoglBool xlib_enable_event_retrieval; #endif +#ifdef COGL_HAS_WIN32_SUPPORT + CoglBool win32_enable_event_retrieval; +#endif + CoglDriver driver; #ifndef HAVE_DIRECTLY_LINKED_GL_LIBRARY GModule *libgl_module; diff --git a/cogl/cogl-renderer.c b/cogl/cogl-renderer.c index bcdbd10f5..1e3471440 100644 --- a/cogl/cogl-renderer.c +++ b/cogl/cogl-renderer.c @@ -193,6 +193,10 @@ cogl_renderer_new (void) renderer->xlib_enable_event_retrieval = TRUE; #endif +#ifdef COGL_HAS_WIN32_SUPPORT + renderer->win32_enable_event_retrieval = TRUE; +#endif + return _cogl_renderer_object_new (renderer); } diff --git a/cogl/cogl-win32-renderer.c b/cogl/cogl-win32-renderer.c index ad7e7912b..89094cb7c 100644 --- a/cogl/cogl-win32-renderer.c +++ b/cogl/cogl-win32-renderer.c @@ -56,3 +56,13 @@ cogl_win32_renderer_remove_filter (CoglRenderer *renderer, (CoglNativeFilterFunc)func, data); } +void +cogl_win32_renderer_set_event_retrieval_enabled (CoglRenderer *renderer, + CoglBool enable) +{ + _COGL_RETURN_IF_FAIL (cogl_is_renderer (renderer)); + /* NB: Renderers are considered immutable once connected */ + _COGL_RETURN_IF_FAIL (!renderer->connected); + + renderer->win32_enable_event_retrieval = enable; +} diff --git a/cogl/cogl-win32-renderer.h b/cogl/cogl-win32-renderer.h index e9747daf3..a144c74db 100644 --- a/cogl/cogl-win32-renderer.h +++ b/cogl/cogl-win32-renderer.h @@ -94,6 +94,25 @@ cogl_win32_renderer_remove_filter (CoglRenderer *renderer, CoglWin32FilterFunc func, void *data); +/** + * cogl_win32_renderer_set_event_retrieval_enabled: + * @renderer: a #CoglRenderer + * @enable: The new value + * + * Sets whether Cogl should automatically retrieve messages from + * Windows. It defaults to %TRUE. It can be set to %FALSE if the + * application wants to handle its own message retrieval. Note that + * Cogl still needs to see all of the messages to function properly so + * the application should call cogl_win32_renderer_handle_event() for + * each message if it disables automatic event retrieval. + * + * Since: 1.16 + * Stability: unstable + */ +void +cogl_win32_renderer_set_event_retrieval_enabled (CoglRenderer *renderer, + CoglBool enable); + COGL_END_DECLS #endif /* __COGL_WIN32_RENDERER_H__ */ diff --git a/cogl/winsys/cogl-winsys-wgl.c b/cogl/winsys/cogl-winsys-wgl.c index ce2e97c36..b0b1b9a8f 100644 --- a/cogl/winsys/cogl-winsys-wgl.c +++ b/cogl/winsys/cogl-winsys-wgl.c @@ -46,6 +46,11 @@ #include "cogl-win32-renderer.h" #include "cogl-winsys-wgl-private.h" #include "cogl-error-private.h" +#include "cogl-poll-private.h" + +/* This magic handle will cause g_poll to wakeup when there is a + * pending message */ +#define WIN32_MSG_HANDLE 19981206 typedef struct _CoglRendererWgl { @@ -161,6 +166,9 @@ _cogl_winsys_renderer_disconnect (CoglRenderer *renderer) { CoglRendererWgl *wgl_renderer = renderer->winsys; + if (renderer->win32_enable_event_retrieval) + _cogl_poll_renderer_remove_fd (renderer, WIN32_MSG_HANDLE); + if (wgl_renderer->gl_module) g_module_close (wgl_renderer->gl_module); @@ -231,12 +239,46 @@ win32_event_filter_cb (MSG *msg, void *data) return COGL_FILTER_CONTINUE; } +static CoglBool +check_messages (void *user_data) +{ + MSG msg; + + return PeekMessageW (&msg, NULL, 0, 0, PM_NOREMOVE) ? TRUE : FALSE; +} + +static void +dispatch_messages (void *user_data) +{ + MSG msg; + + while (PeekMessageW (&msg, NULL, 0, 0, PM_REMOVE)) + /* This should cause the message to be sent to our window proc */ + DispatchMessageW (&msg); +} + static CoglBool _cogl_winsys_renderer_connect (CoglRenderer *renderer, CoglError **error) { renderer->winsys = g_slice_new0 (CoglRendererWgl); + if (renderer->win32_enable_event_retrieval) + { + /* We'll add a magic handle that will cause a GLib main loop to + * wake up when there are messages. This will only work if the + * application is using GLib but it shouldn't matter if it + * doesn't work in other cases because the application shouldn't + * be using the cogl_poll_* functions on non-Unix systems + * anyway */ + _cogl_poll_renderer_add_fd (renderer, + WIN32_MSG_HANDLE, + COGL_POLL_FD_EVENT_IN, + check_messages, + dispatch_messages, + renderer); + } + return TRUE; } diff --git a/doc/reference/cogl-2.0-experimental/cogl-2.0-experimental-sections.txt b/doc/reference/cogl-2.0-experimental/cogl-2.0-experimental-sections.txt index 7a9469595..e97ea21a6 100644 --- a/doc/reference/cogl-2.0-experimental/cogl-2.0-experimental-sections.txt +++ b/doc/reference/cogl-2.0-experimental/cogl-2.0-experimental-sections.txt @@ -85,6 +85,7 @@ CoglWin32FilterFunc cogl_win32_renderer_add_filter cogl_win32_renderer_remove_filter cogl_win32_renderer_handle_event +cogl_win32_renderer_set_event_retrieval_enabled cogl_wayland_renderer_set_foreign_display