Added a test program framework for easy initialization.
authorSam Lantinga <slouken@libsdl.org>
Tue, 18 Jul 2006 07:49:51 +0000
changeset 1914 051df511279c
parent 1913 83420da906a5
child 1915 a228436a2404
Added a test program framework for easy initialization. Started work on multi-window OpenGL demo
include/SDL_events.h
test/Makefile.in
test/common.c
test/common.h
test/testgl2.c
test/testsprite2.c
--- a/include/SDL_events.h	Mon Jul 17 06:47:33 2006 +0000
+++ b/include/SDL_events.h	Tue Jul 18 07:49:51 2006 +0000
@@ -119,7 +119,7 @@
 /**
  * \struct SDL_WindowEvent
  *
- * \brief Window state change event data
+ * \brief Window state change event data (event.window.*)
  */
 typedef struct SDL_WindowEvent
 {
@@ -133,7 +133,7 @@
 /**
  * \struct SDL_KeyboardEvent
  *
- * \brief Keyboard button event structure
+ * \brief Keyboard button event structure (event.key.*)
  */
 typedef struct SDL_KeyboardEvent
 {
@@ -147,7 +147,7 @@
 /**
  * \struct SDL_TextInputEvent
  *
- * \brief Keyboard text input event structure
+ * \brief Keyboard text input event structure (event.text.*)
  */
 typedef struct SDL_TextInputEvent
 {
@@ -160,7 +160,7 @@
 /**
  * \struct SDL_MouseMotionEvent
  *
- * \brief Mouse motion event structure
+ * \brief Mouse motion event structure (event.motion.*)
  */
 typedef struct SDL_MouseMotionEvent
 {
@@ -177,7 +177,7 @@
 /**
  * \struct SDL_MouseButtonEvent
  *
- * \brief Mouse button event structure
+ * \brief Mouse button event structure (event.button.*)
  */
 typedef struct SDL_MouseButtonEvent
 {
@@ -193,20 +193,20 @@
 /**
  * \struct SDL_MouseWheelEvent
  *
- * \brief Mouse wheel event structure
+ * \brief Mouse wheel event structure (event.wheel.*)
  */
 typedef struct SDL_MouseWheelEvent
 {
     Uint8 type;             /**< SDL_MOUSEWHEEL */
     Uint8 which;            /**< The mouse device index */
-    int motion;                                 /**< The direction and distance scrolled */
+    int motion;             /**< The direction and distance scrolled */
     SDL_WindowID windowID;  /**< The window with mouse focus, if any */
 } SDL_MouseWheelEvent;
 
 /**
  * \struct SDL_JoyAxisEvent
  *
- * \brief Joystick axis motion event structure
+ * \brief Joystick axis motion event structure (event.jaxis.*)
  */
 typedef struct SDL_JoyAxisEvent
 {
@@ -219,7 +219,7 @@
 /**
  * \struct SDL_JoyBallEvent
  *
- * \brief Joystick trackball motion event structure
+ * \brief Joystick trackball motion event structure (event.jball.*)
  */
 typedef struct SDL_JoyBallEvent
 {
@@ -233,7 +233,7 @@
 /**
  * \struct SDL_JoyHatEvent
  *
- * \brief Joystick hat position change event structure
+ * \brief Joystick hat position change event structure (event.jhat.*)
  */
 typedef struct SDL_JoyHatEvent
 {
@@ -251,7 +251,7 @@
 /**
  * \struct SDL_JoyButtonEvent
  *
- * \brief Joystick button event structure
+ * \brief Joystick button event structure (event.jbutton.*)
  */
 typedef struct SDL_JoyButtonEvent
 {
@@ -274,7 +274,7 @@
 /**
  * \struct SDL_UserEvent
  *
- * \brief A user-defined event type
+ * \brief A user-defined event type (event.user.*)
  */
 typedef struct SDL_UserEvent
 {
@@ -287,7 +287,7 @@
 /**
  * \struct SDL_SysWMEvent
  *
- * \brief A video driver dependent system event
+ * \brief A video driver dependent system event (event.syswm.*)
  *
  * \note If you want to use this event, you should include SDL_syswm.h
  */
--- a/test/Makefile.in	Mon Jul 17 06:47:33 2006 +0000
+++ b/test/Makefile.in	Tue Jul 18 07:49:51 2006 +0000
@@ -7,9 +7,12 @@
 CFLAGS  = @CFLAGS@
 LIBS	= @LIBS@
 
-TARGETS = checkkeys$(EXE) graywin$(EXE) loopwave$(EXE) testalpha$(EXE) testbitmap$(EXE) testblitspeed$(EXE) testcdrom$(EXE) testcursor$(EXE) testdyngl$(EXE) testerror$(EXE) testfile$(EXE) testgamma$(EXE) testgl$(EXE) testhread$(EXE) testiconv$(EXE) testjoystick$(EXE) testkeys$(EXE) testlock$(EXE) testoverlay2$(EXE) testoverlay$(EXE) testpalette$(EXE) testplatform$(EXE) testsem$(EXE) testsprite$(EXE) testsprite2$(EXE) testtimer$(EXE) testver$(EXE) testvidinfo$(EXE) testwin$(EXE) testwm$(EXE) testwm2$(EXE) threadwin$(EXE) torturethread$(EXE)
+TARGETS = checkkeys$(EXE) graywin$(EXE) loopwave$(EXE) testalpha$(EXE) testbitmap$(EXE) testblitspeed$(EXE) testcdrom$(EXE) testcursor$(EXE) testdyngl$(EXE) testerror$(EXE) testfile$(EXE) testgamma$(EXE) testgl$(EXE) testgl2$(EXE) testhread$(EXE) testiconv$(EXE) testjoystick$(EXE) testkeys$(EXE) testlock$(EXE) testoverlay2$(EXE) testoverlay$(EXE) testpalette$(EXE) testplatform$(EXE) testsem$(EXE) testsprite$(EXE) testsprite2$(EXE) testtimer$(EXE) testver$(EXE) testvidinfo$(EXE) testwin$(EXE) testwm$(EXE) testwm2$(EXE) threadwin$(EXE) torturethread$(EXE)
 
-all: $(TARGETS)
+all: Makefile $(TARGETS)
+
+Makefile: $(srcdir)/Makefile.in
+	$(SHELL) config.status $@
 
 checkkeys$(EXE): $(srcdir)/checkkeys.c
 	$(CC) -o $@ $? $(CFLAGS) $(LIBS)
@@ -50,6 +53,9 @@
 testgl$(EXE): $(srcdir)/testgl.c
 	$(CC) -o $@ $? $(CFLAGS) $(LIBS) @GLLIB@ @MATHLIB@
 
+testgl2$(EXE): $(srcdir)/testgl2.c
+	$(CC) -o $@ $? $(CFLAGS) $(LIBS) @GLLIB@ @MATHLIB@
+
 testhread$(EXE): $(srcdir)/testhread.c
 	$(CC) -o $@ $? $(CFLAGS) $(LIBS)
 
@@ -83,8 +89,8 @@
 testsprite$(EXE): $(srcdir)/testsprite.c
 	$(CC) -o $@ $? $(CFLAGS) $(LIBS) @MATHLIB@
 
-testsprite2$(EXE): $(srcdir)/testsprite2.c
-	$(CC) -o $@ $? $(CFLAGS) $(LIBS) @MATHLIB@
+testsprite2$(EXE): $(srcdir)/testsprite2.c $(srcdir)/common.c
+	$(CC) -o $@ $(srcdir)/testsprite2.c $(srcdir)/common.c $(CFLAGS) $(LIBS) @MATHLIB@
 
 testtimer$(EXE): $(srcdir)/testtimer.c
 	$(CC) -o $@ $? $(CFLAGS) $(LIBS)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/common.c	Tue Jul 18 07:49:51 2006 +0000
@@ -0,0 +1,927 @@
+
+/* A simple test program framework */
+
+#include <stdio.h>
+
+#include "common.h"
+
+#define VIDEO_USAGE \
+"[--video driver] [--renderer driver] [--info all|video|modes|render|event] [--display %d] [--fullscreen | --windows N] [--title title] [--center | --position X,Y] [--geometry WxH] [--depth N] [--refresh R] [--vsync] [--noframe] [--resize] [--minimize] [--maximize] [--grab]"
+
+#define AUDIO_USAGE \
+"[--rate N] [--format U8|S8|U16|U16LE|U16BE|S16|S16LE|S16BE] [--channels N] [--samples N]"
+
+CommonState *
+CommonCreateState(char **argv, Uint32 flags)
+{
+    CommonState *state = SDL_calloc(1, sizeof(*state));
+    if (!state) {
+        SDL_OutOfMemory();
+        return NULL;
+    }
+
+    /* Initialize some defaults */
+    state->argv = argv;
+    state->flags = flags;
+    state->window_title = argv[0];
+    state->window_flags = SDL_WINDOW_SHOWN;
+    state->window_x = SDL_WINDOWPOS_UNDEFINED;
+    state->window_y = SDL_WINDOWPOS_UNDEFINED;
+    state->window_w = 640;
+    state->window_h = 480;
+    state->num_windows = 1;
+    state->audiospec.freq = 22050;
+    state->audiospec.format = AUDIO_S16;
+    state->audiospec.channels = 2;
+    state->audiospec.samples = 2048;
+    return state;
+}
+
+int
+CommonArg(CommonState * state, int index)
+{
+    char **argv = state->argv;
+
+    if (SDL_strcasecmp(argv[index], "--video") == 0) {
+        ++index;
+        if (!argv[index]) {
+            return -1;
+        }
+        state->videodriver = argv[index];
+        return 2;
+    }
+    if (SDL_strcasecmp(argv[index], "--renderer") == 0) {
+        ++index;
+        if (!argv[index]) {
+            return -1;
+        }
+        if (SDL_strcasecmp(argv[index], "opengl") == 0) {
+            state->window_flags |= SDL_WINDOW_OPENGL;
+        }
+        state->renderdriver = argv[index];
+        return 2;
+    }
+    if (SDL_strcasecmp(argv[index], "--info") == 0) {
+        ++index;
+        if (!argv[index]) {
+            return -1;
+        }
+        if (SDL_strcasecmp(argv[index], "all") == 0) {
+            state->verbose |=
+                (VERBOSE_VIDEO | VERBOSE_MODES | VERBOSE_RENDER |
+                 VERBOSE_EVENT);
+            return 2;
+        }
+        if (SDL_strcasecmp(argv[index], "video") == 0) {
+            state->verbose |= VERBOSE_VIDEO;
+            return 2;
+        }
+        if (SDL_strcasecmp(argv[index], "modes") == 0) {
+            state->verbose |= VERBOSE_MODES;
+            return 2;
+        }
+        if (SDL_strcasecmp(argv[index], "render") == 0) {
+            state->verbose |= VERBOSE_RENDER;
+            return 2;
+        }
+        if (SDL_strcasecmp(argv[index], "event") == 0) {
+            state->verbose |= VERBOSE_EVENT;
+            return 2;
+        }
+        return -1;
+    }
+    if (SDL_strcasecmp(argv[index], "--display") == 0) {
+        ++index;
+        if (!argv[index]) {
+            return -1;
+        }
+        state->display = SDL_atoi(argv[index]);
+        return 2;
+    }
+    if (SDL_strcasecmp(argv[index], "--fullscreen") == 0) {
+        state->window_flags |= SDL_WINDOW_FULLSCREEN;
+        state->num_windows = 1;
+        return 1;
+    }
+    if (SDL_strcasecmp(argv[index], "--windows") == 0) {
+        ++index;
+        if (!argv[index] || !isdigit(*argv[index])) {
+            return -1;
+        }
+        if (!(state->window_flags & SDL_WINDOW_FULLSCREEN)) {
+            state->num_windows = SDL_atoi(argv[index]);
+        }
+        return 2;
+    }
+    if (SDL_strcasecmp(argv[index], "--title") == 0) {
+        ++index;
+        if (!argv[index]) {
+            return -1;
+        }
+        state->window_title = argv[index];
+        return 2;
+    }
+    if (SDL_strcasecmp(argv[index], "--center") == 0) {
+        state->window_x = SDL_WINDOWPOS_CENTERED;
+        state->window_y = SDL_WINDOWPOS_CENTERED;
+        return 1;
+    }
+    if (SDL_strcasecmp(argv[index], "--position") == 0) {
+        char *x, *y;
+        ++index;
+        if (!argv[index]) {
+            return -1;
+        }
+        x = argv[index];
+        y = argv[index];
+        while (*y && *y != ',') {
+            ++y;
+        }
+        if (!*y) {
+            return -1;
+        }
+        *y++ = '\0';
+        state->window_x = SDL_atoi(x);
+        state->window_y = SDL_atoi(y);
+        return 2;
+    }
+    if (SDL_strcasecmp(argv[index], "--geometry") == 0) {
+        char *w, *h;
+        ++index;
+        if (!argv[index]) {
+            return -1;
+        }
+        w = argv[index];
+        h = argv[index];
+        while (*h && *h != 'x') {
+            ++h;
+        }
+        if (!*h) {
+            return -1;
+        }
+        *h++ = '\0';
+        state->window_w = SDL_atoi(w);
+        state->window_h = SDL_atoi(h);
+        return 2;
+    }
+    if (SDL_strcasecmp(argv[index], "--refresh") == 0) {
+        ++index;
+        if (!argv[index]) {
+            return -1;
+        }
+        state->refresh_rate = SDL_atoi(argv[index]);
+        return 2;
+    }
+    if (SDL_strcasecmp(argv[index], "--vsync") == 0) {
+        state->render_flags |= SDL_Renderer_PresentVSync;
+        return 1;
+    }
+    if (SDL_strcasecmp(argv[index], "--noframe") == 0) {
+        state->window_flags |= SDL_WINDOW_BORDERLESS;
+        return 1;
+    }
+    if (SDL_strcasecmp(argv[index], "--resize") == 0) {
+        state->window_flags |= SDL_WINDOW_RESIZABLE;
+        return 1;
+    }
+    if (SDL_strcasecmp(argv[index], "--minimize") == 0) {
+        state->window_flags |= SDL_WINDOW_MINIMIZED;
+        return 1;
+    }
+    if (SDL_strcasecmp(argv[index], "--maximize") == 0) {
+        state->window_flags |= SDL_WINDOW_MAXIMIZED;
+        return 1;
+    }
+    if (SDL_strcasecmp(argv[index], "--grab") == 0) {
+        state->window_flags |= SDL_WINDOW_INPUT_GRABBED;
+        return 1;
+    }
+    if (SDL_strcasecmp(argv[index], "--rate") == 0) {
+        ++index;
+        if (!argv[index]) {
+            return -1;
+        }
+        state->audiospec.freq = SDL_atoi(argv[index]);
+        return 2;
+    }
+    if (SDL_strcasecmp(argv[index], "--format") == 0) {
+        ++index;
+        if (!argv[index]) {
+            return -1;
+        }
+        if (SDL_strcasecmp(argv[index], "U8") == 0) {
+            state->audiospec.format = AUDIO_U8;
+            return 2;
+        }
+        if (SDL_strcasecmp(argv[index], "S8") == 0) {
+            state->audiospec.format = AUDIO_S8;
+            return 2;
+        }
+        if (SDL_strcasecmp(argv[index], "U16") == 0) {
+            state->audiospec.format = AUDIO_U16;
+            return 2;
+        }
+        if (SDL_strcasecmp(argv[index], "U16LE") == 0) {
+            state->audiospec.format = AUDIO_U16LSB;
+            return 2;
+        }
+        if (SDL_strcasecmp(argv[index], "U16BE") == 0) {
+            state->audiospec.format = AUDIO_U16MSB;
+            return 2;
+        }
+        if (SDL_strcasecmp(argv[index], "S16") == 0) {
+            state->audiospec.format = AUDIO_S16;
+            return 2;
+        }
+        if (SDL_strcasecmp(argv[index], "S16LE") == 0) {
+            state->audiospec.format = AUDIO_S16LSB;
+            return 2;
+        }
+        if (SDL_strcasecmp(argv[index], "S16BE") == 0) {
+            state->audiospec.format = AUDIO_S16MSB;
+            return 2;
+        }
+        return -1;
+    }
+    if (SDL_strcasecmp(argv[index], "--channels") == 0) {
+        ++index;
+        if (!argv[index]) {
+            return -1;
+        }
+        state->audiospec.channels = SDL_atoi(argv[index]);
+        return 2;
+    }
+    if (SDL_strcasecmp(argv[index], "--samples") == 0) {
+        ++index;
+        if (!argv[index]) {
+            return -1;
+        }
+        state->audiospec.samples = SDL_atoi(argv[index]);
+        return 2;
+    }
+    if ((SDL_strcasecmp(argv[index], "-h") == 0)
+        || (SDL_strcasecmp(argv[index], "--help") == 0)) {
+        /* Print the usage message */
+        return -1;
+    }
+    return 0;
+}
+
+const char *
+CommonUsage(CommonState * state)
+{
+    switch (state->flags & (SDL_INIT_VIDEO | SDL_INIT_AUDIO)) {
+    case SDL_INIT_VIDEO:
+        return VIDEO_USAGE;
+    case SDL_INIT_AUDIO:
+        return AUDIO_USAGE;
+    case (SDL_INIT_VIDEO | SDL_INIT_AUDIO):
+        return VIDEO_USAGE " " AUDIO_USAGE;
+    default:
+        return "";
+    }
+}
+
+static void
+PrintRendererFlag(Uint32 flag)
+{
+    switch (flag) {
+    case SDL_Renderer_SingleBuffer:
+        fprintf(stderr, "SingleBuffer");
+        break;
+    case SDL_Renderer_PresentCopy:
+        fprintf(stderr, "PresentCopy");
+        break;
+    case SDL_Renderer_PresentFlip2:
+        fprintf(stderr, "PresentFlip2");
+        break;
+    case SDL_Renderer_PresentFlip3:
+        fprintf(stderr, "PresentFlip3");
+        break;
+    case SDL_Renderer_PresentDiscard:
+        fprintf(stderr, "PresentDiscard");
+        break;
+    case SDL_Renderer_PresentVSync:
+        fprintf(stderr, "PresentVSync");
+        break;
+    default:
+        fprintf(stderr, "0x%8.8x", flag);
+        break;
+    }
+}
+
+static void
+PrintBlendMode(Uint32 flag)
+{
+    switch (flag) {
+    case SDL_TextureBlendMode_None:
+        fprintf(stderr, "None");
+        break;
+    case SDL_TextureBlendMode_Mask:
+        fprintf(stderr, "Mask");
+        break;
+    case SDL_TextureBlendMode_Blend:
+        fprintf(stderr, "Blend");
+        break;
+    case SDL_TextureBlendMode_Add:
+        fprintf(stderr, "Add");
+        break;
+    case SDL_TextureBlendMode_Mod:
+        fprintf(stderr, "Mod");
+        break;
+    default:
+        fprintf(stderr, "0x%8.8x", flag);
+        break;
+    }
+}
+
+static void
+PrintScaleMode(Uint32 flag)
+{
+    switch (flag) {
+    case SDL_TextureScaleMode_None:
+        fprintf(stderr, "None");
+        break;
+    case SDL_TextureScaleMode_Fast:
+        fprintf(stderr, "Fast");
+        break;
+    case SDL_TextureScaleMode_Slow:
+        fprintf(stderr, "Slow");
+        break;
+    case SDL_TextureScaleMode_Best:
+        fprintf(stderr, "Best");
+        break;
+    default:
+        fprintf(stderr, "0x%8.8x", flag);
+        break;
+    }
+}
+
+static void
+PrintPixelFormat(Uint32 format)
+{
+    switch (format) {
+    case SDL_PixelFormat_Unknown:
+        fprintf(stderr, "Unknwon");
+        break;
+    case SDL_PixelFormat_Index1LSB:
+        fprintf(stderr, "Index1LSB");
+        break;
+    case SDL_PixelFormat_Index1MSB:
+        fprintf(stderr, "Index1MSB");
+        break;
+    case SDL_PixelFormat_Index4LSB:
+        fprintf(stderr, "Index4LSB");
+        break;
+    case SDL_PixelFormat_Index4MSB:
+        fprintf(stderr, "Index4MSB");
+        break;
+    case SDL_PixelFormat_Index8:
+        fprintf(stderr, "Index8");
+        break;
+    case SDL_PixelFormat_RGB332:
+        fprintf(stderr, "RGB332");
+        break;
+    case SDL_PixelFormat_RGB444:
+        fprintf(stderr, "RGB444");
+        break;
+    case SDL_PixelFormat_RGB555:
+        fprintf(stderr, "RGB555");
+        break;
+    case SDL_PixelFormat_ARGB4444:
+        fprintf(stderr, "ARGB4444");
+        break;
+    case SDL_PixelFormat_ARGB1555:
+        fprintf(stderr, "ARGB1555");
+        break;
+    case SDL_PixelFormat_RGB565:
+        fprintf(stderr, "RGB565");
+        break;
+    case SDL_PixelFormat_RGB24:
+        fprintf(stderr, "RGB24");
+        break;
+    case SDL_PixelFormat_BGR24:
+        fprintf(stderr, "BGR24");
+        break;
+    case SDL_PixelFormat_RGB888:
+        fprintf(stderr, "RGB888");
+        break;
+    case SDL_PixelFormat_BGR888:
+        fprintf(stderr, "BGR888");
+        break;
+    case SDL_PixelFormat_ARGB8888:
+        fprintf(stderr, "ARGB8888");
+        break;
+    case SDL_PixelFormat_RGBA8888:
+        fprintf(stderr, "RGBA8888");
+        break;
+    case SDL_PixelFormat_ABGR8888:
+        fprintf(stderr, "ABGR8888");
+        break;
+    case SDL_PixelFormat_BGRA8888:
+        fprintf(stderr, "BGRA8888");
+        break;
+    case SDL_PixelFormat_ARGB2101010:
+        fprintf(stderr, "ARGB2101010");
+        break;
+    case SDL_PixelFormat_YV12:
+        fprintf(stderr, "YV12");
+        break;
+    case SDL_PixelFormat_IYUV:
+        fprintf(stderr, "IYUV");
+        break;
+    case SDL_PixelFormat_YUY2:
+        fprintf(stderr, "YUY2");
+        break;
+    case SDL_PixelFormat_UYVY:
+        fprintf(stderr, "UYVY");
+        break;
+    case SDL_PixelFormat_YVYU:
+        fprintf(stderr, "YVYU");
+        break;
+    default:
+        fprintf(stderr, "0x%8.8x", format);
+        break;
+    }
+}
+
+static void
+PrintRenderer(SDL_RendererInfo * info)
+{
+    int i, count;
+
+    fprintf(stderr, "  Renderer %s:\n", info->name);
+
+    fprintf(stderr, "    Flags: 0x%8.8X", info->flags);
+    fprintf(stderr, " (");
+    count = 0;
+    for (i = 0; i < sizeof(info->flags) * 8; ++i) {
+        Uint32 flag = (1 << i);
+        if (info->flags & flag) {
+            if (count > 0) {
+                fprintf(stderr, " | ");
+            }
+            PrintRendererFlag(flag);
+            ++count;
+        }
+    }
+    fprintf(stderr, ")\n");
+
+    fprintf(stderr, "    Blend: 0x%8.8X", info->blend_modes);
+    fprintf(stderr, " (");
+    count = 0;
+    for (i = 0; i < sizeof(info->blend_modes) * 8; ++i) {
+        Uint32 flag = (1 << i);
+        if (info->blend_modes & flag) {
+            if (count > 0) {
+                fprintf(stderr, " | ");
+            }
+            PrintBlendMode(flag);
+            ++count;
+        }
+    }
+    fprintf(stderr, ")\n");
+
+    fprintf(stderr, "    Scale: 0x%8.8X", info->scale_modes);
+    fprintf(stderr, " (");
+    count = 0;
+    for (i = 0; i < sizeof(info->scale_modes) * 8; ++i) {
+        Uint32 flag = (1 << i);
+        if (info->scale_modes & flag) {
+            if (count > 0) {
+                fprintf(stderr, " | ");
+            }
+            PrintScaleMode(flag);
+            ++count;
+        }
+    }
+    fprintf(stderr, ")\n");
+
+    fprintf(stderr, "    Texture formats (%d): ", info->num_texture_formats);
+    for (i = 0; i < info->num_texture_formats; ++i) {
+        if (i > 0) {
+            fprintf(stderr, ", ");
+        }
+        PrintPixelFormat(info->texture_formats[i]);
+    }
+    fprintf(stderr, "\n");
+
+    if (info->max_texture_width || info->max_texture_height) {
+        fprintf(stderr, "    Max Texture Size: %dx%d\n",
+                info->max_texture_width, info->max_texture_height);
+    }
+}
+
+SDL_bool
+CommonInit(CommonState * state)
+{
+    int i, j, m, n;
+    SDL_DisplayMode fullscreen_mode;
+
+    if (state->flags & SDL_INIT_VIDEO) {
+        if (state->verbose & VERBOSE_VIDEO) {
+            n = SDL_GetNumVideoDrivers();
+            if (n == 0) {
+                fprintf(stderr, "No built-in video drivers\n");
+            } else {
+                fprintf(stderr, "Built-in video drivers:");
+                for (i = 0; i < n; ++i) {
+                    if (i > 0) {
+                        fprintf(stderr, ",");
+                    }
+                    fprintf(stderr, " %s", SDL_GetVideoDriver(i));
+                }
+                fprintf(stderr, "\n");
+            }
+        }
+        if (SDL_VideoInit(state->videodriver, 0) < 0) {
+            fprintf(stderr, "Couldn't initialize video driver: %s\n",
+                    SDL_GetError());
+            return SDL_FALSE;
+        }
+        if (state->verbose & VERBOSE_VIDEO) {
+            fprintf(stderr, "Video driver: %s\n",
+                    SDL_GetCurrentVideoDriver());
+        }
+
+        if (state->verbose & VERBOSE_MODES) {
+            const SDL_DisplayMode *mode;
+            int bpp;
+            Uint32 Rmask, Gmask, Bmask, Amask;
+
+            n = SDL_GetNumVideoDisplays();
+            fprintf(stderr, "Number of displays: %d\n", n);
+            for (i = 0; i < n; ++i) {
+                fprintf(stderr, "Display %d:\n", i);
+                SDL_SelectVideoDisplay(i);
+
+                mode = SDL_GetDesktopDisplayMode();
+                SDL_PixelFormatEnumToMasks(mode->format, &bpp, &Rmask, &Gmask,
+                                           &Bmask, &Amask);
+                fprintf(stderr,
+                        "  Current mode: %dx%d@%dHz, %d bits-per-pixel\n",
+                        mode->w, mode->h, mode->refresh_rate, bpp);
+                if (Rmask || Gmask || Bmask) {
+                    fprintf(stderr, "      Red Mask = 0x%.8x\n", Rmask);
+                    fprintf(stderr, "      Green Mask = 0x%.8x\n", Gmask);
+                    fprintf(stderr, "      Blue Mask = 0x%.8x\n", Bmask);
+                    if (Amask)
+                        fprintf(stderr, "      Alpha Mask = 0x%.8x\n", Amask);
+                }
+
+                /* Print available fullscreen video modes */
+                m = SDL_GetNumDisplayModes();
+                if (m == 0) {
+                    fprintf(stderr, "No available fullscreen video modes\n");
+                } else {
+                    fprintf(stderr, "  Fullscreen video modes:\n");
+                    for (j = 0; j < m; ++j) {
+                        mode = SDL_GetDisplayMode(j);
+                        SDL_PixelFormatEnumToMasks(mode->format, &bpp, &Rmask,
+                                                   &Gmask, &Bmask, &Amask);
+                        fprintf(stderr,
+                                "    Mode %d: %dx%d@%dHz, %d bits-per-pixel\n",
+                                j, mode->w, mode->h, mode->refresh_rate, bpp);
+                        if (Rmask || Gmask || Bmask) {
+                            fprintf(stderr, "        Red Mask = 0x%.8x\n",
+                                    Rmask);
+                            fprintf(stderr, "        Green Mask = 0x%.8x\n",
+                                    Gmask);
+                            fprintf(stderr, "        Blue Mask = 0x%.8x\n",
+                                    Bmask);
+                            if (Amask)
+                                fprintf(stderr,
+                                        "        Alpha Mask = 0x%.8x\n",
+                                        Amask);
+                        }
+                    }
+                }
+            }
+        }
+
+        SDL_SelectVideoDisplay(state->display);
+        if (state->verbose & VERBOSE_RENDER) {
+            SDL_RendererInfo info;
+
+            n = SDL_GetNumRenderers();
+            if (n == 0) {
+                fprintf(stderr, "No built-in render drivers\n");
+            } else {
+                fprintf(stderr, "Built-in render video drivers:\n");
+                for (i = 0; i < n; ++i) {
+                    SDL_GetRendererInfo(i, &info);
+                    PrintRenderer(&info);
+                }
+            }
+        }
+
+        switch (state->depth) {
+        case 8:
+            fullscreen_mode.format = SDL_PixelFormat_Index8;
+            break;
+        case 15:
+            fullscreen_mode.format = SDL_PixelFormat_RGB555;
+            break;
+        case 16:
+            fullscreen_mode.format = SDL_PixelFormat_RGB565;
+            break;
+        default:
+            fullscreen_mode.format = SDL_PixelFormat_RGB888;
+            break;
+        }
+        fullscreen_mode.w = state->window_w;
+        fullscreen_mode.h = state->window_h;
+        fullscreen_mode.refresh_rate = state->refresh_rate;
+        SDL_SetFullscreenDisplayMode(&fullscreen_mode);
+
+        state->windows =
+            (SDL_WindowID *) SDL_malloc(state->num_windows *
+                                        sizeof(*state->windows));
+        if (!state->windows) {
+            fprintf(stderr, "Out of memory!\n");
+            return SDL_FALSE;
+        }
+        for (i = 0; i < state->num_windows; ++i) {
+            char title[1024];
+
+            if (state->num_windows > 1) {
+                SDL_snprintf(title, SDL_arraysize(title), "%s %d",
+                             state->window_title, i + 1);
+            } else {
+                SDL_strlcpy(title, state->window_title, SDL_arraysize(title));
+            }
+            state->windows[i] =
+                SDL_CreateWindow(title, state->window_x, state->window_y,
+                                 state->window_w, state->window_h,
+                                 state->window_flags);
+            if (!state->windows[i]) {
+                fprintf(stderr, "Couldn't create window: %s\n",
+                        SDL_GetError());
+                return SDL_FALSE;
+            }
+
+            if (state->renderdriver
+                || !(state->window_flags & SDL_WINDOW_OPENGL)) {
+                m = -1;
+                if (state->renderdriver) {
+                    SDL_RendererInfo info;
+                    n = SDL_GetNumRenderers();
+                    for (j = 0; j < n; ++j) {
+                        SDL_GetRendererInfo(j, &info);
+                        if (SDL_strcasecmp(info.name, state->renderdriver) ==
+                            0) {
+                            m = j;
+                            break;
+                        }
+                    }
+                    if (m == n) {
+                        fprintf(stderr,
+                                "Couldn't find render driver named %s",
+                                state->renderdriver);
+                        return SDL_FALSE;
+                    }
+                }
+                if (SDL_CreateRenderer
+                    (state->windows[i], m, state->render_flags) < 0) {
+                    fprintf(stderr, "Couldn't create renderer: %s\n",
+                            SDL_GetError());
+                    return SDL_FALSE;
+                }
+            }
+        }
+        SDL_SelectRenderer(state->windows[0]);
+    }
+
+    if (state->flags & SDL_INIT_AUDIO) {
+        if (state->verbose & VERBOSE_AUDIO) {
+            n = SDL_GetNumAudioDrivers();
+            if (n == 0) {
+                fprintf(stderr, "No built-in audio drivers\n");
+            } else {
+                fprintf(stderr, "Built-in audio drivers:");
+                for (i = 0; i < n; ++i) {
+                    if (i > 0) {
+                        fprintf(stderr, ",");
+                    }
+                    fprintf(stderr, " %s", SDL_GetAudioDriver(i));
+                }
+                fprintf(stderr, "\n");
+            }
+        }
+        if (SDL_AudioInit(state->audiodriver) < 0) {
+            fprintf(stderr, "Couldn't initialize audio driver: %s\n",
+                    SDL_GetError());
+            return SDL_FALSE;
+        }
+        if (state->verbose & VERBOSE_VIDEO) {
+            fprintf(stderr, "Audio driver: %s\n",
+                    SDL_GetCurrentAudioDriver());
+        }
+
+        if (SDL_OpenAudio(&state->audiospec, NULL) < 0) {
+            fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError());
+            return SDL_FALSE;
+        }
+    }
+
+    return SDL_TRUE;
+}
+
+static void
+PrintEvent(SDL_Event * event)
+{
+    fprintf(stderr, "SDL EVENT: ");
+    switch (event->type) {
+    case SDL_WINDOWEVENT:
+        switch (event->window.event) {
+        case SDL_WINDOWEVENT_SHOWN:
+            fprintf(stderr, "Window %d shown", event->window.windowID);
+            break;
+        case SDL_WINDOWEVENT_HIDDEN:
+            fprintf(stderr, "Window %d hidden", event->window.windowID);
+            break;
+        case SDL_WINDOWEVENT_EXPOSED:
+            fprintf(stderr, "Window %d exposed: %d", event->window.windowID);
+            break;
+        case SDL_WINDOWEVENT_MOVED:
+            fprintf(stderr, "Window %d moved to %d,%d: %d",
+                    event->window.windowID, event->window.data1,
+                    event->window.data2);
+            break;
+        case SDL_WINDOWEVENT_RESIZED:
+            fprintf(stderr, "Window %d resized to %dx%d: %d",
+                    event->window.windowID, event->window.data1,
+                    event->window.data2);
+            break;
+        case SDL_WINDOWEVENT_MINIMIZED:
+            fprintf(stderr, "Window %d minimized", event->window.windowID);
+            break;
+        case SDL_WINDOWEVENT_MAXIMIZED:
+            fprintf(stderr, "Window %d maximized", event->window.windowID);
+            break;
+        case SDL_WINDOWEVENT_RESTORED:
+            fprintf(stderr, "Window %d restored", event->window.windowID);
+            break;
+        case SDL_WINDOWEVENT_ENTER:
+            fprintf(stderr, "Mouse entered window %d",
+                    event->window.windowID);
+            break;
+        case SDL_WINDOWEVENT_LEAVE:
+            fprintf(stderr, "Mouse left window %d", event->window.windowID);
+            break;
+        case SDL_WINDOWEVENT_FOCUS_GAINED:
+            fprintf(stderr, "Window %d gained keyboard focus",
+                    event->window.windowID);
+            break;
+        case SDL_WINDOWEVENT_FOCUS_LOST:
+            fprintf(stderr, "Window %d lost keyboard focus",
+                    event->window.windowID);
+            break;
+        default:
+            fprintf(stderr, "Window %d got unknown event %d",
+                    event->window.windowID, event->window.event);
+            break;
+        }
+        break;
+    case SDL_KEYDOWN:
+        fprintf(stderr, "Keyboard %d: key %s pressed in window %d",
+                event->key.which, SDL_GetKeyName(event->key.keysym.sym),
+                event->key.windowID);
+        break;
+    case SDL_KEYUP:
+        fprintf(stderr, "Keyboard %d: key %s released in window %d",
+                event->key.which, SDL_GetKeyName(event->key.keysym.sym),
+                event->key.windowID);
+        break;
+    case SDL_TEXTINPUT:
+        fprintf(stderr, "Keyboard %d: text input \"%s\" in window %d",
+                event->text.which, event->text.text, event->text.windowID);
+        break;
+    case SDL_MOUSEMOTION:
+        fprintf(stderr, "Mouse %d: moved to %d,%d (%d,%d) in window %d",
+                event->motion.which, event->motion.x, event->motion.y,
+                event->motion.xrel, event->motion.yrel,
+                event->motion.windowID);
+        break;
+    case SDL_MOUSEBUTTONDOWN:
+        fprintf(stderr, "Mouse %d: button %d pressed at %d,%d in window %d",
+                event->button.which, event->button.button, event->button.x,
+                event->button.y, event->button.windowID);
+        break;
+    case SDL_MOUSEBUTTONUP:
+        fprintf(stderr, "Mouse %d: button %d released at %d,%d in window %d",
+                event->button.which, event->button.button, event->button.x,
+                event->button.y, event->button.windowID);
+        break;
+    case SDL_MOUSEWHEEL:
+        fprintf(stderr, "Mouse %d: wheel scrolled %d in window %d",
+                event->wheel.which, event->wheel.motion,
+                event->button.windowID);
+        break;
+    case SDL_JOYBALLMOTION:
+        fprintf(stderr, "Joystick %d: ball %d moved by %d,%d",
+                event->jball.which, event->jball.ball, event->jball.xrel,
+                event->jball.yrel);
+        break;
+    case SDL_JOYHATMOTION:
+        fprintf(stderr, "Joystick %d: hat %d moved to ", event->jhat.which,
+                event->jhat.hat);
+        switch (event->jhat.value) {
+        case SDL_HAT_CENTERED:
+            fprintf(stderr, "CENTER");
+            break;
+        case SDL_HAT_UP:
+            fprintf(stderr, "UP");
+            break;
+        case SDL_HAT_RIGHTUP:
+            fprintf(stderr, "RIGHTUP");
+            break;
+        case SDL_HAT_RIGHT:
+            fprintf(stderr, "RIGHT");
+            break;
+        case SDL_HAT_RIGHTDOWN:
+            fprintf(stderr, "RIGHTDOWN");
+            break;
+        case SDL_HAT_DOWN:
+            fprintf(stderr, "DOWN");
+            break;
+        case SDL_HAT_LEFTDOWN:
+            fprintf(stderr, "LEFTDOWN");
+            break;
+        case SDL_HAT_LEFT:
+            fprintf(stderr, "LEFT");
+            break;
+        case SDL_HAT_LEFTUP:
+            fprintf(stderr, "LEFTUP");
+            break;
+        default:
+            fprintf(stderr, "UNKNOWN");
+            break;
+        }
+        break;
+    case SDL_JOYBUTTONDOWN:
+        fprintf(stderr, "Joystick %d: button %d pressed",
+                event->jbutton.which, event->jbutton.button);
+        break;
+    case SDL_JOYBUTTONUP:
+        fprintf(stderr, "Joystick %d: button %d released",
+                event->jbutton.which, event->jbutton.button);
+        break;
+    case SDL_QUIT:
+        fprintf(stderr, "Quit requested");
+        break;
+    case SDL_USEREVENT:
+        fprintf(stderr, "User event %d", event->user.code);
+        break;
+    default:
+        fprintf(stderr, "Unknown event %d", event->type);
+        break;
+    }
+    fprintf(stderr, "\n");
+}
+
+void
+CommonEvent(CommonState * state, SDL_Event * event, int *done)
+{
+    if (state->verbose & VERBOSE_EVENT) {
+        PrintEvent(event);
+    }
+
+    switch (event->type) {
+    case SDL_WINDOWEVENT:
+        switch (event->window.event) {
+        case SDL_WINDOWEVENT_CLOSE:
+            *done = 1;
+            break;
+        }
+        break;
+    case SDL_KEYDOWN:
+        switch (event->key.keysym.sym) {
+            /* Add hotkeys here */
+        case SDLK_ESCAPE:
+            *done = 1;
+            break;
+        default:
+            break;
+        }
+        break;
+    case SDL_QUIT:
+        *done = 1;
+        break;
+    }
+}
+
+void
+CommonQuit(CommonState * state)
+{
+    if (state->flags & SDL_INIT_VIDEO) {
+        SDL_VideoQuit();
+    }
+    if (state->flags & SDL_INIT_AUDIO) {
+        SDL_AudioQuit();
+    }
+    if (state->windows) {
+        SDL_free(state->windows);
+    }
+    SDL_free(state);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/common.h	Tue Jul 18 07:49:51 2006 +0000
@@ -0,0 +1,47 @@
+
+/* A simple test program framework */
+
+#include "SDL.h"
+
+#define VERBOSE_VIDEO   0x00000001
+#define VERBOSE_MODES   0x00000002
+#define VERBOSE_RENDER  0x00000004
+#define VERBOSE_EVENT   0x00000008
+#define VERBOSE_AUDIO   0x00000010
+
+typedef struct
+{
+    /* SDL init flags */
+    char **argv;
+    Uint32 flags;
+    Uint32 verbose;
+
+    /* Video info */
+    const char *videodriver;
+    int display;
+    const char *window_title;
+    Uint32 window_flags;
+    int window_x;
+    int window_y;
+    int window_w;
+    int window_h;
+    int depth;
+    int refresh_rate;
+    int num_windows;
+    SDL_WindowID *windows;
+
+    /* Renderer info */
+    const char *renderdriver;
+    Uint32 render_flags;
+
+    /* Audio info */
+    const char *audiodriver;
+    SDL_AudioSpec audiospec;
+} CommonState;
+
+extern CommonState *CommonCreateState(char **argv, Uint32 flags);
+extern int CommonArg(CommonState * state, int index);
+extern const char *CommonUsage(CommonState * state);
+extern SDL_bool CommonInit(CommonState * state);
+extern void CommonEvent(CommonState * state, SDL_Event * event, int *done);
+extern void CommonQuit(CommonState * state);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/testgl2.c	Tue Jul 18 07:49:51 2006 +0000
@@ -0,0 +1,770 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+
+#include "SDL.h"
+
+#ifdef __MACOS__
+#define HAVE_OPENGL
+#endif
+
+#ifdef HAVE_OPENGL
+
+#include "SDL_opengl.h"
+
+/* Undefine this if you want a flat cube instead of a rainbow cube */
+#define SHADED_CUBE
+
+/* Define this to be the name of the logo image to use with -logo */
+#define LOGO_FILE	"icon.bmp"
+
+static SDL_Surface *global_image = NULL;
+static GLuint global_texture = 0;
+static GLuint cursor_texture = 0;
+
+/**********************************************************************/
+
+void
+HotKey_ToggleFullScreen(void)
+{
+    SDL_Surface *screen;
+
+    screen = SDL_GetVideoSurface();
+    if (SDL_WM_ToggleFullScreen(screen)) {
+        printf("Toggled fullscreen mode - now %s\n",
+               (screen->flags & SDL_FULLSCREEN) ? "fullscreen" : "windowed");
+    } else {
+        printf("Unable to toggle fullscreen mode\n");
+    }
+}
+
+void
+HotKey_ToggleGrab(void)
+{
+    SDL_GrabMode mode;
+
+    printf("Ctrl-G: toggling input grab!\n");
+    mode = SDL_WM_GrabInput(SDL_GRAB_QUERY);
+    if (mode == SDL_GRAB_ON) {
+        printf("Grab was on\n");
+    } else {
+        printf("Grab was off\n");
+    }
+    mode = SDL_WM_GrabInput(!mode);
+    if (mode == SDL_GRAB_ON) {
+        printf("Grab is now on\n");
+    } else {
+        printf("Grab is now off\n");
+    }
+}
+
+void
+HotKey_Iconify(void)
+{
+    printf("Ctrl-Z: iconifying window!\n");
+    SDL_WM_IconifyWindow();
+}
+
+int
+HandleEvent(SDL_Event * event)
+{
+    int done;
+
+    done = 0;
+    switch (event->type) {
+    case SDL_ACTIVEEVENT:
+        /* See what happened */
+        printf("app %s ", event->active.gain ? "gained" : "lost");
+        if (event->active.state & SDL_APPACTIVE) {
+            printf("active ");
+        } else if (event->active.state & SDL_APPMOUSEFOCUS) {
+            printf("mouse ");
+        } else if (event->active.state & SDL_APPINPUTFOCUS) {
+            printf("input ");
+        }
+        printf("focus\n");
+        break;
+
+
+    case SDL_KEYDOWN:
+        if (event->key.keysym.sym == SDLK_ESCAPE) {
+            done = 1;
+        }
+        if ((event->key.keysym.sym == SDLK_g) &&
+            (event->key.keysym.mod & KMOD_CTRL)) {
+            HotKey_ToggleGrab();
+        }
+        if ((event->key.keysym.sym == SDLK_z) &&
+            (event->key.keysym.mod & KMOD_CTRL)) {
+            HotKey_Iconify();
+        }
+        if ((event->key.keysym.sym == SDLK_RETURN) &&
+            (event->key.keysym.mod & KMOD_ALT)) {
+            HotKey_ToggleFullScreen();
+        }
+        printf("key '%s' pressed\n", SDL_GetKeyName(event->key.keysym.sym));
+        break;
+    case SDL_QUIT:
+        done = 1;
+        break;
+    }
+    return (done);
+}
+
+void
+SDL_GL_Enter2DMode()
+{
+    SDL_Surface *screen = SDL_GetVideoSurface();
+
+    /* Note, there may be other things you need to change,
+       depending on how you have your OpenGL state set up.
+     */
+    glPushAttrib(GL_ENABLE_BIT);
+    glDisable(GL_DEPTH_TEST);
+    glDisable(GL_CULL_FACE);
+    glEnable(GL_TEXTURE_2D);
+
+    /* This allows alpha blending of 2D textures with the scene */
+    glEnable(GL_BLEND);
+    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+    glViewport(0, 0, screen->w, screen->h);
+
+    glMatrixMode(GL_PROJECTION);
+    glPushMatrix();
+    glLoadIdentity();
+
+    glOrtho(0.0, (GLdouble) screen->w, (GLdouble) screen->h, 0.0, 0.0, 1.0);
+
+    glMatrixMode(GL_MODELVIEW);
+    glPushMatrix();
+    glLoadIdentity();
+
+    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
+}
+
+void
+SDL_GL_Leave2DMode()
+{
+    glMatrixMode(GL_MODELVIEW);
+    glPopMatrix();
+
+    glMatrixMode(GL_PROJECTION);
+    glPopMatrix();
+
+    glPopAttrib();
+}
+
+/* Quick utility function for texture creation */
+static int
+power_of_two(int input)
+{
+    int value = 1;
+
+    while (value < input) {
+        value <<= 1;
+    }
+    return value;
+}
+
+GLuint
+SDL_GL_LoadTexture(SDL_Surface * surface, GLfloat * texcoord)
+{
+    GLuint texture;
+    int w, h;
+    SDL_Surface *image;
+    SDL_Rect area;
+    Uint32 saved_flags;
+    Uint8 saved_alpha;
+
+    /* Use the surface width and height expanded to powers of 2 */
+    w = power_of_two(surface->w);
+    h = power_of_two(surface->h);
+    texcoord[0] = 0.0f;         /* Min X */
+    texcoord[1] = 0.0f;         /* Min Y */
+    texcoord[2] = (GLfloat) surface->w / w;     /* Max X */
+    texcoord[3] = (GLfloat) surface->h / h;     /* Max Y */
+
+    image = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32,
+#if SDL_BYTEORDER == SDL_LIL_ENDIAN     /* OpenGL RGBA masks */
+                                 0x000000FF,
+                                 0x0000FF00, 0x00FF0000, 0xFF000000
+#else
+                                 0xFF000000,
+                                 0x00FF0000, 0x0000FF00, 0x000000FF
+#endif
+        );
+    if (image == NULL) {
+        return 0;
+    }
+
+    /* Save the alpha blending attributes */
+    saved_flags = surface->flags & (SDL_SRCALPHA | SDL_RLEACCELOK);
+    saved_alpha = surface->format->alpha;
+    if ((saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA) {
+        SDL_SetAlpha(surface, 0, 0);
+    }
+
+    /* Copy the surface into the GL texture image */
+    area.x = 0;
+    area.y = 0;
+    area.w = surface->w;
+    area.h = surface->h;
+    SDL_BlitSurface(surface, &area, image, &area);
+
+    /* Restore the alpha blending attributes */
+    if ((saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA) {
+        SDL_SetAlpha(surface, saved_flags, saved_alpha);
+    }
+
+    /* Create an OpenGL texture for the image */
+    glGenTextures(1, &texture);
+    glBindTexture(GL_TEXTURE_2D, texture);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexImage2D(GL_TEXTURE_2D,
+                 0,
+                 GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, image->pixels);
+    SDL_FreeSurface(image);     /* No longer needed */
+
+    return texture;
+}
+
+void
+DrawLogoCursor(void)
+{
+    static GLfloat texMinX, texMinY;
+    static GLfloat texMaxX, texMaxY;
+    static int w, h;
+    int x, y;
+
+    if (!cursor_texture) {
+        SDL_Surface *image;
+        GLfloat texcoord[4];
+
+        /* Load the image (could use SDL_image library here) */
+        image = SDL_LoadBMP(LOGO_FILE);
+        if (image == NULL) {
+            return;
+        }
+        w = image->w;
+        h = image->h;
+
+        /* Convert the image into an OpenGL texture */
+        cursor_texture = SDL_GL_LoadTexture(image, texcoord);
+
+        /* Make texture coordinates easy to understand */
+        texMinX = texcoord[0];
+        texMinY = texcoord[1];
+        texMaxX = texcoord[2];
+        texMaxY = texcoord[3];
+
+        /* We don't need the original image anymore */
+        SDL_FreeSurface(image);
+
+        /* Make sure that the texture conversion is okay */
+        if (!cursor_texture) {
+            return;
+        }
+    }
+
+    /* Move the image around */
+    SDL_GetMouseState(&x, &y);
+    x -= w / 2;
+    y -= h / 2;
+
+    /* Show the image on the screen */
+    SDL_GL_Enter2DMode();
+    glBindTexture(GL_TEXTURE_2D, cursor_texture);
+    glBegin(GL_TRIANGLE_STRIP);
+    glTexCoord2f(texMinX, texMinY);
+    glVertex2i(x, y);
+    glTexCoord2f(texMaxX, texMinY);
+    glVertex2i(x + w, y);
+    glTexCoord2f(texMinX, texMaxY);
+    glVertex2i(x, y + h);
+    glTexCoord2f(texMaxX, texMaxY);
+    glVertex2i(x + w, y + h);
+    glEnd();
+    SDL_GL_Leave2DMode();
+}
+
+void
+DrawLogoTexture(void)
+{
+    static GLfloat texMinX, texMinY;
+    static GLfloat texMaxX, texMaxY;
+    static int x = 0;
+    static int y = 0;
+    static int w, h;
+    static int delta_x = 1;
+    static int delta_y = 1;
+
+    SDL_Surface *screen = SDL_GetVideoSurface();
+
+    if (!global_texture) {
+        SDL_Surface *image;
+        GLfloat texcoord[4];
+
+        /* Load the image (could use SDL_image library here) */
+        image = SDL_LoadBMP(LOGO_FILE);
+        if (image == NULL) {
+            return;
+        }
+        w = image->w;
+        h = image->h;
+
+        /* Convert the image into an OpenGL texture */
+        global_texture = SDL_GL_LoadTexture(image, texcoord);
+
+        /* Make texture coordinates easy to understand */
+        texMinX = texcoord[0];
+        texMinY = texcoord[1];
+        texMaxX = texcoord[2];
+        texMaxY = texcoord[3];
+
+        /* We don't need the original image anymore */
+        SDL_FreeSurface(image);
+
+        /* Make sure that the texture conversion is okay */
+        if (!global_texture) {
+            return;
+        }
+    }
+
+    /* Move the image around */
+    x += delta_x;
+    if (x < 0) {
+        x = 0;
+        delta_x = -delta_x;
+    } else if ((x + w) > screen->w) {
+        x = screen->w - w;
+        delta_x = -delta_x;
+    }
+    y += delta_y;
+    if (y < 0) {
+        y = 0;
+        delta_y = -delta_y;
+    } else if ((y + h) > screen->h) {
+        y = screen->h - h;
+        delta_y = -delta_y;
+    }
+
+    /* Show the image on the screen */
+    SDL_GL_Enter2DMode();
+    glBindTexture(GL_TEXTURE_2D, global_texture);
+    glBegin(GL_TRIANGLE_STRIP);
+    glTexCoord2f(texMinX, texMinY);
+    glVertex2i(x, y);
+    glTexCoord2f(texMaxX, texMinY);
+    glVertex2i(x + w, y);
+    glTexCoord2f(texMinX, texMaxY);
+    glVertex2i(x, y + h);
+    glTexCoord2f(texMaxX, texMaxY);
+    glVertex2i(x + w, y + h);
+    glEnd();
+    SDL_GL_Leave2DMode();
+}
+
+int
+RunGLTest(int argc, char *argv[],
+          int logo, int logocursor, int slowly, int bpp, float gamma,
+          int noframe, int fsaa, int sync, int accel)
+{
+    int i;
+    int rgb_size[3];
+    int w = 640;
+    int h = 480;
+    int done = 0;
+    int frames;
+    Uint32 start_time, this_time;
+    float color[8][3] = { {1.0, 1.0, 0.0},
+    {1.0, 0.0, 0.0},
+    {0.0, 0.0, 0.0},
+    {0.0, 1.0, 0.0},
+    {0.0, 1.0, 1.0},
+    {1.0, 1.0, 1.0},
+    {1.0, 0.0, 1.0},
+    {0.0, 0.0, 1.0}
+    };
+    float cube[8][3] = { {0.5, 0.5, -0.5},
+    {0.5, -0.5, -0.5},
+    {-0.5, -0.5, -0.5},
+    {-0.5, 0.5, -0.5},
+    {-0.5, 0.5, 0.5},
+    {0.5, 0.5, 0.5},
+    {0.5, -0.5, 0.5},
+    {-0.5, -0.5, 0.5}
+    };
+    Uint32 video_flags;
+    int value;
+
+    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
+        fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError());
+        exit(1);
+    }
+
+    /* See if we should detect the display depth */
+    if (bpp == 0) {
+        if (SDL_GetVideoInfo()->vfmt->BitsPerPixel <= 8) {
+            bpp = 8;
+        } else {
+            bpp = 16;           /* More doesn't seem to work */
+        }
+    }
+
+    /* Set the flags we want to use for setting the video mode */
+    video_flags = SDL_OPENGL;
+    for (i = 1; argv[i]; ++i) {
+        if (strcmp(argv[i], "-fullscreen") == 0) {
+            video_flags |= SDL_FULLSCREEN;
+        }
+    }
+
+    if (noframe) {
+        video_flags |= SDL_NOFRAME;
+    }
+
+    /* Initialize the display */
+    switch (bpp) {
+    case 8:
+        rgb_size[0] = 3;
+        rgb_size[1] = 3;
+        rgb_size[2] = 2;
+        break;
+    case 15:
+    case 16:
+        rgb_size[0] = 5;
+        rgb_size[1] = 5;
+        rgb_size[2] = 5;
+        break;
+    default:
+        rgb_size[0] = 8;
+        rgb_size[1] = 8;
+        rgb_size[2] = 8;
+        break;
+    }
+    SDL_GL_SetAttribute(SDL_GL_RED_SIZE, rgb_size[0]);
+    SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, rgb_size[1]);
+    SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, rgb_size[2]);
+    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
+    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+    if (fsaa) {
+        SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
+        SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, fsaa);
+    }
+    if (accel) {
+        SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
+    }
+    if (SDL_SetVideoMode(w, h, bpp, video_flags) == NULL) {
+        fprintf(stderr, "Couldn't set GL mode: %s\n", SDL_GetError());
+        SDL_Quit();
+        exit(1);
+    }
+    if (sync) {
+        SDL_GL_SetSwapInterval(1);
+    } else {
+        SDL_GL_SetSwapInterval(0);
+    }
+
+    printf("Screen BPP: %d\n", SDL_GetVideoSurface()->format->BitsPerPixel);
+    printf("\n");
+    printf("Vendor     : %s\n", glGetString(GL_VENDOR));
+    printf("Renderer   : %s\n", glGetString(GL_RENDERER));
+    printf("Version    : %s\n", glGetString(GL_VERSION));
+    printf("Extensions : %s\n", glGetString(GL_EXTENSIONS));
+    printf("\n");
+
+    SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &value);
+    printf("SDL_GL_RED_SIZE: requested %d, got %d\n", rgb_size[0], value);
+    SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &value);
+    printf("SDL_GL_GREEN_SIZE: requested %d, got %d\n", rgb_size[1], value);
+    SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &value);
+    printf("SDL_GL_BLUE_SIZE: requested %d, got %d\n", rgb_size[2], value);
+    SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &value);
+    printf("SDL_GL_DEPTH_SIZE: requested %d, got %d\n", bpp, value);
+    SDL_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, &value);
+    printf("SDL_GL_DOUBLEBUFFER: requested 1, got %d\n", value);
+    if (fsaa) {
+        SDL_GL_GetAttribute(SDL_GL_MULTISAMPLEBUFFERS, &value);
+        printf("SDL_GL_MULTISAMPLEBUFFERS: requested 1, got %d\n", value);
+        SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &value);
+        printf("SDL_GL_MULTISAMPLESAMPLES: requested %d, got %d\n", fsaa,
+               value);
+    }
+    if (accel) {
+        SDL_GL_GetAttribute(SDL_GL_ACCELERATED_VISUAL, &value);
+        printf("SDL_GL_ACCELERATED_VISUAL: requested 1, got %d\n", value);
+    }
+    if (sync) {
+        printf("Buffer swap interval: requested 1, got %d\n",
+               SDL_GL_GetSwapInterval());
+    }
+
+    /* Set the window manager title bar */
+    SDL_WM_SetCaption("SDL GL test", "testgl");
+
+    /* Set the gamma for the window */
+    if (gamma != 0.0) {
+        SDL_SetGamma(gamma, gamma, gamma);
+    }
+
+    glViewport(0, 0, w, h);
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+
+    glOrtho(-2.0, 2.0, -2.0, 2.0, -20.0, 20.0);
+
+    glMatrixMode(GL_MODELVIEW);
+    glLoadIdentity();
+
+    glEnable(GL_DEPTH_TEST);
+
+    glDepthFunc(GL_LESS);
+
+    glShadeModel(GL_SMOOTH);
+
+    /* Loop until done. */
+    start_time = SDL_GetTicks();
+    frames = 0;
+    while (!done) {
+        GLenum gl_error;
+        char *sdl_error;
+        SDL_Event event;
+
+        /* Do our drawing, too. */
+        glClearColor(0.0, 0.0, 0.0, 1.0);
+        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+        glBegin(GL_QUADS);
+
+#ifdef SHADED_CUBE
+        glColor3fv(color[0]);
+        glVertex3fv(cube[0]);
+        glColor3fv(color[1]);
+        glVertex3fv(cube[1]);
+        glColor3fv(color[2]);
+        glVertex3fv(cube[2]);
+        glColor3fv(color[3]);
+        glVertex3fv(cube[3]);
+
+        glColor3fv(color[3]);
+        glVertex3fv(cube[3]);
+        glColor3fv(color[4]);
+        glVertex3fv(cube[4]);
+        glColor3fv(color[7]);
+        glVertex3fv(cube[7]);
+        glColor3fv(color[2]);
+        glVertex3fv(cube[2]);
+
+        glColor3fv(color[0]);
+        glVertex3fv(cube[0]);
+        glColor3fv(color[5]);
+        glVertex3fv(cube[5]);
+        glColor3fv(color[6]);
+        glVertex3fv(cube[6]);
+        glColor3fv(color[1]);
+        glVertex3fv(cube[1]);
+
+        glColor3fv(color[5]);
+        glVertex3fv(cube[5]);
+        glColor3fv(color[4]);
+        glVertex3fv(cube[4]);
+        glColor3fv(color[7]);
+        glVertex3fv(cube[7]);
+        glColor3fv(color[6]);
+        glVertex3fv(cube[6]);
+
+        glColor3fv(color[5]);
+        glVertex3fv(cube[5]);
+        glColor3fv(color[0]);
+        glVertex3fv(cube[0]);
+        glColor3fv(color[3]);
+        glVertex3fv(cube[3]);
+        glColor3fv(color[4]);
+        glVertex3fv(cube[4]);
+
+        glColor3fv(color[6]);
+        glVertex3fv(cube[6]);
+        glColor3fv(color[1]);
+        glVertex3fv(cube[1]);
+        glColor3fv(color[2]);
+        glVertex3fv(cube[2]);
+        glColor3fv(color[7]);
+        glVertex3fv(cube[7]);
+#else /* flat cube */
+        glColor3f(1.0, 0.0, 0.0);
+        glVertex3fv(cube[0]);
+        glVertex3fv(cube[1]);
+        glVertex3fv(cube[2]);
+        glVertex3fv(cube[3]);
+
+        glColor3f(0.0, 1.0, 0.0);
+        glVertex3fv(cube[3]);
+        glVertex3fv(cube[4]);
+        glVertex3fv(cube[7]);
+        glVertex3fv(cube[2]);
+
+        glColor3f(0.0, 0.0, 1.0);
+        glVertex3fv(cube[0]);
+        glVertex3fv(cube[5]);
+        glVertex3fv(cube[6]);
+        glVertex3fv(cube[1]);
+
+        glColor3f(0.0, 1.0, 1.0);
+        glVertex3fv(cube[5]);
+        glVertex3fv(cube[4]);
+        glVertex3fv(cube[7]);
+        glVertex3fv(cube[6]);
+
+        glColor3f(1.0, 1.0, 0.0);
+        glVertex3fv(cube[5]);
+        glVertex3fv(cube[0]);
+        glVertex3fv(cube[3]);
+        glVertex3fv(cube[4]);
+
+        glColor3f(1.0, 0.0, 1.0);
+        glVertex3fv(cube[6]);
+        glVertex3fv(cube[1]);
+        glVertex3fv(cube[2]);
+        glVertex3fv(cube[7]);
+#endif /* SHADED_CUBE */
+
+        glEnd();
+
+        glMatrixMode(GL_MODELVIEW);
+        glRotatef(5.0, 1.0, 1.0, 1.0);
+
+        /* Draw 2D logo onto the 3D display */
+        if (logo) {
+            DrawLogoTexture();
+        }
+        if (logocursor) {
+            DrawLogoCursor();
+        }
+
+        SDL_GL_SwapBuffers();
+
+        /* Check for error conditions. */
+        gl_error = glGetError();
+
+        if (gl_error != GL_NO_ERROR) {
+            fprintf(stderr, "testgl: OpenGL error: %d\n", gl_error);
+        }
+
+        sdl_error = SDL_GetError();
+
+        if (sdl_error[0] != '\0') {
+            fprintf(stderr, "testgl: SDL error '%s'\n", sdl_error);
+            SDL_ClearError();
+        }
+
+        /* Allow the user to see what's happening */
+        if (slowly) {
+            SDL_Delay(20);
+        }
+
+        /* Check if there's a pending event. */
+        while (SDL_PollEvent(&event)) {
+            done = HandleEvent(&event);
+        }
+        ++frames;
+    }
+
+    /* Print out the frames per second */
+    this_time = SDL_GetTicks();
+    if (this_time != start_time) {
+        printf("%2.2f FPS\n",
+               ((float) frames / (this_time - start_time)) * 1000.0);
+    }
+
+    if (global_image) {
+        SDL_FreeSurface(global_image);
+        global_image = NULL;
+    }
+    if (global_texture) {
+        glDeleteTextures(1, &global_texture);
+        global_texture = 0;
+    }
+    if (cursor_texture) {
+        glDeleteTextures(1, &cursor_texture);
+        cursor_texture = 0;
+    }
+
+    /* Destroy our GL context, etc. */
+    SDL_Quit();
+    return (0);
+}
+
+int
+main(int argc, char *argv[])
+{
+    int i, logo, logocursor = 0;
+    int numtests;
+    int bpp = 0;
+    int slowly;
+    float gamma = 0.0;
+    int noframe = 0;
+    int fsaa = 0;
+    int accel = 0;
+    int sync = 0;
+
+    logo = 0;
+    slowly = 0;
+    numtests = 1;
+    for (i = 1; argv[i]; ++i) {
+        if (strcmp(argv[i], "-twice") == 0) {
+            ++numtests;
+        }
+        if (strcmp(argv[i], "-logo") == 0) {
+            logo = 1;
+        }
+        if (strcmp(argv[i], "-logocursor") == 0) {
+            logocursor = 1;
+        }
+        if (strcmp(argv[i], "-slow") == 0) {
+            slowly = 1;
+        }
+        if (strcmp(argv[i], "-bpp") == 0) {
+            bpp = atoi(argv[++i]);
+        }
+        if (strcmp(argv[i], "-gamma") == 0) {
+            gamma = (float) atof(argv[++i]);
+        }
+        if (strcmp(argv[i], "-noframe") == 0) {
+            noframe = 1;
+        }
+        if (strcmp(argv[i], "-fsaa") == 0) {
+            ++fsaa;
+        }
+        if (strcmp(argv[i], "-accel") == 0) {
+            ++accel;
+        }
+        if (strcmp(argv[i], "-sync") == 0) {
+            ++sync;
+        }
+        if (strncmp(argv[i], "-h", 2) == 0) {
+            printf
+                ("Usage: %s [-twice] [-logo] [-logocursor] [-slow] [-bpp n] [-gamma n] [-noframe] [-fsaa] [-accel] [-sync] [-fullscreen]\n",
+                 argv[0]);
+            exit(0);
+        }
+    }
+    for (i = 0; i < numtests; ++i) {
+        RunGLTest(argc, argv, logo, logocursor, slowly, bpp, gamma,
+                  noframe, fsaa, sync, accel);
+    }
+    return 0;
+}
+
+#else /* HAVE_OPENGL */
+
+int
+main(int argc, char *argv[])
+{
+    printf("No OpenGL support on this system\n");
+    return 1;
+}
+
+#endif /* HAVE_OPENGL */
--- a/test/testsprite2.c	Mon Jul 17 06:47:33 2006 +0000
+++ b/test/testsprite2.c	Tue Jul 18 07:49:51 2006 +0000
@@ -4,18 +4,14 @@
 #include <stdio.h>
 #include <time.h>
 
