[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