[Cogl] [PATCH 1/3] win32: Automatically process windows messages when using a GMainLoop
Robert Bragg
robert at sixbynine.org
Tue May 28 03:35:03 PDT 2013
This looks good to land to me:
Reviewed-by: Robert Bragg <robert at linux.intel.com>
thanks,
- Robert
On Tue, May 14, 2013 at 5:03 PM, Neil Roberts <neil at linux.intel.com> wrote:
> Previously the WGL winsys was expecting the application to send all
> windows messages to Cogl via the cogl_win32_renderer_handle_event
> function. When using a GLib main loop we can make this work
> transparently to the application with a GSource for the magic
> G_WIN32_MSG_HANDLE file descriptor. That causes the GMainLoop to wake
> up whenever a message is available.
>
> This patch makes the WGL winsys add that magic value as a source fd.
> This will only have any meaning if the application is using glib, but
> it shouldn't matter because the cogl_poll_renderer_get_info function
> is documented to only work on Unix-based winsys's anyway.
>
> This patch is an API break because by default Cogl will now start
> stealing all of the Windows messages. Something like Clutter that wants to handle
> its own event retrieval would now need to call
> cogl_win32_renderer_set_event_retrieval_enabled to stop Cogl from
> stealing the events.
> ---
> cogl/cogl-renderer-private.h | 4 ++++
> cogl/cogl-renderer.c | 4 ++++
> cogl/cogl-win32-renderer.c | 10 ++++++++
> cogl/cogl-win32-renderer.h | 19 +++++++++++++++
> cogl/winsys/cogl-winsys-wgl.c | 42 ++++++++++++++++++++++++++++++++++
> doc/reference/cogl2/cogl2-sections.txt | 1 +
> 6 files changed, 80 insertions(+)
>
> diff --git a/cogl/cogl-renderer-private.h b/cogl/cogl-renderer-private.h
> index e71e8b9..62aca7e 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 9cbb894..bfd91cd 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 ad7e791..89094cb 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 e9747da..a144c74 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 df82a5d..ecaf346 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);
>
> @@ -232,11 +240,45 @@ win32_event_filter_cb (MSG *msg, void *data)
> }
>
> 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/cogl2/cogl2-sections.txt b/doc/reference/cogl2/cogl2-sections.txt
> index 68769bd..59f40bd 100644
> --- a/doc/reference/cogl2/cogl2-sections.txt
> +++ b/doc/reference/cogl2/cogl2-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
>
> <SUBSECTION>
> cogl_wayland_renderer_set_foreign_display
> --
> 1.7.11.3.g3c3efa5
>
> _______________________________________________
> Cogl mailing list
> Cogl at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/cogl
More information about the Cogl
mailing list