This looks good to me:<div><br></div><div>Reviewed-by: Robert Bragg <<a href="mailto:robert@linux.intel.com">robert@linux.intel.com</a>></div><div><br></div><div>thanks,</div><div>- Robert<br><br><div class="gmail_quote">
On Tue, Nov 20, 2012 at 6:53 PM, Neil Roberts <span dir="ltr"><<a href="mailto:neil@linux.intel.com" target="_blank">neil@linux.intel.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
The SDL2 winsys will now set the SDL_WINDOW_RESIZABLE flag on the<br>
window before creating it if the resizable property is set on the<br>
onscreen. Note that there doesn't appear to be a way in SDL to change<br>
the flag later so unlike the other winsyses it will only take affect<br>
if it is set before allocating the framebuffer.<br>
<br>
The winsys now registers a callback for SDL events so that it can<br>
report window size changes back to the application.<br>
---<br>
cogl/winsys/cogl-winsys-sdl2.c | 109 ++++++++++++++++++++++++++++++++++++++++-<br>
examples/cogl-sdl2-hello.c | 4 ++<br>
2 files changed, 111 insertions(+), 2 deletions(-)<br>
<br>
diff --git a/cogl/winsys/cogl-winsys-sdl2.c b/cogl/winsys/cogl-winsys-sdl2.c<br>
index 4c0583b..3ae0962 100644<br>
--- a/cogl/winsys/cogl-winsys-sdl2.c<br>
+++ b/cogl/winsys/cogl-winsys-sdl2.c<br>
@@ -53,13 +53,19 @@ typedef struct _CoglDisplaySdl2<br>
{<br>
SDL_Window *dummy_window;<br>
SDL_GLContext *context;<br>
+ CoglBool pending_resize_notify;<br>
} CoglDisplaySdl2;<br>
<br>
typedef struct _CoglOnscreenSdl2<br>
{<br>
SDL_Window *window;<br>
+ CoglBool pending_resize_notify;<br>
} CoglOnscreenSdl2;<br>
<br>
+/* The key used to store a pointer to the CoglOnscreen in an<br>
+ * SDL_Window */<br>
+#define COGL_SDL_WINDOW_DATA_KEY "cogl-onscreen"<br>
+<br>
static CoglFuncPtr<br>
_cogl_winsys_renderer_get_proc_address (CoglRenderer *renderer,<br>
const char *name,<br>
@@ -258,6 +264,47 @@ error:<br>
return FALSE;<br>
}<br>
<br>
+static CoglFilterReturn<br>
+sdl_event_filter_cb (SDL_Event *event, void *data)<br>
+{<br>
+ if (event->type == SDL_WINDOWEVENT &&<br>
+ event->window.event == SDL_WINDOWEVENT_SIZE_CHANGED)<br>
+ {<br>
+ CoglContext *context = data;<br>
+ CoglDisplay *display = context->display;<br>
+ CoglDisplaySdl2 *sdl_display = display->winsys;<br>
+ float width = event->window.data1;<br>
+ float height = event->window.data2;<br>
+ CoglFramebuffer *framebuffer;<br>
+ CoglOnscreenSdl2 *sdl_onscreen;<br>
+ SDL_Window *window;<br>
+<br>
+ window = SDL_GetWindowFromID (event->window.windowID);<br>
+<br>
+ if (window == NULL)<br>
+ return COGL_FILTER_CONTINUE;<br>
+<br>
+ framebuffer = SDL_GetWindowData (window, COGL_SDL_WINDOW_DATA_KEY);<br>
+<br>
+ if (framebuffer == NULL || framebuffer->context != context)<br>
+ return COGL_FILTER_CONTINUE;<br>
+<br>
+ _cogl_framebuffer_winsys_update_size (framebuffer, width, height);<br>
+<br>
+ sdl_onscreen = COGL_ONSCREEN (framebuffer)->winsys;<br>
+<br>
+ /* We only want to notify that a resize happened when the<br>
+ application calls cogl_context_dispatch so instead of immediately<br>
+ notifying we'll set a flag to remember to notify later */<br>
+ sdl_display->pending_resize_notify = TRUE;<br>
+ sdl_onscreen->pending_resize_notify = TRUE;<br>
+<br>
+ return COGL_FILTER_CONTINUE;<br>
+ }<br>
+<br>
+ return COGL_FILTER_CONTINUE;<br>
+}<br>
+<br>
static CoglBool<br>
_cogl_winsys_context_init (CoglContext *context, CoglError **error)<br>
{<br>
@@ -277,12 +324,23 @@ _cogl_winsys_context_init (CoglContext *context, CoglError **error)<br>
COGL_WINSYS_FEATURE_SWAP_REGION_THROTTLE,<br>
TRUE);<br>
<br>
+ _cogl_renderer_add_native_filter (renderer,<br>
+ (CoglNativeFilterFunc) sdl_event_filter_cb,<br>
+ context);<br>
+<br>
return TRUE;<br>
}<br>
<br>
static void<br>
_cogl_winsys_context_deinit (CoglContext *context)<br>
{<br>
+ CoglRenderer *renderer = context->display->renderer;<br>
+<br>
+ _cogl_renderer_remove_native_filter (renderer,<br>
+ (CoglNativeFilterFunc)<br>
+ sdl_event_filter_cb,<br>
+ context);<br>
+<br>
g_free (context->winsys);<br>
}<br>
<br>
@@ -346,15 +404,22 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,<br>
CoglOnscreenSdl2 *sdl_onscreen;<br>
SDL_Window *window;<br>
int width, height;<br>
+ SDL_WindowFlags flags;<br>
<br>
width = cogl_framebuffer_get_width (framebuffer);<br>
height = cogl_framebuffer_get_height (framebuffer);<br>
<br>
+ flags = SDL_WINDOW_OPENGL | SDL_WINDOW_HIDDEN;<br>
+<br>
+ /* The resizable property on SDL window apparently can only be set<br>
+ * on creation */<br>
+ if (onscreen->resizable)<br>
+ flags |= SDL_WINDOW_RESIZABLE;<br>
+<br>
window = SDL_CreateWindow ("" /* title */,<br>
0, 0, /* x/y */<br>
width, height,<br>
- SDL_WINDOW_OPENGL |<br>
- SDL_WINDOW_HIDDEN);<br>
+ flags);<br>
<br>
if (window == NULL)<br>
{<br>
@@ -365,6 +430,8 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,<br>
return FALSE;<br>
}<br>
<br>
+ SDL_SetWindowData (window, COGL_SDL_WINDOW_DATA_KEY, onscreen);<br>
+<br>
onscreen->winsys = g_slice_new (CoglOnscreenSdl2);<br>
sdl_onscreen = onscreen->winsys;<br>
sdl_onscreen->window = window;<br>
@@ -406,6 +473,42 @@ _cogl_winsys_onscreen_set_visibility (CoglOnscreen *onscreen,<br>
SDL_HideWindow (sdl_onscreen->window);<br>
}<br>
<br>
+static void<br>
+flush_pending_notifications_cb (void *data,<br>
+ void *user_data)<br>
+{<br>
+ CoglFramebuffer *framebuffer = data;<br>
+<br>
+ if (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN)<br>
+ {<br>
+ CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);<br>
+ CoglOnscreenSdl2 *sdl_onscreen = onscreen->winsys;<br>
+<br>
+ if (sdl_onscreen->pending_resize_notify)<br>
+ {<br>
+ _cogl_onscreen_notify_resize (onscreen);<br>
+ sdl_onscreen->pending_resize_notify = FALSE;<br>
+ }<br>
+ }<br>
+}<br>
+<br>
+static void<br>
+_cogl_winsys_poll_dispatch (CoglContext *context,<br>
+ const CoglPollFD *poll_fds,<br>
+ int n_poll_fds)<br>
+{<br>
+ CoglDisplay *display = context->display;<br>
+ CoglDisplaySdl2 *sdl_display = display->winsys;<br>
+<br>
+ if (sdl_display->pending_resize_notify)<br>
+ {<br>
+ g_list_foreach (context->framebuffers,<br>
+ flush_pending_notifications_cb,<br>
+ NULL);<br>
+ sdl_display->pending_resize_notify = FALSE;<br>
+ }<br>
+}<br>
+<br>
const CoglWinsysVtable *<br>
_cogl_winsys_sdl_get_vtable (void)<br>
{<br>
@@ -438,6 +541,8 @@ _cogl_winsys_sdl_get_vtable (void)<br>
_cogl_winsys_onscreen_update_swap_throttled;<br>
vtable.onscreen_set_visibility = _cogl_winsys_onscreen_set_visibility;<br>
<br>
+ vtable.poll_dispatch = _cogl_winsys_poll_dispatch;<br>
+<br>
vtable_inited = TRUE;<br>
}<br>
<br>
diff --git a/examples/cogl-sdl2-hello.c b/examples/cogl-sdl2-hello.c<br>
index 972e7e1..0370460 100644<br>
--- a/examples/cogl-sdl2-hello.c<br>
+++ b/examples/cogl-sdl2-hello.c<br>
@@ -99,6 +99,10 @@ main (int argc, char **argv)<br>
data.center_y = 0.0f;<br>
data.quit = FALSE;<br>
<br>
+ /* In SDL2, setting resizable only works before allocating the<br>
+ * onscreen */<br>
+ cogl_onscreen_set_resizable (onscreen, TRUE);<br>
+<br>
cogl_onscreen_show (onscreen);<br>
<br>
data.triangle = cogl_primitive_new_p2c4 (ctx, COGL_VERTICES_MODE_TRIANGLES,<br>
<span class="HOEnZb"><font color="#888888">--<br>
1.7.11.3.g3c3efa5<br>
<br>
_______________________________________________<br>
Cogl mailing list<br>
<a href="mailto:Cogl@lists.freedesktop.org">Cogl@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/cogl" target="_blank">http://lists.freedesktop.org/mailman/listinfo/cogl</a><br>
</font></span></blockquote></div><br></div>