diff --git a/cogl/Makefile.am b/cogl/Makefile.am
index 44cbc65c5..95f8482c5 100644
--- a/cogl/Makefile.am
+++ b/cogl/Makefile.am
@@ -471,6 +471,13 @@ cogl_sources_c += \
$(srcdir)/winsys/cogl-winsys-sdl.c \
$(srcdir)/cogl-sdl.c
endif
+if SUPPORT_SDL2
+cogl_experimental_h += $(srcdir)/cogl-sdl.h
+cogl_sources_c += \
+ $(srcdir)/winsys/cogl-winsys-sdl-private.h \
+ $(srcdir)/winsys/cogl-winsys-sdl2.c \
+ $(srcdir)/cogl-sdl.c
+endif
EXTRA_DIST += stb_image.c
diff --git a/cogl/cogl-sdl.c b/cogl/cogl-sdl.c
index 76932c342..5de168386 100644
--- a/cogl/cogl-sdl.c
+++ b/cogl/cogl-sdl.c
@@ -31,13 +31,13 @@
#include "cogl-renderer-private.h"
void
-cogl_sdl_renderer_set_event_type (CoglRenderer *renderer, uint8_t type)
+cogl_sdl_renderer_set_event_type (CoglRenderer *renderer, int type)
{
renderer->sdl_event_type_set = TRUE;
renderer->sdl_event_type = type;
}
-uint8_t
+int
cogl_sdl_renderer_get_event_type (CoglRenderer *renderer)
{
_COGL_RETURN_VAL_IF_FAIL (renderer->sdl_event_type_set, SDL_USEREVENT);
@@ -46,7 +46,7 @@ cogl_sdl_renderer_get_event_type (CoglRenderer *renderer)
}
CoglContext *
-cogl_sdl_context_new (uint8_t type, GError **error)
+cogl_sdl_context_new (int type, GError **error)
{
CoglRenderer *renderer = cogl_renderer_new ();
CoglDisplay *display;
diff --git a/cogl/cogl-sdl.h b/cogl/cogl-sdl.h
index bf2eafaa0..0a3c4632e 100644
--- a/cogl/cogl-sdl.h
+++ b/cogl/cogl-sdl.h
@@ -123,7 +123,7 @@ G_BEGIN_DECLS
* Stability: unstable
*/
CoglContext *
-cogl_sdl_context_new (uint8_t type, GError **error);
+cogl_sdl_context_new (int type, GError **error);
/**
* cogl_sdl_renderer_set_event_type:
@@ -147,7 +147,7 @@ cogl_sdl_context_new (uint8_t type, GError **error);
* Stability: unstable
*/
void
-cogl_sdl_renderer_set_event_type (CoglRenderer *renderer, uint8_t type);
+cogl_sdl_renderer_set_event_type (CoglRenderer *renderer, int type);
/**
* cogl_sdl_renderer_get_event_type:
@@ -161,7 +161,7 @@ cogl_sdl_renderer_set_event_type (CoglRenderer *renderer, uint8_t type);
* Since: 2.0
* Stability: unstable
*/
-uint8_t
+int
cogl_sdl_renderer_get_event_type (CoglRenderer *renderer);
/**
diff --git a/cogl/winsys/cogl-winsys-sdl2.c b/cogl/winsys/cogl-winsys-sdl2.c
new file mode 100644
index 000000000..44843ade1
--- /dev/null
+++ b/cogl/winsys/cogl-winsys-sdl2.c
@@ -0,0 +1,415 @@
+/*
+ * Cogl
+ *
+ * An object oriented GL/GLES Abstraction/Utility Layer
+ *
+ * Copyright (C) 2011, 2012 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, see .
+ *
+ *
+ * Authors:
+ * Neil Roberts
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include
+
+#include "cogl-renderer-private.h"
+#include "cogl-display-private.h"
+#include "cogl-framebuffer-private.h"
+#include "cogl-swap-chain-private.h"
+#include "cogl-onscreen-template-private.h"
+#include "cogl-context-private.h"
+#include "cogl-onscreen-private.h"
+#include "cogl-winsys-sdl-private.h"
+
+typedef struct _CoglContextSdl2
+{
+ SDL_Window *current_window;
+} CoglContextSdl2;
+
+typedef struct _CoglRendererSdl2
+{
+ int stub;
+} CoglRendererSdl2;
+
+typedef struct _CoglDisplaySdl2
+{
+ SDL_Window *dummy_window;
+ SDL_GLContext *context;
+} CoglDisplaySdl2;
+
+typedef struct _CoglOnscreenSdl2
+{
+ SDL_Window *window;
+} CoglOnscreenSdl2;
+
+static CoglFuncPtr
+_cogl_winsys_renderer_get_proc_address (CoglRenderer *renderer,
+ const char *name)
+{
+ return SDL_GL_GetProcAddress (name);
+}
+
+static void
+_cogl_winsys_renderer_disconnect (CoglRenderer *renderer)
+{
+ SDL_VideoQuit ();
+
+ g_slice_free (CoglRendererSdl2, renderer->winsys);
+}
+
+static CoglBool
+_cogl_winsys_renderer_connect (CoglRenderer *renderer,
+ GError **error)
+{
+ if (SDL_VideoInit (NULL) < 0)
+ {
+ g_set_error (error, COGL_WINSYS_ERROR,
+ COGL_WINSYS_ERROR_INIT,
+ "SDL_Init failed: %s",
+ SDL_GetError ());
+ return FALSE;
+ }
+
+ renderer->winsys = g_slice_new0 (CoglRendererSdl2);
+
+ return TRUE;
+}
+
+static void
+_cogl_winsys_display_destroy (CoglDisplay *display)
+{
+ CoglDisplaySdl2 *sdl_display = display->winsys;
+
+ _COGL_RETURN_IF_FAIL (sdl_display != NULL);
+
+ if (sdl_display->context)
+ SDL_GL_DeleteContext (sdl_display->context);
+
+ if (sdl_display->dummy_window)
+ SDL_DestroyWindow (sdl_display->dummy_window);
+
+ g_slice_free (CoglDisplaySdl2, display->winsys);
+ display->winsys = NULL;
+}
+
+static void
+set_gl_attribs_from_framebuffer_config (CoglFramebufferConfig *config)
+{
+ SDL_GL_SetAttribute (SDL_GL_RED_SIZE, 1);
+ SDL_GL_SetAttribute (SDL_GL_GREEN_SIZE, 1);
+ SDL_GL_SetAttribute (SDL_GL_BLUE_SIZE, 1);
+ SDL_GL_SetAttribute (SDL_GL_DEPTH_SIZE, 1);
+
+ SDL_GL_SetAttribute (SDL_GL_STENCIL_SIZE,
+ config->need_stencil ? 1 : 0);
+
+ SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER,
+ config->swap_chain->length > 1 ? 1 : 0);
+
+ SDL_GL_SetAttribute (SDL_GL_ALPHA_SIZE,
+ config->swap_chain->has_alpha ? 1 : 0);
+}
+
+static CoglBool
+_cogl_winsys_display_setup (CoglDisplay *display,
+ GError **error)
+{
+ CoglDisplaySdl2 *sdl_display;
+ const char * (* get_string_func) (GLenum name);
+ const char *gl_version;
+
+ _COGL_RETURN_VAL_IF_FAIL (display->winsys == NULL, FALSE);
+
+ sdl_display = g_slice_new0 (CoglDisplaySdl2);
+ display->winsys = sdl_display;
+
+ set_gl_attribs_from_framebuffer_config (&display->onscreen_template->config);
+
+ if (display->renderer->driver == COGL_DRIVER_GLES1)
+ SDL_GL_SetAttribute (SDL_GL_CONTEXT_MAJOR_VERSION, 1);
+ else if (display->renderer->driver == COGL_DRIVER_GLES2)
+ SDL_GL_SetAttribute (SDL_GL_CONTEXT_MAJOR_VERSION, 2);
+
+ /* Create a dummy 1x1 window that never gets display so that we can
+ * create a GL context */
+ sdl_display->dummy_window = SDL_CreateWindow ("",
+ 0, 0, /* x/y */
+ 1, 1, /* w/h */
+ SDL_WINDOW_OPENGL |
+ SDL_WINDOW_HIDDEN);
+ if (sdl_display->dummy_window == NULL)
+ {
+ g_set_error (error, COGL_WINSYS_ERROR,
+ COGL_WINSYS_ERROR_INIT,
+ "SDL_CreateWindow failed: %s",
+ SDL_GetError ());
+ goto error;
+ }
+
+ sdl_display->context = SDL_GL_CreateContext (sdl_display->dummy_window);
+
+ if (sdl_display->context == NULL)
+ {
+ g_set_error (error, COGL_WINSYS_ERROR,
+ COGL_WINSYS_ERROR_INIT,
+ "SDL_GL_CreateContext failed: %s",
+ SDL_GetError ());
+ goto error;
+ }
+
+ /* SDL doesn't seem to provide a way to select between GL and GLES
+ * and instead it will just pick one itself. We can at least try to
+ * verify that it picked the one we were expecting by looking at the
+ * GL version string */
+ get_string_func = SDL_GL_GetProcAddress ("glGetString");
+ gl_version = get_string_func (GL_VERSION);
+
+ switch (display->renderer->driver)
+ {
+ case COGL_DRIVER_GL:
+ /* The first character of the version string will be a digit if
+ * it's normal GL */
+ if (!g_ascii_isdigit (gl_version[0]))
+ {
+ g_set_error (error, COGL_WINSYS_ERROR,
+ COGL_WINSYS_ERROR_INIT,
+ "The GL driver was requested but SDL is using GLES");
+ goto error;
+ }
+ break;
+
+ case COGL_DRIVER_GLES2:
+ if (!g_str_has_prefix (gl_version, "OpenGL ES 2"))
+ {
+ g_set_error (error, COGL_WINSYS_ERROR,
+ COGL_WINSYS_ERROR_INIT,
+ "The GLES2 driver was requested but SDL is "
+ "not using GLES2");
+ goto error;
+ }
+ break;
+
+ case COGL_DRIVER_GLES1:
+ if (!g_str_has_prefix (gl_version, "OpenGL ES 1"))
+ {
+ g_set_error (error, COGL_WINSYS_ERROR,
+ COGL_WINSYS_ERROR_INIT,
+ "The GLES1 driver was requested but SDL is "
+ "not using GLES1");
+ goto error;
+ }
+ break;
+
+ default:
+ g_assert_not_reached ();
+ }
+
+ return TRUE;
+
+error:
+ _cogl_winsys_display_destroy (display);
+ return FALSE;
+}
+
+static CoglBool
+_cogl_winsys_context_init (CoglContext *context, GError **error)
+{
+ CoglRenderer *renderer = context->display->renderer;
+
+ context->winsys = g_new0 (CoglContextSdl2, 1);
+
+ if (G_UNLIKELY (renderer->sdl_event_type_set == FALSE))
+ g_error ("cogl_sdl_renderer_set_event_type() or cogl_sdl_context_new() "
+ "must be called during initialization");
+
+ if (!_cogl_context_update_features (context, error))
+ return FALSE;
+
+ if (SDL_GL_GetSwapInterval () != -1)
+ COGL_FLAGS_SET (context->winsys_features,
+ COGL_WINSYS_FEATURE_SWAP_REGION_THROTTLE,
+ TRUE);
+
+ return TRUE;
+}
+
+static void
+_cogl_winsys_context_deinit (CoglContext *context)
+{
+ g_free (context->winsys);
+}
+
+static void
+_cogl_winsys_onscreen_bind (CoglOnscreen *onscreen)
+{
+ CoglFramebuffer *fb = COGL_FRAMEBUFFER (onscreen);
+ CoglContext *context = fb->context;
+ CoglContextSdl2 *sdl_context = context->winsys;
+ CoglDisplaySdl2 *sdl_display = context->display->winsys;
+ CoglOnscreenSdl2 *sdl_onscreen = onscreen->winsys;
+
+ if (sdl_context->current_window == sdl_onscreen->window)
+ return;
+
+ SDL_GL_MakeCurrent (sdl_onscreen->window, sdl_display->context);
+
+ sdl_context->current_window = sdl_onscreen->window;
+
+ /* It looks like SDL just directly calls a glXSwapInterval function
+ * when this is called. This may be provided by either the EXT
+ * extension, the SGI extension or the Mesa extension. The SGI
+ * extension is per context so we can't just do this once when the
+ * framebuffer is allocated. See the comments in the GLX winsys for
+ * more info. */
+ if (COGL_FLAGS_GET (context->winsys_features,
+ COGL_WINSYS_FEATURE_SWAP_REGION_THROTTLE))
+ {
+ CoglFramebuffer *fb = COGL_FRAMEBUFFER (onscreen);
+
+ SDL_GL_SetSwapInterval (fb->config.swap_throttled ? 1 : 0);
+ }
+}
+
+static void
+_cogl_winsys_onscreen_deinit (CoglOnscreen *onscreen)
+{
+ CoglOnscreenSdl2 *sdl_onscreen = onscreen->winsys;
+
+ if (sdl_onscreen->window != NULL)
+ {
+ CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
+ CoglContextSdl2 *sdl_context = context->winsys;
+
+ if (sdl_context->current_window == sdl_onscreen->window)
+ sdl_context->current_window = NULL;
+
+ SDL_DestroyWindow (sdl_onscreen->window);
+ sdl_onscreen->window = NULL;
+ }
+
+ g_slice_free (CoglOnscreenSdl2, sdl_onscreen);
+ onscreen->winsys = NULL;
+}
+
+static CoglBool
+_cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
+ GError **error)
+{
+ CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
+ CoglOnscreenSdl2 *sdl_onscreen;
+ SDL_Window *window;
+ int width, height;
+
+ width = cogl_framebuffer_get_width (framebuffer);
+ height = cogl_framebuffer_get_height (framebuffer);
+
+ window = SDL_CreateWindow ("" /* title */,
+ 0, 0, /* x/y */
+ width, height,
+ SDL_WINDOW_OPENGL |
+ SDL_WINDOW_HIDDEN);
+
+ if (window == NULL)
+ {
+ g_set_error (error, COGL_WINSYS_ERROR,
+ COGL_WINSYS_ERROR_CREATE_ONSCREEN,
+ "SDL_CreateWindow failed: %s",
+ SDL_GetError ());
+ return FALSE;
+ }
+
+ onscreen->winsys = g_slice_new (CoglOnscreenSdl2);
+ sdl_onscreen = onscreen->winsys;
+ sdl_onscreen->window = window;
+
+ return TRUE;
+}
+
+static void
+_cogl_winsys_onscreen_swap_buffers (CoglOnscreen *onscreen)
+{
+ CoglOnscreenSdl2 *sdl_onscreen = onscreen->winsys;
+
+ SDL_GL_SwapWindow (sdl_onscreen->window);
+}
+
+static void
+_cogl_winsys_onscreen_update_swap_throttled (CoglOnscreen *onscreen)
+{
+ CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
+ CoglContextSdl2 *sdl_context = context->winsys;
+ CoglOnscreenSdl2 *sdl_onscreen = onscreen->winsys;
+
+ if (sdl_context->current_window != sdl_onscreen->window)
+ return;
+
+ sdl_context->current_window = NULL;
+ _cogl_winsys_onscreen_bind (onscreen);
+}
+
+static void
+_cogl_winsys_onscreen_set_visibility (CoglOnscreen *onscreen,
+ CoglBool visibility)
+{
+ CoglOnscreenSdl2 *sdl_onscreen = onscreen->winsys;
+
+ if (visibility)
+ SDL_ShowWindow (sdl_onscreen->window);
+ else
+ SDL_HideWindow (sdl_onscreen->window);
+}
+
+const CoglWinsysVtable *
+_cogl_winsys_sdl_get_vtable (void)
+{
+ static CoglBool vtable_inited = FALSE;
+ static CoglWinsysVtable vtable;
+
+ /* It would be nice if we could use C99 struct initializers here
+ like the GLX backend does. However this code is more likely to be
+ compiled using Visual Studio which (still!) doesn't support them
+ so we initialize it in code instead */
+
+ if (!vtable_inited)
+ {
+ memset (&vtable, 0, sizeof (vtable));
+
+ vtable.id = COGL_WINSYS_ID_SDL;
+ vtable.name = "SDL";
+ vtable.renderer_get_proc_address = _cogl_winsys_renderer_get_proc_address;
+ vtable.renderer_connect = _cogl_winsys_renderer_connect;
+ vtable.renderer_disconnect = _cogl_winsys_renderer_disconnect;
+ vtable.display_setup = _cogl_winsys_display_setup;
+ vtable.display_destroy = _cogl_winsys_display_destroy;
+ vtable.context_init = _cogl_winsys_context_init;
+ vtable.context_deinit = _cogl_winsys_context_deinit;
+ vtable.onscreen_init = _cogl_winsys_onscreen_init;
+ vtable.onscreen_deinit = _cogl_winsys_onscreen_deinit;
+ vtable.onscreen_bind = _cogl_winsys_onscreen_bind;
+ vtable.onscreen_swap_buffers = _cogl_winsys_onscreen_swap_buffers;
+ vtable.onscreen_update_swap_throttled =
+ _cogl_winsys_onscreen_update_swap_throttled;
+ vtable.onscreen_set_visibility = _cogl_winsys_onscreen_set_visibility;
+
+ vtable_inited = TRUE;
+ }
+
+ return &vtable;
+}
diff --git a/configure.ac b/configure.ac
index f273dbd72..c18e1bf65 100644
--- a/configure.ac
+++ b/configure.ac
@@ -748,6 +748,30 @@ AS_IF([test "x$enable_sdl" = "xyes"],
[SUPPORT_SDL=no])
AM_CONDITIONAL(SUPPORT_SDL, [test "x$SUPPORT_SDL" = "xyes"])
+AC_ARG_ENABLE(
+ [sdl2],
+ [AC_HELP_STRING([--enable-sdl2=@<:@no/yes@:>@], [Enable SDL2 support @<:@default=no@:>@])],
+ [],
+ [enable_sdl2=no])
+AS_IF([test "x$enable_sdl2" = "xyes"],
+ [
+ PKG_CHECK_MODULES([SDL2],
+ [sdl2],
+ [],
+ [AC_MSG_ERROR([SDL2 support requested but SDL2 not found])])
+
+ SUPPORT_SDL2=yes
+ GL_WINSYS_APIS="$GL_WINSYS_APIS sdl2"
+ COGL_PKG_REQUIRES="$COGL_PKG_REQUIRES sdl2"
+
+ COGL_DEFINES_SYMBOLS="$COGL_DEFINES_SYMBOLS COGL_HAS_SDL_SUPPORT"
+ ],
+ [SUPPORT_SDL2=no])
+AM_CONDITIONAL(SUPPORT_SDL2, [test "x$SUPPORT_SDL2" = "xyes"])
+
+AS_IF([test "x$SUPPORT_SDL2" = "xyes" -a "x$SUPPORT_SDL" = "xyes"],
+ [AC_MSG_ERROR([The SDL1 and SDL2 winsyses are currently mutually exclusive])])
+
EGL_PLATFORM_COUNT=0
AC_ARG_ENABLE(
@@ -890,7 +914,7 @@ AC_ARG_ENABLE(
[xlib-egl-platform],
[AC_HELP_STRING([--enable-xlib-egl-platform=@<:@no/yes@:>@], [Enable support for the Xlib egl platform @<:@default=auto@:>@])],
[],
- AS_IF([test "x$enable_gles1" = "xyes" -o "x$enable_gles2" = "xyes" && test "x$SUPPORT_SDL_GLES" != "xyes" && test $EGL_PLATFORM_COUNT -eq 0],
+ AS_IF([test "x$enable_gles1" = "xyes" -o "x$enable_gles2" = "xyes" && test "x$SUPPORT_SDL_GLES" != "xyes" && test "x$SUPPORT_SDL2" != "xyes" && test $EGL_PLATFORM_COUNT -eq 0],
[enable_xlib_egl_platform=yes], [enable_xlib_egl_platform=no])
)
AS_IF([test "x$enable_xlib_egl_platform" = "xyes"],
diff --git a/examples/Makefile.am b/examples/Makefile.am
index cb2964083..6145d2290 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -63,6 +63,12 @@ cogl_sdl_hello_SOURCES = cogl-sdl-hello.c
cogl_sdl_hello_LDADD = $(common_ldadd)
endif
+if SUPPORT_SDL2
+programs += cogl-sdl2-hello
+cogl_sdl2_hello_SOURCES = cogl-sdl2-hello.c
+cogl_sdl2_hello_LDADD = $(common_ldadd)
+endif
+
cogl_gles2_context_SOURCES = cogl-gles2-context.c
cogl_gles2_context_LDADD = $(common_ldadd)
diff --git a/examples/cogl-sdl2-hello.c b/examples/cogl-sdl2-hello.c
new file mode 100644
index 000000000..f46577114
--- /dev/null
+++ b/examples/cogl-sdl2-hello.c
@@ -0,0 +1,137 @@
+#include
+#include
+#include
+#include
+
+/* This short example is just to demonstrate mixing SDL with Cogl as a
+ simple way to get portable support for events */
+
+typedef struct Data
+{
+ CoglPrimitive *triangle;
+ CoglPipeline *pipeline;
+ float center_x, center_y;
+ CoglFramebuffer *fb;
+ CoglBool quit;
+ CoglBool redraw_queued;
+} Data;
+
+static CoglBool
+redraw (Data *data)
+{
+ CoglFramebuffer *fb = data->fb;
+
+ cogl_framebuffer_clear4f (fb, COGL_BUFFER_BIT_COLOR, 0, 0, 0, 1);
+
+ cogl_framebuffer_push_matrix (fb);
+ cogl_framebuffer_translate (fb, data->center_x, -data->center_y, 0.0f);
+
+ cogl_framebuffer_draw_primitive (fb, data->pipeline, data->triangle);
+ cogl_framebuffer_pop_matrix (fb);
+
+ cogl_onscreen_swap_buffers (COGL_ONSCREEN (fb));
+
+ return FALSE;
+}
+
+static void
+handle_event (Data *data, SDL_Event *event)
+{
+ switch (event->type)
+ {
+ case SDL_WINDOWEVENT:
+ switch (event->window.event)
+ {
+ case SDL_WINDOWEVENT_EXPOSED:
+ data->redraw_queued = TRUE;
+ break;
+
+ case SDL_WINDOWEVENT_CLOSE:
+ data->quit = TRUE;
+ break;
+ }
+ break;
+
+ case SDL_MOUSEMOTION:
+ {
+ int width =
+ cogl_framebuffer_get_width (COGL_FRAMEBUFFER (data->fb));
+ int height =
+ cogl_framebuffer_get_height (COGL_FRAMEBUFFER (data->fb));
+
+ data->center_x = event->motion.x * 2.0f / width - 1.0f;
+ data->center_y = event->motion.y * 2.0f / height - 1.0f;
+
+ data->redraw_queued = TRUE;
+ }
+ break;
+
+ case SDL_QUIT:
+ data->quit = TRUE;
+ break;
+ }
+}
+
+int
+main (int argc, char **argv)
+{
+ CoglContext *ctx;
+ CoglOnscreen *onscreen;
+ GError *error = NULL;
+ CoglVertexP2C4 triangle_vertices[] = {
+ {0, 0.7, 0xff, 0x00, 0x00, 0x80},
+ {-0.7, -0.7, 0x00, 0xff, 0x00, 0xff},
+ {0.7, -0.7, 0x00, 0x00, 0xff, 0xff}
+ };
+ Data data;
+ SDL_Event event;
+
+ ctx = cogl_sdl_context_new (SDL_USEREVENT, &error);
+ if (!ctx)
+ {
+ fprintf (stderr, "Failed to create context: %s\n", error->message);
+ return 1;
+ }
+
+ onscreen = cogl_onscreen_new (ctx, 800, 600);
+ data.fb = COGL_FRAMEBUFFER (onscreen);
+
+ data.center_x = 0.0f;
+ data.center_y = 0.0f;
+ data.quit = FALSE;
+
+ cogl_onscreen_show (onscreen);
+
+ data.triangle = cogl_primitive_new_p2c4 (ctx, COGL_VERTICES_MODE_TRIANGLES,
+ 3, triangle_vertices);
+ data.pipeline = cogl_pipeline_new (ctx);
+
+ data.redraw_queued = TRUE;
+ while (!data.quit)
+ {
+ while (!data.quit)
+ {
+ if (!SDL_PollEvent (&event))
+ {
+ if (data.redraw_queued)
+ break;
+
+ cogl_sdl_idle (ctx);
+ if (!SDL_WaitEvent (&event))
+ {
+ fprintf (stderr, "Error waiting for SDL events");
+ return 1;
+ }
+ }
+
+ handle_event (&data, &event);
+ cogl_sdl_handle_event (ctx, &event);
+ }
+
+ data.redraw_queued = redraw (&data);
+ }
+
+ cogl_object_unref (ctx);
+
+ return 0;
+}