1
0
mirror of https://github.com/brl/mutter.git synced 2025-04-10 20:29:38 +00:00

replace public native_event APIs with typesafe APIs

This adds Xlib and Win32 typesafe replacements for
cogl_renderer_handle_native_event, cogl_renderer_add_native_filter,
cogl_renderer_remove_native_filter. The old functions are kept as an
implementation detail so we can share code.

Signed-off-by: Neil Roberts <neil@linux.intel.com>
This commit is contained in:
Robert Bragg 2011-06-28 13:38:50 +01:00
parent f0a28f4287
commit 3b64a439f0
14 changed files with 250 additions and 96 deletions

@ -332,6 +332,7 @@ cogl_sources_c += \
endif endif
if SUPPORT_WGL if SUPPORT_WGL
cogl_sources_c += \ cogl_sources_c += \
$(srcdir)/cogl-win32-renderer.c \
$(srcdir)/winsys/cogl-winsys-wgl.c \ $(srcdir)/winsys/cogl-winsys-wgl.c \
$(srcdir)/winsys/cogl-winsys-wgl-feature-functions.h $(srcdir)/winsys/cogl-winsys-wgl-feature-functions.h
endif endif

@ -53,4 +53,21 @@ struct _CoglRenderer
void *winsys; void *winsys;
}; };
typedef CoglFilterReturn (* CoglNativeFilterFunc) (void *native_event,
void *data);
CoglFilterReturn
_cogl_renderer_handle_native_event (CoglRenderer *renderer,
void *event);
void
_cogl_renderer_add_native_filter (CoglRenderer *renderer,
CoglNativeFilterFunc func,
void *data);
void
_cogl_renderer_remove_native_filter (CoglRenderer *renderer,
CoglNativeFilterFunc func,
void *data);
#endif /* __COGL_RENDERER_PRIVATE_H */ #endif /* __COGL_RENDERER_PRIVATE_H */

@ -198,3 +198,29 @@ cogl_renderer_xlib_get_display (CoglRenderer *renderer)
return xlib_renderer->xdpy; return xlib_renderer->xdpy;
} }
CoglFilterReturn
cogl_xlib_renderer_handle_event (CoglRenderer *renderer,
XEvent *event)
{
return _cogl_renderer_handle_native_event (renderer, event);
}
void
cogl_xlib_renderer_add_filter (CoglRenderer *renderer,
CoglXlibFilterFunc func,
void *data)
{
_cogl_renderer_add_native_filter (renderer,
(CoglNativeFilterFunc)func, data);
}
void
cogl_xlib_renderer_remove_filter (CoglRenderer *renderer,
CoglXlibFilterFunc func,
void *data)
{
_cogl_renderer_remove_native_filter (renderer,
(CoglNativeFilterFunc)func, data);
}