-#include "SDL.h"
+#include "common.h"
 
-#define NUM_WINDOWS 4
-#define WINDOW_W    640
-#define WINDOW_H    480
 #define NUM_SPRITES	100
 #define MAX_SPEED 	1
 #define BACKGROUND  0x00FFFFFF
 
-static int num_windows;
+static CommonState *state;
 static int num_sprites;
-static SDL_WindowID *windows;
 static SDL_TextureID *sprites;
 static SDL_Rect *positions;
 static SDL_Rect *velocities;
@@ -25,9 +21,6 @@
 static void
 quit(int rc)
 {
-    if (windows) {
-        SDL_free(windows);
-    }
     if (sprites) {
         SDL_free(sprites);
     }
@@ -37,7 +30,7 @@
     if (velocities) {
         SDL_free(velocities);
     }
-    SDL_Quit();
+    CommonQuit(state);
     exit(rc);
 }
 
@@ -62,8 +55,8 @@
     }
 
     /* Create textures from the image */
-    for (i = 0; i < num_windows; ++i) {
-        SDL_SelectRenderer(windows[i]);
+    for (i = 0; i < state->num_windows; ++i) {
+        SDL_SelectRenderer(state->windows[i]);
         sprites[i] =
             SDL_CreateTextureFromSurface(0, SDL_TextureAccess_Remote, temp);
         if (!sprites[i]) {
@@ -125,78 +118,45 @@
 int
 main(int argc, char *argv[])
 {
-    int window_w, window_h;
-    Uint32 window_flags = SDL_WINDOW_SHOWN;
-    Uint32 render_flags = 0;
-    SDL_DisplayMode *mode, fullscreen_mode;
     int i, done;
     SDL_Event event;
     Uint32 then, now, frames;
 
-    /* Initialize SDL */
-    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
-        fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError());
-        return (1);
-    }
-
-    num_windows = NUM_WINDOWS;
+    /* Initialize parameters */
     num_sprites = NUM_SPRITES;
-    window_w = WINDOW_W;
-    window_h = WINDOW_H;
-    for (i = 1; i < argc; ++i) {
-        if (strcmp(argv[i], "-width") == 0 && (i + 1 < argc)) {
-            window_w = atoi(argv[++i]);
-        } else if (strcmp(argv[i], "-height") == 0 && (i + 1 < argc)) {
-            window_h = atoi(argv[++i]);
-        } else if (strcmp(argv[i], "-windows") == 0 && (i + 1 < argc)) {
-            num_windows = atoi(argv[++i]);
-            window_flags &= ~SDL_WINDOW_FULLSCREEN;
-        } else if (strcmp(argv[i], "-fullscreen") == 0) {
-            num_windows = 1;
-            window_flags |= SDL_WINDOW_FULLSCREEN;
-        } else if (strcmp(argv[i], "-sync") == 0) {
-            render_flags |= SDL_Renderer_PresentVSync;
-        } else if (isdigit(argv[i][0])) {
-            num_sprites = atoi(argv[i]);
-        } else {
-            fprintf(stderr,
-                    "Usage: %s [-width N] [-height N] [-windows N] [-fullscreen] [-sync] [numsprites]\n",
-                    argv[0]);
+
+    /* Initialize test framework */
+    state = CommonCreateState(argv, SDL_INIT_VIDEO);
+    if (!state) {
+        return 1;
+    }
+    for (i = 1; i < argc;) {
+        int consumed;
+
+        consumed = CommonArg(state, i);
+        if (consumed < 0) {
+            fprintf(stderr, "Usage: %s %s", argv[0], CommonUsage(state));
             quit(1);
         }
+        if (consumed == 0) {
+            num_sprites = SDL_atoi(argv[i]);
+            consumed = 1;
+        }
+        i += consumed;
     }
-
-    if (window_flags & SDL_WINDOW_FULLSCREEN) {
-        SDL_zero(fullscreen_mode);
-        fullscreen_mode.w = window_w;
-        fullscreen_mode.h = window_h;
-        SDL_SetFullscreenDisplayMode(&fullscreen_mode);
+    if (!CommonInit(state)) {
+        quit(2);
     }
 
     /* Create the windows, initialize the renderers, and load the textures */
-    windows = (SDL_WindowID *) SDL_malloc(num_windows * sizeof(*windows));
-    sprites = (SDL_TextureID *) SDL_malloc(num_windows * sizeof(*sprites));
-    if (!windows || !sprites) {
+    sprites =
+        (SDL_TextureID *) SDL_malloc(state->num_windows * sizeof(*sprites));
+    if (!sprites) {
         fprintf(stderr, "Out of memory!\n");
         quit(2);
     }
-    for (i = 0; i < num_windows; ++i) {
-        char title[32];
-
-        SDL_snprintf(title, sizeof(title), "testsprite %d", i + 1);
-        windows[i] =
-            SDL_CreateWindow(title, SDL_WINDOWPOS_UNDEFINED,
-                             SDL_WINDOWPOS_UNDEFINED, window_w, window_h,
-                             window_flags);
-        if (!windows[i]) {
-            fprintf(stderr, "Couldn't create window: %s\n", SDL_GetError());
-            quit(2);
-        }
-
-        if (SDL_CreateRenderer(windows[i], -1, render_flags) < 0) {
-            fprintf(stderr, "Couldn't create renderer: %s\n", SDL_GetError());
-            quit(2);
-        }
+    for (i = 0; i < state->num_windows; ++i) {
+        SDL_SelectRenderer(state->windows[i]);
         SDL_RenderFill(NULL, BACKGROUND);
     }
     if (LoadSprite("icon.bmp") < 0) {
@@ -212,8 +172,8 @@
     }
     srand(time(NULL));
     for (i = 0; i < num_sprites; ++i) {
-        positions[i].x = rand() % (window_w - sprite_w);
-        positions[i].y = rand() % (window_h - sprite_h);
+        positions[i].x = rand() % (state->window_w - sprite_w);
+        positions[i].y = rand() % (state->window_h - sprite_h);
         positions[i].w = sprite_w;
         positions[i].h = sprite_h;
         velocities[i].x = 0;
@@ -232,6 +192,7 @@
         /* Check for events */
         ++frames;
         while (SDL_PollEvent(&event)) {
+            CommonEvent(state, &event, &done);
             switch (event.type) {
             case SDL_WINDOWEVENT:
                 switch (event.window.event) {
@@ -239,22 +200,14 @@
                     SDL_SelectRenderer(event.window.windowID);
                     SDL_RenderFill(NULL, BACKGROUND);
                     break;
-                case SDL_WINDOWEVENT_CLOSE:
-                    done = 1;
-                    break;
                 }
                 break;
-            case SDL_KEYDOWN:
-                /* Any keypress quits the app... */
-            case SDL_QUIT:
-                done = 1;
-                break;
             default:
                 break;
             }
         }
-        for (i = 0; i < num_windows; ++i) {
-            MoveSprites(windows[i], sprites[i]);
+        for (i = 0; i < state->num_windows; ++i) {
+            MoveSprites(state->windows[i], sprites[i]);
         }
     }