@ -229,8 +229,8 @@ cogl_renderer_connect (CoglRenderer *renderer, GError **error)
} }
CoglFilterReturn CoglFilterReturn
cogl_renderer_handle_native_event (CoglRenderer *renderer, _cogl_renderer_handle_native_event (CoglRenderer *renderer,
void *event) void *event)
{ {
GSList *l, *next; GSList *l, *next;
@ -254,9 +254,9 @@ cogl_renderer_handle_native_event (CoglRenderer *renderer,
} }
void void
cogl_renderer_add_native_filter (CoglRenderer *renderer, _cogl_renderer_add_native_filter (CoglRenderer *renderer,
CoglNativeFilterFunc func, CoglNativeFilterFunc func,
void *data) void *data)
{ {
CoglNativeFilterClosure *closure; CoglNativeFilterClosure *closure;
@ -268,9 +268,9 @@ cogl_renderer_add_native_filter (CoglRenderer *renderer,
} }
void void
cogl_renderer_remove_native_filter (CoglRenderer *renderer, _cogl_renderer_remove_native_filter (CoglRenderer *renderer,
CoglNativeFilterFunc func, CoglNativeFilterFunc func,
void *data) void *data)
{ {
GSList *l, *prev = NULL; GSList *l, *prev = NULL;

@ -122,17 +122,17 @@ cogl_renderer_set_winsys_id (CoglRenderer *renderer,
CoglWinsysID CoglWinsysID
cogl_renderer_get_winsys_id (CoglRenderer *renderer); cogl_renderer_get_winsys_id (CoglRenderer *renderer);
#define cogl_renderer_handle_native_event cogl_renderer_handle_native_event_EXP #ifdef COGL_HAS_XLIB
#define cogl_xlib_renderer_handle_event \
cogl_xlib_renderer_handle_event_EXP
/* /*
* cogl_renderer_handle_native_event: * cogl_xlib_renderer_handle_event:
* @event: pointer to native event structure * @event: pointer to an XEvent structure
* *
* This function processes a single event; it can be used to hook into * This function processes a single event; it can be used to hook into
* external event retrieval (for example that done by Clutter or * external event retrieval (for example that done by Clutter or
* GDK). The type of the structure that event points to depends on the * GDK).
* window system used for the renderer. On an xlib renderer it would
* be a pointer to an XEvent or an a Windows renderer it would be a
* pointer to a MSG struct.
* *
* Return value: #CoglFilterReturn. %COGL_FILTER_REMOVE indicates that * Return value: #CoglFilterReturn. %COGL_FILTER_REMOVE indicates that
* Cogl has internally handled the event and the caller should do no * Cogl has internally handled the event and the caller should do no
@ -141,38 +141,47 @@ cogl_renderer_get_winsys_id (CoglRenderer *renderer);
* internal state without taking any exclusive action. * internal state without taking any exclusive action.
*/ */
CoglFilterReturn CoglFilterReturn
cogl_renderer_handle_native_event (CoglRenderer *renderer, cogl_xlib_renderer_handle_event (CoglRenderer *renderer,
void *event); XEvent *event);
#define cogl_renderer_add_native_filter cogl_renderer_add_native_filter_EXP
/* /*
* cogl_renderer_add_native_filter: * CoglXlibFilterFunc:
* @event: pointer to an XEvent structure
* @data: The data that was given when the filter was added
*
* A callback function that can be registered with
* cogl_xlib_renderer_add_filter(). The function should return
* %COGL_FILTER_REMOVE if it wants to prevent further processing or
* %COGL_FILTER_CONTINUE otherwise.
*/
typedef CoglFilterReturn (* CoglXlibFilterFunc) (XEvent *event,
void *data);
#define cogl_xlib_renderer_add_filter cogl_xlib_renderer_add_filter_EXP
/*
* cogl_xlib_renderer_add_filter:
* *
* Adds a callback function that will receive all native events. The * Adds a callback function that will receive all native events. The
* function can stop further processing of the event by return * function can stop further processing of the event by return
* %COGL_FILTER_REMOVE. What is considered a native event depends on * %COGL_FILTER_REMOVE.
* the type of renderer used. An xlib based renderer would pass all
* XEvents whereas a Windows based renderer would pass MSGs.
*/ */
void void
cogl_renderer_add_native_filter (CoglRenderer *renderer, cogl_xlib_renderer_add_filter (CoglRenderer *renderer,
CoglNativeFilterFunc func, CoglXlibFilterFunc func,
void *data); void *data);
#define cogl_renderer_remove_native_filter \ #define cogl_xlib_renderer_remove_filter \
cogl_renderer_remove_native_filter_EXP cogl_xlib_renderer_remove_filter_EXP
/* /*
* cogl_renderer_remove_native_filter: * cogl_xlib_renderer_remove_filter:
* *
* Removes a callback that was previously added with * Removes a callback that was previously added with
* cogl_renderer_add_native_filter(). * cogl_xlib_renderer_add_filter().
*/ */
void void
cogl_renderer_remove_native_filter (CoglRenderer *renderer, cogl_xlib_renderer_remove_filter (CoglRenderer *renderer,
CoglNativeFilterFunc func, CoglXlibFilterFunc func,
void *data); void *data);
#ifdef COGL_HAS_XLIB
#define cogl_renderer_xlib_get_foreign_display \ #define cogl_renderer_xlib_get_foreign_display \
cogl_renderer_xlib_get_foreign_display_EXP cogl_renderer_xlib_get_foreign_display_EXP
@ -228,6 +237,68 @@ struct wl_compositor *
cogl_renderer_wayland_get_compositor (CoglRenderer *renderer); cogl_renderer_wayland_get_compositor (CoglRenderer *renderer);
#endif /* COGL_HAS_EGL_PLATFORM_WAYLAND_SUPPORT */ #endif /* COGL_HAS_EGL_PLATFORM_WAYLAND_SUPPORT */
#ifdef COGL_HAS_WGL_SUPPORT
#define cogl_win32_renderer_handle_event \
cogl_win32_renderer_handle_event_EXP
/*
* cogl_win32_renderer_handle_event:
* @message: A pointer to a win32 MSG struct
*
* This function processes a single event; it can be used to hook into
* external event retrieval (for example that done by Clutter or
* GDK).
*
* Return value: #CoglFilterReturn. %COGL_FILTER_REMOVE indicates that
* Cogl has internally handled the event and the caller should do no
* further processing. %COGL_FILTER_CONTINUE indicates that Cogl is
* either not interested in the event, or has used the event to update
* internal state without taking any exclusive action.
*/
CoglFilterReturn
cogl_win32_renderer_handle_event (CoglRenderer *renderer,
MSG *message);
/*
* CoglXlibFilterFunc:
* @message: A pointer to a win32 MSG struct
* @data: The data that was given when the filter was added
*
* A callback function that can be registered with
* cogl_win32_renderer_add_filter(). The function should return
* %COGL_FILTER_REMOVE if it wants to prevent further processing or
* %COGL_FILTER_CONTINUE otherwise.
*/
typedef CoglFilterReturn (* CoglWin32FilterFunc) (MSG *message,
void *data);
#define cogl_win32_renderer_add_filter cogl_win32_renderer_add_filter_EXP
/*
* cogl_win32_renderer_add_filter:
*
* Adds a callback function that will receive all native events. The
* function can stop further processing of the event by return
* %COGL_FILTER_REMOVE.
*/
void
cogl_win32_renderer_add_filter (CoglRenderer *renderer,
CoglWin32FilterFunc func,
void *data);
#define cogl_win32_renderer_remove_filter \
cogl_win32_renderer_remove_filter_EXP
/*
* cogl_win32_renderer_remove_filter:
*
* Removes a callback that was previously added with
* cogl_win32_renderer_add_filter().
*/
void
cogl_win32_renderer_remove_filter (CoglRenderer *renderer,
CoglWin32FilterFunc func,
void *data);
#endif /* COGL_HAS_WGL_SUPPORT */
#define cogl_renderer_check_onscreen_template \ #define cogl_renderer_check_onscreen_template \
cogl_renderer_check_onscreen_template_EXP cogl_renderer_check_onscreen_template_EXP
gboolean gboolean

@ -671,28 +671,6 @@ typedef enum _CoglWinsysFeature
COGL_WINSYS_FEATURE_N_FEATURES COGL_WINSYS_FEATURE_N_FEATURES
} CoglWinsysFeature; } CoglWinsysFeature;
/* XXX: Note these enum types are only referenced by experimental API
* so although they aren't explicitly guarded they are implicitly
* experimental too. */
/*
* CoglNativeFilterFunc:
* @native_event: A pointer to the native system event
* @data: The data that was given when the filter was added
*
* A callback function that can be registered with
* cogl_renderer_add_native_filter(). The function should return
* %COGL_FILTER_REMOVE if it wants to prevent further processing or
* %COGL_FILTER_CONTINUE otherwise.
*
* The type that @native_event points to depends on the type of the
* underlying renderer. On xlib based renderers this would point to an
* XEvent struct and on Windows it would point to a MSG struct.
*/
typedef CoglFilterReturn (* CoglNativeFilterFunc) (void *native_event,
void *data);
G_END_DECLS G_END_DECLS
#endif /* __COGL_TYPES_H__ */ #endif /* __COGL_TYPES_H__ */

@ -0,0 +1,58 @@
/*
* Cogl
*
* An object oriented GL/GLES Abstraction/Utility Layer
*
* Copyright (C) 2011 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* Authors:
* Robert Bragg <robert@linux.intel.com>
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "cogl-renderer-private.h"
#include "cogl-win32-renderer.h"
CoglFilterReturn
cogl_win32_renderer_handle_event (CoglRenderer *renderer,
MSG *event)
{
return _cogl_renderer_handle_native_event (renderer, event);
}
void
cogl_win32_renderer_add_filter (CoglRenderer *renderer,
CoglWin32FilterFunc func,
void *data)
{
_cogl_renderer_add_native_filter (renderer,
(CoglNativeFilterFunc)func, data);
}
void
cogl_win32_renderer_remove_filter (CoglRenderer *renderer,
CoglWin32FilterFunc func,
void *data)
{
_cogl_renderer_remove_native_filter (renderer,
(CoglNativeFilterFunc)func, data);
}

@ -78,7 +78,7 @@ cogl_xlib_handle_event (XEvent *xevent)
_COGL_GET_CONTEXT (ctx, COGL_FILTER_CONTINUE); _COGL_GET_CONTEXT (ctx, COGL_FILTER_CONTINUE);
/* Pass the event on to the renderer */ /* Pass the event on to the renderer */
return cogl_renderer_handle_native_event (ctx->display->renderer, xevent); return cogl_xlib_renderer_handle_event (ctx->display->renderer, xevent);
} }
void void

@ -213,9 +213,8 @@ process_damage_event (CoglTexturePixmapX11 *tex_pixmap,
} }
static CoglFilterReturn static CoglFilterReturn
_cogl_texture_pixmap_x11_filter (void *native_event, void *data) _cogl_texture_pixmap_x11_filter (XEvent *event, void *data)
{ {
XEvent *event = native_event;
CoglTexturePixmapX11 *tex_pixmap = data; CoglTexturePixmapX11 *tex_pixmap = data;
int damage_base; int damage_base;
@ -241,9 +240,9 @@ set_damage_object_internal (CoglContext *ctx,
{ {
if (tex_pixmap->damage) if (tex_pixmap->damage)
{ {
cogl_renderer_remove_native_filter (ctx->display->renderer, cogl_xlib_renderer_remove_filter (ctx->display->renderer,
_cogl_texture_pixmap_x11_filter, _cogl_texture_pixmap_x11_filter,
tex_pixmap); tex_pixmap);
if (tex_pixmap->damage_owned) if (tex_pixmap->damage_owned)
{ {
@ -256,9 +255,9 @@ set_damage_object_internal (CoglContext *ctx,
tex_pixmap->damage_report_level = report_level; tex_pixmap->damage_report_level = report_level;
if (damage) if (damage)
cogl_renderer_add_native_filter (ctx->display->renderer, cogl_xlib_renderer_add_filter (ctx->display->renderer,
_cogl_texture_pixmap_x11_filter, _cogl_texture_pixmap_x11_filter,
tex_pixmap); tex_pixmap);
} }
CoglHandle CoglHandle

@ -252,9 +252,8 @@ find_onscreen_for_xid (CoglContext *context, guint32 xid)
} }
static CoglFilterReturn static CoglFilterReturn
event_filter_cb (void *event, void *data) event_filter_cb (XEvent *event, void *data)
{ {
XEvent *xevent = event;
CoglContext *context = data; CoglContext *context = data;
if (xevent->type == ConfigureNotify) if (xevent->type == ConfigureNotify)
@ -1108,9 +1107,9 @@ _cogl_winsys_context_init (CoglContext *context, GError **error)
context->winsys = g_new0 (CoglContextEGL, 1); context->winsys = g_new0 (CoglContextEGL, 1);
#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT #ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
cogl_renderer_add_native_filter (context->display->renderer, cogl_xlib_renderer_add_filter (context->display->renderer,
event_filter_cb, event_filter_cb,
context); context);
#endif #endif
update_winsys_features (context); update_winsys_features (context);
@ -1121,9 +1120,9 @@ static void
_cogl_winsys_context_deinit (CoglContext *context) _cogl_winsys_context_deinit (CoglContext *context)
{ {
#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT #ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
cogl_renderer_remove_native_filter (context->display->renderer, cogl_xlib_renderer_remove_filter (context->display->renderer,
event_filter_cb, event_filter_cb,
context); context);
#endif #endif
g_free (context->winsys); g_free (context->winsys);
} }

@ -220,9 +220,8 @@ notify_swap_buffers (CoglContext *context, GLXDrawable drawable)
} }
static CoglFilterReturn static CoglFilterReturn
glx_event_filter_cb (void *native_event, void *data) glx_event_filter_cb (XEvent *xevent, void *data)
{ {
XEvent *xevent = native_event;
CoglContext *context = data; CoglContext *context = data;
#ifdef GLX_INTEL_swap_event #ifdef GLX_INTEL_swap_event
CoglRendererGLX *glx_renderer; CoglRendererGLX *glx_renderer;
@ -672,9 +671,9 @@ _cogl_winsys_context_init (CoglContext *context, GError **error)
{ {
context->winsys = g_new0 (CoglContextGLX, 1); context->winsys = g_new0 (CoglContextGLX, 1);
cogl_renderer_add_native_filter (context->display->renderer, cogl_xlib_renderer_add_filter (context->display->renderer,
glx_event_filter_cb, glx_event_filter_cb,
context); context);
update_winsys_features (context); update_winsys_features (context);
return TRUE; return TRUE;
@ -683,9 +682,9 @@ _cogl_winsys_context_init (CoglContext *context, GError **error)
static void static void
_cogl_winsys_context_deinit (CoglContext *context) _cogl_winsys_context_deinit (CoglContext *context)
{ {
cogl_renderer_remove_native_filter (context->display->renderer, cogl_xlib_renderer_remove_filter (context->display->renderer,
glx_event_filter_cb, glx_event_filter_cb,
context); context);
g_free (context->winsys); g_free (context->winsys);
} }

@ -41,6 +41,7 @@
#include "cogl-onscreen-template-private.h" #include "cogl-onscreen-template-private.h"
#include "cogl-private.h" #include "cogl-private.h"
#include "cogl-feature-private.h" #include "cogl-feature-private.h"
#include "cogl-win32-renderer.h"
typedef struct _CoglRendererWgl typedef struct _CoglRendererWgl
{ {
@ -166,9 +167,8 @@ find_onscreen_for_hwnd (CoglContext *context, HWND hwnd)
} }
static CoglFilterReturn static CoglFilterReturn
win32_event_filter_cb (void *native_event, void *data) win32_event_filter_cb (MSG *msg, void *data)
{ {
MSG *msg = native_event;
CoglContext *context = data; CoglContext *context = data;
if (msg->message == WM_SIZE) if (msg->message == WM_SIZE)
@ -217,7 +217,7 @@ window_proc (HWND hwnd, UINT umsg,
the window proc is. We want the application to forward on all the window proc is. We want the application to forward on all
messages through Cogl so that it can have a chance to process messages through Cogl so that it can have a chance to process
them which might mean that that in it's GetMessage loop it could them which might mean that that in it's GetMessage loop it could
call cogl_renderer_handle_native_event for every message. However call cogl_win32_renderer_handle_event for every message. However
the message loop would usually call DispatchMessage as well which the message loop would usually call DispatchMessage as well which
mean this window proc would be invoked and Cogl would see the mean this window proc would be invoked and Cogl would see the
message twice. However we can't just ignore messages in the message twice. However we can't just ignore messages in the
@ -260,7 +260,7 @@ window_proc (HWND hwnd, UINT umsg,
renderer = COGL_FRAMEBUFFER (onscreen)->context->display->renderer; renderer = COGL_FRAMEBUFFER (onscreen)->context->display->renderer;
message_handled = message_handled =
cogl_renderer_handle_native_event (renderer, &msg); cogl_win32_renderer_handle_event (renderer, &msg);
} }
if (!message_handled) if (!message_handled)
@ -587,9 +587,9 @@ _cogl_winsys_context_init (CoglContext *context, GError **error)
wgl_context = context->winsys = g_new0 (CoglContextWgl, 1); wgl_context = context->winsys = g_new0 (CoglContextWgl, 1);
cogl_renderer_add_native_filter (context->display->renderer, cogl_win32_renderer_add_filter (context->display->renderer,
win32_event_filter_cb, win32_event_filter_cb,
context); context);
update_winsys_features (context); update_winsys_features (context);
@ -599,9 +599,9 @@ _cogl_winsys_context_init (CoglContext *context, GError **error)
static void static void
_cogl_winsys_context_deinit (CoglContext *context) _cogl_winsys_context_deinit (CoglContext *context)
{ {
cogl_renderer_remove_native_filter (context->display->renderer, cogl_win32_renderer_remove_filter (context->display->renderer,
win32_event_filter_cb, win32_event_filter_cb,
context); context);
g_free (context->winsys); g_free (context->winsys);
} }

@ -21,9 +21,16 @@ cogl_renderer_xlib_set_foreign_display
cogl_renderer_xlib_get_foreign_display cogl_renderer_xlib_get_foreign_display
<SUBSECTION> <SUBSECTION>
cogl_renderer_add_native_filter CoglXlibFilterFunc
cogl_renderer_remove_native_filter cogl_xlib_renderer_add_native_filter
cogl_renderer_handle_native_event cogl_xlib_renderer_remove_native_filter
cogl_xlib_renderer_handle_native_event
<SUBSECTION>
CoglWin32FilterFunc
cogl_win32_renderer_add_native_filter
cogl_win32_renderer_remove_native_filter
cogl_win32_renderer_handle_native_event
<SUBSECTION> <SUBSECTION>
cogl_renderer_wayland_set_foreign_display cogl_renderer_wayland_set_foreign_display

@ -175,8 +175,7 @@ main (int argc, char **argv)
case ButtonRelease: case ButtonRelease:
return 0; return 0;
} }
/* FIXME: This should be replaced with some equivalent cogl_xlib_ typesafe API... */ cogl_xlib_renderer_handle_event (renderer, &event);
cogl_renderer_handle_native_event (renderer, &event);
} }
cogl_clear (&black, COGL_BUFFER_BIT_COLOR); cogl_clear (&black, COGL_BUFFER_BIT_COLOR);
cogl_primitive_draw (triangle); cogl_primitive_draw (triangle);