Proof of concept done - Win32 GDI implementation mostly complete. SDL-1.3
authorSam Lantinga <slouken@libsdl.org>
Thu, 06 Jul 2006 07:17:11 +0000
branchSDL-1.3
changeset 1724 6c63fc2bd986
parent 1723 4bdbb9b2bd0a
child 1725 98a3207ddde8
Proof of concept done - Win32 GDI implementation mostly complete.
configure.in
include/SDL_compat.h
include/SDL_events.h
include/SDL_keyboard.h
include/SDL_mouse.h
include/SDL_video.h
src/SDL_compat.c
src/events/SDL_events.c
src/events/SDL_events_c.h
src/events/SDL_keyboard.c
src/events/SDL_keyboard_c.h
src/events/SDL_mouse.c
src/events/SDL_mouse_c.h
src/events/SDL_windowevents.c
src/events/SDL_windowevents_c.h
src/video/SDL_surface.c
src/video/SDL_video.c
src/video/win32/SDL_dibrender.c
src/video/win32/SDL_dibrender.h
src/video/win32/SDL_vkeys.h
src/video/win32/SDL_win32events.c
src/video/win32/SDL_win32keyboard.c
src/video/win32/SDL_win32keyboard.h
src/video/win32/SDL_win32mouse.c
src/video/win32/SDL_win32mouse.h
src/video/win32/SDL_win32video.c
src/video/win32/SDL_win32video.h
src/video/win32/SDL_win32window.c
src/video/win32/SDL_win32window.h
src/video/win32/wmmsg.h
test/graywin.c
test/testsprite2.c
test/testwm.c
test/threadwin.c
--- a/configure.in	Thu Jul 06 05:53:32 2006 +0000
+++ b/configure.in	Thu Jul 06 07:17:11 2006 +0000
@@ -2347,7 +2347,7 @@
             have_loadso=yes
         fi
         # Set up the system libraries we need
-        EXTRA_LDFLAGS="$EXTRA_LDFLAGS -luser32 -lgdi32 -lwinmm"
+        EXTRA_LDFLAGS="$EXTRA_LDFLAGS -luser32 -lgdi32 -lmsimg32 -lwinmm"
         # The Win32 platform requires special setup
         SDLMAIN_SOURCES="$srcdir/src/main/win32/*.c"
         SDL_CFLAGS="$SDL_CFLAGS -Dmain=SDL_main"
--- a/include/SDL_compat.h	Thu Jul 06 05:53:32 2006 +0000
+++ b/include/SDL_compat.h	Thu Jul 06 07:17:11 2006 +0000
@@ -57,6 +57,12 @@
 #define SDL_ACTIVEEVENT	SDL_EVENT_RESERVED1
 #define SDL_VIDEORESIZE	SDL_EVENT_RESERVED2
 #define SDL_VIDEOEXPOSE	SDL_EVENT_RESERVED3
+#define SDL_ACTIVEEVENTMASK	SDL_EVENTMASK(SDL_ACTIVEEVENT)
+#define SDL_VIDEORESIZEMASK SDL_EVENTMASK(SDL_VIDEORESIZE)
+#define SDL_VIDEOEXPOSEMASK SDL_EVENTMASK(SDL_VIDEOEXPOSE)
+
+#define SDL_BUTTON_WHEELUP	4
+#define SDL_BUTTON_WHEELDOWN	5
 
 typedef struct SDL_VideoInfo
 {
--- a/include/SDL_events.h	Thu Jul 06 05:53:32 2006 +0000
+++ b/include/SDL_events.h	Thu Jul 06 07:17:11 2006 +0000
@@ -60,9 +60,11 @@
     SDL_WINDOWEVENT,            /**< Window state change */
     SDL_KEYDOWN,                /**< Keys pressed */
     SDL_KEYUP,                  /**< Keys released */
+    SDL_TEXTINPUT,                              /**< Keyboard text input */
     SDL_MOUSEMOTION,            /**< Mouse moved */
     SDL_MOUSEBUTTONDOWN,        /**< Mouse button pressed */
     SDL_MOUSEBUTTONUP,          /**< Mouse button released */
+    SDL_MOUSEWHEEL,                             /**< Mouse wheel motion */
     SDL_JOYAXISMOTION,          /**< Joystick axis motion */
     SDL_JOYBALLMOTION,          /**< Joystick trackball motion */
     SDL_JOYHATMOTION,           /**< Joystick hat position change */
@@ -93,9 +95,11 @@
     SDL_KEYDOWNMASK = SDL_EVENTMASK(SDL_KEYDOWN),
     SDL_KEYUPMASK = SDL_EVENTMASK(SDL_KEYUP),
     SDL_KEYEVENTMASK = SDL_EVENTMASK(SDL_KEYDOWN) | SDL_EVENTMASK(SDL_KEYUP),
+    SDL_TEXTINPUTMASK = SDL_EVENTMASK(SDL_TEXTINPUT),
     SDL_MOUSEMOTIONMASK = SDL_EVENTMASK(SDL_MOUSEMOTION),
     SDL_MOUSEBUTTONDOWNMASK = SDL_EVENTMASK(SDL_MOUSEBUTTONDOWN),
     SDL_MOUSEBUTTONUPMASK = SDL_EVENTMASK(SDL_MOUSEBUTTONUP),
+    SDL_MOUSEWHEELMASK = SDL_EVENTMASK(SDL_MOUSEWHEEL),
     SDL_MOUSEEVENTMASK = SDL_EVENTMASK(SDL_MOUSEMOTION) |
         SDL_EVENTMASK(SDL_MOUSEBUTTONDOWN) | SDL_EVENTMASK(SDL_MOUSEBUTTONUP),
     SDL_JOYAXISMOTIONMASK = SDL_EVENTMASK(SDL_JOYAXISMOTION),
@@ -141,17 +145,17 @@
 } SDL_KeyboardEvent;
 
 /**
- * \struct SDL_CharEvent
+ * \struct SDL_TextInputEvent
  *
- * \brief Keyboard input event structure
+ * \brief Keyboard text input event structure
  */
-typedef struct SDL_CharEvent
+typedef struct SDL_TextInputEvent
 {
-    Uint8 type;             /**< SDL_CHARINPUT (FIXME: NYI) */
+    Uint8 type;             /**< SDL_TEXTINPUT */
     Uint8 which;            /**< The keyboard device index */
     char text[32];          /**< The input text */
     SDL_WindowID windowID;  /**< The window with keyboard focus, if any */
-} SDL_CharEvent;
+} SDL_TextInputEvent;
 
 /**
  * \struct SDL_MouseMotionEvent
@@ -187,6 +191,19 @@
 } SDL_MouseButtonEvent;
 
 /**
+ * \struct SDL_MouseWheelEvent
+ *
+ * \brief Mouse wheel event structure
+ */
+typedef struct SDL_MouseWheelEvent
+{
+    Uint8 type;             /**< SDL_MOUSEWHEEL */
+    Uint8 which;            /**< The mouse device index */
+    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
@@ -306,8 +323,10 @@
     Uint8 type;                     /**< Event type, shared with all events */
     SDL_WindowEvent window;         /**< Window event data */
     SDL_KeyboardEvent key;          /**< Keyboard event data */
+    SDL_TextInputEvent text;                    /**< Text input event data */
     SDL_MouseMotionEvent motion;    /**< Mouse motion event data */
     SDL_MouseButtonEvent button;    /**< Mouse button event data */
+    SDL_MouseWheelEvent wheel;                  /**< Mouse wheel event data */
     SDL_JoyAxisEvent jaxis;         /**< Joystick axis event data */
     SDL_JoyBallEvent jball;         /**< Joystick ball event data */
     SDL_JoyHatEvent jhat;           /**< Joystick hat event data */
@@ -353,6 +372,10 @@
                                            SDL_eventaction action,
                                            Uint32 mask);
 
+/* Checks to see if certain event types are in the event queue.
+ */
+extern DECLSPEC SDL_bool SDLCALL SDL_HasEvent(Uint32 mask);
+
 /* Polls for currently pending events, and returns 1 if there are any pending
    events, or 0 if there are none available.  If 'event' is not NULL, the next
    event is removed from the queue and stored in that area.
--- a/include/SDL_keyboard.h	Thu Jul 06 05:53:32 2006 +0000
+++ b/include/SDL_keyboard.h	Thu Jul 06 07:17:11 2006 +0000
@@ -52,7 +52,7 @@
     Uint8 padding[3];           /**< alignment padding */
     Uint16 sym;                 /**< SDL virtual keysym */
     Uint16 mod;                 /**< current key modifiers */
-    Uint32 unicode;             /**< OBSOLETE, use SDL_CharEvent instead */
+    Uint32 unicode;             /**< OBSOLETE, use SDL_TextInputEvent instead */
 } SDL_keysym;
 
 /* Function prototypes */
--- a/include/SDL_mouse.h	Thu Jul 06 05:53:32 2006 +0000
+++ b/include/SDL_mouse.h	Thu Jul 06 07:17:11 2006 +0000
@@ -202,15 +202,11 @@
    Button 1:	Left mouse button
    Button 2:	Middle mouse button
    Button 3:	Right mouse button
-   Button 4:	Mouse wheel up	 (may also be a real button)
-   Button 5:	Mouse wheel down (may also be a real button)
  */
 #define SDL_BUTTON(X)		(1 << ((X)-1))
 #define SDL_BUTTON_LEFT		1
 #define SDL_BUTTON_MIDDLE	2
 #define SDL_BUTTON_RIGHT	3
-#define SDL_BUTTON_WHEELUP	4
-#define SDL_BUTTON_WHEELDOWN	5
 #define SDL_BUTTON_LMASK	SDL_BUTTON(SDL_BUTTON_LEFT)
 #define SDL_BUTTON_MMASK	SDL_BUTTON(SDL_BUTTON_MIDDLE)
 #define SDL_BUTTON_RMASK	SDL_BUTTON(SDL_BUTTON_RIGHT)
--- a/include/SDL_video.h	Thu Jul 06 05:53:32 2006 +0000
+++ b/include/SDL_video.h	Thu Jul 06 07:17:11 2006 +0000
@@ -148,6 +148,7 @@
     SDL_WINDOWEVENT_NONE,               /**< Never used */
     SDL_WINDOWEVENT_SHOWN,              /**< Window has been shown */
     SDL_WINDOWEVENT_HIDDEN,             /**< Window has been hidden */
+    SDL_WINDOWEVENT_EXPOSED,            /**< Window has been exposed and should be redrawn */
     SDL_WINDOWEVENT_MOVED,              /**< Window has been moved to data1,data2 */
     SDL_WINDOWEVENT_RESIZED,            /**< Window size changed to data1xdata2 */
     SDL_WINDOWEVENT_MINIMIZED,          /**< Window has been minimized */
@@ -157,6 +158,7 @@
     SDL_WINDOWEVENT_LEAVE,              /**< The window has lost mouse focus */
     SDL_WINDOWEVENT_FOCUS_GAINED,       /**< The window has gained keyboard focus */
     SDL_WINDOWEVENT_FOCUS_LOST,         /**< The window has lost keyboard focus */
+    SDL_WINDOWEVENT_CLOSE,                              /**< The window manager requests that the window be closed */
 } SDL_WindowEventID;
 
 /**
@@ -1419,6 +1421,13 @@
  */
 extern DECLSPEC void SDLCALL SDL_GL_SwapBuffers(void);
 
+/*
+ * Calculate the intersection of two rectangles
+ */
+extern DECLSPEC SDL_bool SDLCALL SDL_IntersectRect(const SDL_Rect * A,
+                                                   const SDL_Rect * B,
+                                                   SDL_Rect * intersection);
+
 /* Ends C function definitions when using C++ */
 #ifdef __cplusplus
 /* *INDENT-OFF* */
--- a/src/SDL_compat.c	Thu Jul 06 05:53:32 2006 +0000
+++ b/src/SDL_compat.c	Thu Jul 06 07:17:11 2006 +0000
@@ -164,6 +164,12 @@
     switch (event->type) {
     case SDL_WINDOWEVENT:
         switch (event->window.event) {
+        case SDL_WINDOWEVENT_EXPOSED:
+            if (!SDL_HasEvent(SDL_VIDEOEXPOSEMASK)) {
+                fake.type = SDL_VIDEOEXPOSE;
+                SDL_PushEvent(&fake);
+            }
+            break;
         case SDL_WINDOWEVENT_RESIZED:
             fake.type = SDL_VIDEORESIZE;
             fake.resize.w = event->window.data1;
@@ -206,6 +212,10 @@
             fake.active.state = SDL_APPINPUTFOCUS;
             SDL_PushEvent(&fake);
             break;
+        case SDL_WINDOWEVENT_CLOSE:
+            fake.type = SDL_QUIT;
+            SDL_PushEvent(&fake);
+            break;
         }
     case SDL_KEYDOWN:
     case SDL_KEYUP:
@@ -226,6 +236,38 @@
             }
             break;
         }
+    case SDL_MOUSEWHEEL:
+        {
+            Uint8 button;
+            int selected;
+            int x, y;
+
+            selected = SDL_SelectMouse(event->wheel.which);
+            SDL_GetMouseState(&x, &y);
+            SDL_SelectMouse(selected);
+
+            if (event->wheel.motion > 0) {
+                button = SDL_BUTTON_WHEELUP;
+            } else {
+                button = SDL_BUTTON_WHEELDOWN;
+            }
+
+            fake.button.which = event->wheel.windowID;
+            fake.button.button = button;
+            fake.button.x = x;
+            fake.button.y = y;
+            fake.button.windowID = event->wheel.windowID;
+
+            fake.type = SDL_MOUSEBUTTONDOWN;
+            fake.button.state = SDL_PRESSED;
+            SDL_PushEvent(&fake);
+
+            fake.type = SDL_MOUSEBUTTONUP;
+            fake.button.state = SDL_RELEASED;
+            SDL_PushEvent(&fake);
+            break;
+        }
+
     }
     if (orig_eventfilter) {
         return orig_eventfilter(orig_eventfilterparam, event);
@@ -304,7 +346,9 @@
         window_flags |= SDL_WINDOW_BORDERLESS;
     }
     SDL_VideoWindow =
-        SDL_CreateWindow(wm_title, 0, 0, width, height, window_flags);
+        SDL_CreateWindow(wm_title, SDL_WINDOWPOS_UNDEFINED,
+                         SDL_WINDOWPOS_UNDEFINED, width, height,
+                         window_flags);
     if (!SDL_VideoWindow) {
         return NULL;
     }
--- a/src/events/SDL_events.c	Thu Jul 06 05:53:32 2006 +0000
+++ b/src/events/SDL_events.c	Thu Jul 06 07:17:11 2006 +0000
@@ -373,6 +373,12 @@
     return (used);
 }
 
+SDL_bool
+SDL_HasEvent(Uint32 mask)
+{
+    return (SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, mask) > 0);
+}
+
 /* Run the system dependent event loops */
 void
 SDL_PumpEvents(void)
@@ -520,7 +526,7 @@
 /* This is a generic event handler.
  */
 int
-SDL_PrivateSysWMEvent(SDL_SysWMmsg * message)
+SDL_SendSysWMEvent(SDL_SysWMmsg * message)
 {
     int posted;
 
--- a/src/events/SDL_events_c.h	Thu Jul 06 05:53:32 2006 +0000
+++ b/src/events/SDL_events_c.h	Thu Jul 06 07:17:11 2006 +0000
@@ -25,6 +25,7 @@
 #include "SDL_events.h"
 #include "SDL_mouse_c.h"
 #include "SDL_keyboard_c.h"
+#include "SDL_windowevents_c.h"
 
 /* Start and stop the event processing loop */
 extern int SDL_StartEventLoop(Uint32 flags);
@@ -35,6 +36,8 @@
 extern void SDL_Unlock_EventThread(void);
 extern Uint32 SDL_EventThreadID(void);
 
+extern int SDL_SendSysWMEvent(SDL_SysWMmsg * message);
+
 extern int SDL_QuitInit(void);
 extern int SDL_SendQuit(void);
 extern void SDL_QuitQuit(void);
--- a/src/events/SDL_keyboard.c	Thu Jul 06 05:53:32 2006 +0000
+++ b/src/events/SDL_keyboard.c	Thu Jul 06 07:17:11 2006 +0000
@@ -338,18 +338,15 @@
 SDL_ResetKeyboard(int index)
 {
     SDL_Keyboard *keyboard = SDL_GetKeyboard(index);
-    SDL_keysym keysym;
-    Uint16 key;
+    SDLKey key;
 
     if (!keyboard) {
         return;
     }
 
-    SDL_memset(&keysym, 0, (sizeof keysym));
     for (key = SDLK_FIRST; key < SDLK_LAST; ++key) {
         if (keyboard->keystate[key] == SDL_PRESSED) {
-            keysym.sym = key;
-            SDL_SendKeyboardKey(index, 0, SDL_RELEASED, &keysym);
+            SDL_SendKeyboardKey(index, SDL_RELEASED, 0, key);
         }
     }
     keyboard->repeat.timestamp = 0;
@@ -463,9 +460,57 @@
     return keyname;
 }
 
+void
+SDL_SetKeyboardFocus(int index, SDL_WindowID windowID)
+{
+    SDL_Keyboard *keyboard = SDL_GetKeyboard(index);
+    int i;
+    SDL_bool focus;
+
+    if (!keyboard || (keyboard->focus == windowID)) {
+        return;
+    }
+
+    /* See if the current window has lost focus */
+    if (keyboard->focus) {
+        focus = SDL_FALSE;
+        for (i = 0; i < SDL_num_keyboards; ++i) {
+            SDL_Keyboard *check;
+            if (i != index) {
+                check = SDL_GetKeyboard(i);
+                if (check && check->focus == keyboard->focus) {
+                    focus = SDL_TRUE;
+                    break;
+                }
+            }
+        }
+        if (!focus) {
+            SDL_SendWindowEvent(windowID, SDL_WINDOWEVENT_FOCUS_GAINED, 0, 0);
+        }
+    }
+
+    keyboard->focus = windowID;
+
+    if (keyboard->focus) {
+        focus = SDL_FALSE;
+        for (i = 0; i < SDL_num_keyboards; ++i) {
+            SDL_Keyboard *check;
+            if (i != index) {
+                check = SDL_GetKeyboard(i);
+                if (check && check->focus == keyboard->focus) {
+                    focus = SDL_TRUE;
+                    break;
+                }
+            }
+        }
+        if (!focus) {
+            SDL_SendWindowEvent(windowID, SDL_WINDOWEVENT_FOCUS_LOST, 0, 0);
+        }
+    }
+}
+
 int
-SDL_SendKeyboardKey(int index, SDL_WindowID windowID, Uint8 state,
-                    SDL_keysym * keysym)
+SDL_SendKeyboardKey(int index, Uint8 state, Uint8 scancode, SDLKey key)
 {
     SDL_Keyboard *keyboard = SDL_GetKeyboard(index);
     int posted, repeatable;
@@ -475,106 +520,91 @@
     if (!keyboard) {
         return 0;
     }
-
-    if (windowID) {
-        keyboard->focus = windowID;
-    }
 #if 0
-    printf("The '%s' key has been %s\n", SDL_GetKeyName(keysym->sym),
+    printf("The '%s' key has been %s\n", SDL_GetKeyName(key),
            state == SDL_PRESSED ? "pressed" : "released");
 #endif
-    /* Set up the keysym */
-    modstate = keyboard->modstate;
-
     repeatable = 0;
-
     if (state == SDL_PRESSED) {
-        keysym->mod = modstate;
-        switch (keysym->sym) {
+        modstate = keyboard->modstate;
+        switch (key) {
         case SDLK_UNKNOWN:
             break;
         case SDLK_NUMLOCK:
-            modstate ^= KMOD_NUM;
-            if (!(modstate & KMOD_NUM))
-                state = SDL_RELEASED;
-            keysym->mod = modstate;
+            keyboard->modstate ^= KMOD_NUM;
             break;
         case SDLK_CAPSLOCK:
-            modstate ^= KMOD_CAPS;
-            if (!(modstate & KMOD_CAPS))
-                state = SDL_RELEASED;
-            keysym->mod = modstate;
+            keyboard->modstate ^= KMOD_CAPS;
             break;
         case SDLK_LCTRL:
-            modstate |= KMOD_LCTRL;
+            keyboard->modstate |= KMOD_LCTRL;
             break;
         case SDLK_RCTRL:
-            modstate |= KMOD_RCTRL;
+            keyboard->modstate |= KMOD_RCTRL;
             break;
         case SDLK_LSHIFT:
-            modstate |= KMOD_LSHIFT;
+            keyboard->modstate |= KMOD_LSHIFT;
             break;
         case SDLK_RSHIFT:
-            modstate |= KMOD_RSHIFT;
+            keyboard->modstate |= KMOD_RSHIFT;
             break;
         case SDLK_LALT:
-            modstate |= KMOD_LALT;
+            keyboard->modstate |= KMOD_LALT;
             break;
         case SDLK_RALT:
-            modstate |= KMOD_RALT;
+            keyboard->modstate |= KMOD_RALT;
             break;
         case SDLK_LMETA:
-            modstate |= KMOD_LMETA;
+            keyboard->modstate |= KMOD_LMETA;
             break;
         case SDLK_RMETA:
-            modstate |= KMOD_RMETA;
+            keyboard->modstate |= KMOD_RMETA;
             break;
         case SDLK_MODE:
-            modstate |= KMOD_MODE;
+            keyboard->modstate |= KMOD_MODE;
             break;
         default:
             repeatable = 1;
             break;
         }
     } else {
-        switch (keysym->sym) {
+        switch (key) {
         case SDLK_UNKNOWN:
             break;
         case SDLK_NUMLOCK:
         case SDLK_CAPSLOCK:
-            /* Only send keydown events */
-            return (0);
+            break;
         case SDLK_LCTRL:
-            modstate &= ~KMOD_LCTRL;
+            keyboard->modstate &= ~KMOD_LCTRL;
             break;
         case SDLK_RCTRL:
-            modstate &= ~KMOD_RCTRL;
+            keyboard->modstate &= ~KMOD_RCTRL;
             break;
         case SDLK_LSHIFT:
-            modstate &= ~KMOD_LSHIFT;
+            keyboard->modstate &= ~KMOD_LSHIFT;
             break;
         case SDLK_RSHIFT:
-            modstate &= ~KMOD_RSHIFT;
+            keyboard->modstate &= ~KMOD_RSHIFT;
             break;
         case SDLK_LALT:
-            modstate &= ~KMOD_LALT;
+            keyboard->modstate &= ~KMOD_LALT;
             break;
         case SDLK_RALT:
-            modstate &= ~KMOD_RALT;
+            keyboard->modstate &= ~KMOD_RALT;
             break;
         case SDLK_LMETA:
-            modstate &= ~KMOD_LMETA;
+            keyboard->modstate &= ~KMOD_LMETA;
             break;
         case SDLK_RMETA:
-            modstate &= ~KMOD_RMETA;
+            keyboard->modstate &= ~KMOD_RMETA;
             break;
         case SDLK_MODE:
-            modstate &= ~KMOD_MODE;
+            keyboard->modstate &= ~KMOD_MODE;
             break;
         default:
             break;
         }
-        keysym->mod = modstate;
+        modstate = keyboard->modstate;
     }
 
     /* Figure out what type of event this is */
@@ -588,7 +618,7 @@
          * jk 991215 - Added
          */
         if (keyboard->repeat.timestamp &&
-            keyboard->repeat.evt.key.keysym.sym == keysym->sym) {
+            keyboard->repeat.evt.key.keysym.sym == key) {
             keyboard->repeat.timestamp = 0;
         }
         break;
@@ -597,9 +627,9 @@
         return 0;
     }
 
-    if (keysym->sym != SDLK_UNKNOWN) {
+    if (key != SDLK_UNKNOWN) {
         /* Drop events that don't change state */
-        if (keyboard->keystate[keysym->sym] == state) {
+        if (keyboard->keystate[key] == state) {
 #if 0
             printf("Keyboard event didn't change state - dropped!\n");
 #endif
@@ -607,8 +637,7 @@
         }
 
         /* Update internal keyboard state */
-        keyboard->modstate = modstate;
-        keyboard->keystate[keysym->sym] = state;
+        keyboard->keystate[key] = state;
     }
 
     /* Post the event, if desired */
@@ -618,7 +647,10 @@
         event.key.type = type;
         event.key.which = (Uint8) index;
         event.key.state = state;
-        event.key.keysym = *keysym;
+        event.key.keysym.scancode = scancode;
+        event.key.keysym.sym = (Uint16) key;
+        event.key.keysym.mod = modstate;
+        event.key.keysym.unicode = 0;
         event.key.windowID = keyboard->focus;
         /*
          * jk 991215 - Added
@@ -640,6 +672,32 @@
     return (posted);
 }
 
+int
+SDL_SendKeyboardText(int index, const char *text)
+{
+    SDL_Keyboard *keyboard = SDL_GetKeyboard(index);
+    int posted;
+
+    if (!keyboard) {
+        return 0;
+    }
+
+    /* Post the event, if desired */
+    posted = 0;
+    if (SDL_ProcessEvents[SDL_TEXTINPUT] == SDL_ENABLE) {
+        SDL_Event event;
+        event.text.type = SDL_TEXTINPUT;
+        event.text.which = (Uint8) index;
+        SDL_strlcpy(event.text.text, text, SDL_arraysize(event.text.text));
+        event.key.windowID = keyboard->focus;
+        if ((SDL_EventOK == NULL) || SDL_EventOK(SDL_EventOKParam, &event)) {
+            posted = 1;
+            SDL_PushEvent(&event);
+        }
+    }
+    return (posted);
+}
+
 /*
  * jk 991215 - Added
  */
--- a/src/events/SDL_keyboard_c.h	Thu Jul 06 05:53:32 2006 +0000
+++ b/src/events/SDL_keyboard_c.h	Thu Jul 06 07:17:11 2006 +0000
@@ -75,9 +75,15 @@
 /* Clear the state of a keyboard at an index */
 extern void SDL_ResetKeyboard(int index);
 
+/* Set the keyboard focus window */
+extern void SDL_SetKeyboardFocus(int index, SDL_WindowID windowID);
+
 /* Send a keyboard event for a keyboard at an index */
-extern int SDL_SendKeyboardKey(int index, SDL_WindowID windowID, Uint8 state,
-                               SDL_keysym * keysym);
+extern int SDL_SendKeyboardKey(int index, Uint8 state, Uint8 scancode,
+                               SDLKey key);
+
+/* Send keyboard text input for a keyboard at an index */
+extern int SDL_SendKeyboardText(int index, const char *text);
 
 /* Used by the event loop to queue pending keyboard repeat events */
 extern void SDL_CheckKeyRepeat(void);
--- a/src/events/SDL_mouse.c	Thu Jul 06 05:53:32 2006 +0000
+++ b/src/events/SDL_mouse.c	Thu Jul 06 07:17:11 2006 +0000
@@ -265,9 +265,57 @@
     return mouse->buttonstate;
 }
 
+void
+SDL_SetMouseFocus(int index, SDL_WindowID windowID)
+{
+    SDL_Mouse *mouse = SDL_GetMouse(index);
+    int i;
+    SDL_bool focus;
+
+    if (!mouse || (mouse->focus == windowID)) {
+        return;
+    }
+
+    /* See if the current window has lost focus */
+    if (mouse->focus) {
+        focus = SDL_FALSE;
+        for (i = 0; i < SDL_num_mice; ++i) {
+            SDL_Mouse *check;
+            if (i != index) {
+                check = SDL_GetMouse(i);
+                if (check && check->focus == mouse->focus) {
+                    focus = SDL_TRUE;
+                    break;
+                }
+            }
+        }
+        if (!focus) {
+            SDL_SendWindowEvent(windowID, SDL_WINDOWEVENT_LEAVE, 0, 0);
+        }
+    }
+
+    mouse->focus = windowID;
+
+    if (mouse->focus) {
+        focus = SDL_FALSE;
+        for (i = 0; i < SDL_num_mice; ++i) {
+            SDL_Mouse *check;
+            if (i != index) {
+                check = SDL_GetMouse(i);
+                if (check && check->focus == mouse->focus) {
+                    focus = SDL_TRUE;
+                    break;
+                }
+            }
+        }
+        if (!focus) {
+            SDL_SendWindowEvent(windowID, SDL_WINDOWEVENT_ENTER, 0, 0);
+        }
+    }
+}
+
 int
-SDL_SendMouseMotion(int index, SDL_WindowID windowID, int relative, int x,
-                    int y)
+SDL_SendMouseMotion(int index, int relative, int x, int y)
 {
     SDL_Mouse *mouse = SDL_GetMouse(index);
     int posted;
@@ -278,10 +326,6 @@
         return 0;
     }
 
-    if (windowID) {
-        mouse->focus = windowID;
-    }
-
     if (relative) {
         /* Push the cursor around */
         xrel = x;
@@ -337,8 +381,7 @@
 }
 
 int
-SDL_SendMouseButton(int index, SDL_WindowID windowID, Uint8 state,
-                    Uint8 button)
+SDL_SendMouseButton(int index, Uint8 state, Uint8 button)
 {
     SDL_Mouse *mouse = SDL_GetMouse(index);
     int posted;
@@ -348,10 +391,6 @@
         return 0;
     }
 
-    if (windowID) {
-        mouse->focus = windowID;
-    }
-
     /* Figure out which event to perform */
     switch (state) {
     case SDL_PRESSED:
@@ -395,6 +434,33 @@
     return posted;
 }
 
+int
+SDL_SendMouseWheel(int index, int motion)
+{
+    SDL_Mouse *mouse = SDL_GetMouse(index);
+    int posted;
+
+    if (!mouse || !motion) {
+        return 0;
+    }
+
+    /* Post the event, if desired */
+    posted = 0;
+    if (SDL_ProcessEvents[SDL_MOUSEWHEEL] == SDL_ENABLE) {
+        SDL_Event event;
+        event.type = SDL_MOUSEWHEEL;
+        event.wheel.which = (Uint8) index;
+        event.wheel.motion = motion;
+        event.wheel.windowID = mouse->focus;
+        if ((SDL_EventOK == NULL)
+            || (*SDL_EventOK) (SDL_EventOKParam, &event)) {
+            posted = 1;
+            SDL_PushEvent(&event);
+        }
+    }
+    return posted;
+}
+
 void
 SDL_WarpMouseInWindow(SDL_WindowID windowID, int x, int y)
 {
@@ -407,7 +473,8 @@
     if (mouse->WarpMouse) {
         mouse->WarpMouse(mouse, windowID, x, y);
     } else {
-        SDL_SendMouseMotion(SDL_current_mouse, windowID, 0, x, y);
+        SDL_SetMouseFocus(SDL_current_mouse, windowID);
+        SDL_SendMouseMotion(SDL_current_mouse, 0, x, y);
     }
 }
 
--- a/src/events/SDL_mouse_c.h	Thu Jul 06 05:53:32 2006 +0000
+++ b/src/events/SDL_mouse_c.h	Thu Jul 06 07:17:11 2006 +0000
@@ -92,13 +92,17 @@
 /* Clear the button state of a mouse at an index */
 extern void SDL_ResetMouse(int index);
 
+/* Set the mouse focus window */
+extern void SDL_SetMouseFocus(int index, SDL_WindowID windowID);
+
 /* Send a mouse motion event for a mouse at an index */
-extern int SDL_SendMouseMotion(int index, SDL_WindowID windowID, int relative,
-                               int x, int y);
+extern int SDL_SendMouseMotion(int index, int relative, int x, int y);
 
 /* Send a mouse button event for a mouse at an index */
-extern int SDL_SendMouseButton(int index, SDL_WindowID windowID, Uint8 state,
-                               Uint8 button);
+extern int SDL_SendMouseButton(int index, Uint8 state, Uint8 button);
+
+/* Send a mouse wheel event for a mouse at an index */
+extern int SDL_SendMouseWheel(int index, int motion);
 
 /* Shutdown the mouse subsystem */
 extern void SDL_MouseQuit(void);
--- a/src/events/SDL_windowevents.c	Thu Jul 06 05:53:32 2006 +0000
+++ b/src/events/SDL_windowevents.c	Thu Jul 06 07:17:11 2006 +0000
@@ -28,8 +28,8 @@
 #include "../video/SDL_sysvideo.h"
 
 int
-SDL_PrivateWindowEvent(SDL_WindowID windowID, Uint8 windowevent, int data1,
-                       int data2)
+SDL_SendWindowEvent(SDL_WindowID windowID, Uint8 windowevent, int data1,
+                    int data2)
 {
     int posted;
     SDL_Window *window;
@@ -51,6 +51,16 @@
         }
         window->flags &= ~SDL_WINDOW_SHOWN;
         break;
+    case SDL_WINDOWEVENT_MOVED:
+        if (data1 == window->x && data2 == window->y) {
+            return 0;
+        }
+        break;
+    case SDL_WINDOWEVENT_RESIZED:
+        if (data1 == window->w && data2 == window->h) {
+            return 0;
+        }
+        break;
     case SDL_WINDOWEVENT_MINIMIZED:
         if (window->flags & SDL_WINDOW_MINIMIZED) {
             return 0;
--- a/src/events/SDL_windowevents_c.h	Thu Jul 06 05:53:32 2006 +0000
+++ b/src/events/SDL_windowevents_c.h	Thu Jul 06 07:17:11 2006 +0000
@@ -27,8 +27,6 @@
 extern int SDL_SendWindowEvent(SDL_WindowID windowID, Uint8 windowevent,
                                int data1, int data2);
 
-extern int SDL_SendSysWMEvent(SDL_SysWMmsg * message);
-
 #endif /* _SDL_windowevents_c_h */
 
 /* vi: set ts=4 sw=4 expandtab: */
--- a/src/video/SDL_surface.c	Thu Jul 06 05:53:32 2006 +0000
+++ b/src/video/SDL_surface.c	Thu Jul 06 07:17:11 2006 +0000
@@ -418,7 +418,7 @@
  * A function to calculate the intersection of two rectangles:
  * return true if the rectangles intersect, false otherwise
  */
-static __inline__ SDL_bool
+SDL_bool
 SDL_IntersectRect(const SDL_Rect * A, const SDL_Rect * B,
                   SDL_Rect * intersection)
 {
--- a/src/video/SDL_video.c	Thu Jul 06 05:53:32 2006 +0000
+++ b/src/video/SDL_video.c	Thu Jul 06 07:17:11 2006 +0000
@@ -188,6 +188,11 @@
     }
 #endif
 
+    /* Start the event loop */
+    if (SDL_StartEventLoop(flags) < 0) {
+        return -1;
+    }
+
     /* Check to make sure we don't overwrite '_this' */
     if (_this != NULL) {
         SDL_VideoQuit();
@@ -277,12 +282,6 @@
         }
     }
 
-    /* Start the event loop */
-    if (SDL_StartEventLoop(flags) < 0) {
-        SDL_VideoQuit();
-        return -1;
-    }
-
     /* We're ready to go! */
     return 0;
 }
@@ -1286,10 +1285,22 @@
     }
 
     /* Copy the palette if any */
-    if (fmt->palette) {
-        SDL_SetTexturePalette(textureID, fmt->palette->colors, 0,
-                              fmt->palette->ncolors);
-        SDL_SetSurfacePalette(&dst, fmt->palette);
+    if (SDL_ISPIXELFORMAT_INDEXED(format)) {
+        if (fmt->palette) {
+            SDL_SetTexturePalette(textureID, fmt->palette->colors, 0,
+                                  fmt->palette->ncolors);
+            SDL_SetSurfacePalette(&dst, fmt->palette);
+        } else {
+            dst.format->palette =
+                SDL_AllocPalette((1 << SDL_BITSPERPIXEL(format)));
+            if (!dst.format->palette) {
+                SDL_DestroyTexture(textureID);
+                SDL_FreeFormat(dst.format);
+                return 0;
+            }
+            SDL_DitherColors(dst.format->palette->colors,
+                             SDL_BITSPERPIXEL(format));
+        }
     }
 
     /* Make the texture transparent if the surface has colorkey */
@@ -1557,7 +1568,8 @@
 SDL_RenderFill(const SDL_Rect * rect, Uint32 color)
 {
     SDL_Renderer *renderer;
-    SDL_Rect full_rect;
+    SDL_Window *window;
+    SDL_Rect real_rect;
 
     if (!_this) {
         return -1;
@@ -1568,14 +1580,17 @@
         return -1;
     }
 
-    if (!rect) {
-        SDL_Window *window = SDL_GetWindowFromID(renderer->window);
-        full_rect.x = 0;
-        full_rect.y = 0;
-        full_rect.w = window->w;
-        full_rect.h = window->h;
-        rect = &full_rect;
+    window = SDL_GetWindowFromID(renderer->window);
+    real_rect.x = 0;
+    real_rect.y = 0;
+    real_rect.w = window->w;
+    real_rect.h = window->h;
+    if (rect) {
+        if (!SDL_IntersectRect(rect, &real_rect, &real_rect)) {
+            return 0;
+        }
     }
+    rect = &real_rect;
 
     return renderer->RenderFill(renderer, rect, color);
 }
@@ -1586,8 +1601,9 @@
 {
     SDL_Texture *texture = SDL_GetTextureFromID(textureID);
     SDL_Renderer *renderer;
-    SDL_Rect full_srcrect;
-    SDL_Rect full_dstrect;
+    SDL_Window *window;
+    SDL_Rect real_srcrect;
+    SDL_Rect real_dstrect;
 
     if (!texture || texture->renderer != SDL_CurrentDisplay.current_renderer) {
         return -1;
@@ -1598,20 +1614,21 @@
         return -1;
     }
 
+    /* FIXME: implement clipping */
+    window = SDL_GetWindowFromID(renderer->window);
+    real_srcrect.x = 0;
+    real_srcrect.y = 0;
+    real_srcrect.w = texture->w;
+    real_srcrect.h = texture->h;
+    real_dstrect.x = 0;
+    real_dstrect.y = 0;
+    real_dstrect.w = window->w;
+    real_dstrect.h = window->h;
     if (!srcrect) {
-        full_srcrect.x = 0;
-        full_srcrect.y = 0;
-        full_srcrect.w = texture->w;
-        full_srcrect.h = texture->h;
-        srcrect = &full_srcrect;
+        srcrect = &real_srcrect;
     }
     if (!dstrect) {
-        SDL_Window *window = SDL_GetWindowFromID(renderer->window);
-        full_dstrect.x = 0;
-        full_dstrect.y = 0;
-        full_dstrect.w = window->w;
-        full_dstrect.h = window->h;
-        dstrect = &full_dstrect;
+        dstrect = &real_dstrect;
     }
 
     return renderer->RenderCopy(renderer, texture, srcrect, dstrect,
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/video/win32/SDL_dibrender.c	Thu Jul 06 07:17:11 2006 +0000
@@ -0,0 +1,711 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997-2006 Sam Lantinga
+
+    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.1 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+    Sam Lantinga
+    slouken@libsdl.org
+*/
+#include "SDL_config.h"
+
+#include "SDL_win32video.h"
+#include "../SDL_yuv_sw_c.h"
+
+/* GDI renderer implementation */
+
+static SDL_Renderer *SDL_DIB_CreateRenderer(SDL_Window * window,
+                                            Uint32 flags);
+static int SDL_DIB_CreateTexture(SDL_Renderer * renderer,
+                                 SDL_Texture * texture);
+static int SDL_DIB_QueryTexturePixels(SDL_Renderer * renderer,
+                                      SDL_Texture * texture, void **pixels,
+                                      int *pitch);
+static int SDL_DIB_SetTexturePalette(SDL_Renderer * renderer,
+                                     SDL_Texture * texture,
+                                     const SDL_Color * colors, int firstcolor,
+                                     int ncolors);
+static int SDL_DIB_GetTexturePalette(SDL_Renderer * renderer,
+                                     SDL_Texture * texture,
+                                     SDL_Color * colors, int firstcolor,
+                                     int ncolors);
+static int SDL_DIB_UpdateTexture(SDL_Renderer * renderer,
+                                 SDL_Texture * texture, const SDL_Rect * rect,
+                                 const void *pixels, int pitch);
+static int SDL_DIB_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
+                               const SDL_Rect * rect, int markDirty,
+                               void **pixels, int *pitch);
+static void SDL_DIB_UnlockTexture(SDL_Renderer * renderer,
+                                  SDL_Texture * texture);
+static void SDL_DIB_DirtyTexture(SDL_Renderer * renderer,
+                                 SDL_Texture * texture, int numrects,
+                                 const SDL_Rect * rects);
+static void SDL_DIB_SelectRenderTexture(SDL_Renderer * renderer,
+                                        SDL_Texture * texture);
+static int SDL_DIB_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect,
+                              Uint32 color);
+static int SDL_DIB_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
+                              const SDL_Rect * srcrect,
+                              const SDL_Rect * dstrect, int blendMode,
+                              int scaleMode);
+static int SDL_DIB_RenderReadPixels(SDL_Renderer * renderer,
+                                    const SDL_Rect * rect, void *pixels,
+                                    int pitch);
+static int SDL_DIB_RenderWritePixels(SDL_Renderer * renderer,
+                                     const SDL_Rect * rect,
+                                     const void *pixels, int pitch);
+static void SDL_DIB_RenderPresent(SDL_Renderer * renderer);
+static void SDL_DIB_DestroyTexture(SDL_Renderer * renderer,
+                                   SDL_Texture * texture);
+static void SDL_DIB_DestroyRenderer(SDL_Renderer * renderer);
+
+
+SDL_RenderDriver SDL_DIB_RenderDriver = {
+    SDL_DIB_CreateRenderer,
+    {
+     "gdi",
+     (SDL_Renderer_PresentDiscard |
+      SDL_Renderer_PresentCopy | SDL_Renderer_RenderTarget),
+     (SDL_TextureBlendMode_None |
+      SDL_TextureBlendMode_Mask | SDL_TextureBlendMode_Blend),
+     (SDL_TextureScaleMode_None | SDL_TextureScaleMode_Fast),
+     11,
+     {
+      SDL_PixelFormat_Index8,
+      SDL_PixelFormat_RGB555,
+      SDL_PixelFormat_RGB565,
+      SDL_PixelFormat_RGB888,
+      SDL_PixelFormat_BGR888,
+      SDL_PixelFormat_ARGB8888,
+      SDL_PixelFormat_RGBA8888,
+      SDL_PixelFormat_ABGR8888,
+      SDL_PixelFormat_BGRA8888,
+      SDL_PixelFormat_YUY2,
+      SDL_PixelFormat_UYVY},
+     0,
+     0}
+};
+
+typedef struct
+{
+    HWND hwnd;
+    HDC window_hdc;
+    HDC render_hdc;
+    HDC memory_hdc;
+    HDC current_hdc;
+    LPBITMAPINFO bmi;
+    HBITMAP window_bmp;
+    void *window_pixels;
+    int window_pitch;
+} SDL_DIB_RenderData;
+
+typedef struct
+{
+    SDL_SW_YUVTexture *yuv;
+    Uint32 format;
+    HPALETTE hpal;
+    HBITMAP hbm;
+    void *pixels;
+    int pitch;
+} SDL_DIB_TextureData;
+
+static void
+UpdateYUVTextureData(SDL_Texture * texture)
+{
+    SDL_DIB_TextureData *data = (SDL_DIB_TextureData *) texture->driverdata;
+    SDL_Rect rect;
+
+    rect.x = 0;
+    rect.y = 0;
+    rect.w = texture->w;
+    rect.h = texture->h;
+    SDL_SW_CopyYUVToRGB(data->yuv, &rect, data->format, texture->w,
+                        texture->h, data->pixels, data->pitch);
+}
+
+SDL_Renderer *
+SDL_DIB_CreateRenderer(SDL_Window * window, Uint32 flags)
+{
+    SDL_WindowData *windowdata = (SDL_WindowData *) window->driverdata;
+    SDL_Renderer *renderer;
+    SDL_DIB_RenderData *data;
+    int bmi_size;
+    HBITMAP hbm;
+
+    renderer = (SDL_Renderer *) SDL_malloc(sizeof(*renderer));
+    if (!renderer) {
+        SDL_OutOfMemory();
+        return NULL;
+    }
+    SDL_zerop(renderer);
+
+    data = (SDL_DIB_RenderData *) SDL_malloc(sizeof(*data));
+    if (!data) {
+        SDL_DIB_DestroyRenderer(renderer);
+        SDL_OutOfMemory();
+        return NULL;
+    }
+    SDL_zerop(data);
+
+    data->hwnd = windowdata->hwnd;
+    data->window_hdc = GetDC(data->hwnd);
+    data->render_hdc = CreateCompatibleDC(data->window_hdc);
+    data->memory_hdc = CreateCompatibleDC(data->window_hdc);
+    data->current_hdc = data->window_hdc;
+
+    /* Fill in the compatible bitmap info */
+    bmi_size = sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD);
+    data->bmi = (LPBITMAPINFO) SDL_malloc(bmi_size);
+    if (!data->bmi) {
+        SDL_DIB_DestroyRenderer(renderer);
+        SDL_OutOfMemory();
+        return NULL;
+    }
+    SDL_memset(data->bmi, 0, bmi_size);
+    data->bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+
+    hbm = CreateCompatibleBitmap(data->window_hdc, 1, 1);
+    GetDIBits(data->window_hdc, hbm, 0, 1, NULL, data->bmi, DIB_RGB_COLORS);
+    GetDIBits(data->window_hdc, hbm, 0, 1, NULL, data->bmi, DIB_RGB_COLORS);
+    DeleteObject(hbm);
+
+    renderer->CreateTexture = SDL_DIB_CreateTexture;
+    renderer->QueryTexturePixels = SDL_DIB_QueryTexturePixels;
+    renderer->SetTexturePalette = SDL_DIB_SetTexturePalette;
+    renderer->GetTexturePalette = SDL_DIB_GetTexturePalette;
+    renderer->UpdateTexture = SDL_DIB_UpdateTexture;
+    renderer->LockTexture = SDL_DIB_LockTexture;
+    renderer->UnlockTexture = SDL_DIB_UnlockTexture;
+    renderer->DirtyTexture = SDL_DIB_DirtyTexture;
+    renderer->SelectRenderTexture = SDL_DIB_SelectRenderTexture;
+    renderer->RenderFill = SDL_DIB_RenderFill;
+    renderer->RenderCopy = SDL_DIB_RenderCopy;
+    renderer->RenderReadPixels = SDL_DIB_RenderReadPixels;
+    renderer->RenderWritePixels = SDL_DIB_RenderWritePixels;
+    renderer->RenderPresent = SDL_DIB_RenderPresent;
+    renderer->DestroyTexture = SDL_DIB_DestroyTexture;
+    renderer->DestroyRenderer = SDL_DIB_DestroyRenderer;
+    renderer->info = SDL_DIB_RenderDriver.info;
+    renderer->window = window->id;
+    renderer->driverdata = data;
+
+    renderer->info.flags = SDL_Renderer_RenderTarget;
+
+    return renderer;
+}
+
+static int
+SDL_DIB_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
+{
+    SDL_DIB_RenderData *renderdata =
+        (SDL_DIB_RenderData *) renderer->driverdata;
+    SDL_Window *window = SDL_GetWindowFromID(renderer->window);
+    SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
+    SDL_DIB_TextureData *data;
+
+    data = (SDL_DIB_TextureData *) SDL_malloc(sizeof(*data));
+    if (!data) {
+        SDL_OutOfMemory();
+        return -1;
+    }
+    SDL_zerop(data);
+
+    texture->driverdata = data;
+
+    if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
+        if (texture->access == SDL_TextureAccess_Render) {
+            SDL_SetError("Rendering to YUV format textures is not supported");
+            return -1;
+        }
+        data->yuv = SDL_SW_CreateYUVTexture(texture);
+        if (!data->yuv) {
+            SDL_DIB_DestroyTexture(renderer, texture);
+            return -1;
+        }
+        data->format = display->current_mode.format;
+    } else {
+        data->format = texture->format;
+    }
+    data->pitch = (texture->w * SDL_BYTESPERPIXEL(data->format));
+
+    if (data->yuv || texture->access == SDL_TextureAccess_Local
+        || texture->format != SDL_GetCurrentDisplayMode()->format) {
+        int bmi_size;
+        LPBITMAPINFO bmi;
+
+        bmi_size = sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD);
+        bmi = (LPBITMAPINFO) SDL_malloc(bmi_size);
+        if (!bmi) {
+            SDL_DIB_DestroyTexture(renderer, texture);
+            SDL_OutOfMemory();
+            return -1;
+        }
+        SDL_memset(bmi, 0, bmi_size);
+        bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+        bmi->bmiHeader.biWidth = texture->w;
+        bmi->bmiHeader.biHeight = -texture->h;  /* topdown bitmap */
+        bmi->bmiHeader.biPlanes = 1;
+        bmi->bmiHeader.biSizeImage = texture->h * data->pitch;
+        bmi->bmiHeader.biXPelsPerMeter = 0;
+        bmi->bmiHeader.biYPelsPerMeter = 0;
+        bmi->bmiHeader.biClrUsed = 0;
+        bmi->bmiHeader.biClrImportant = 0;
+        bmi->bmiHeader.biBitCount = SDL_BYTESPERPIXEL(data->format) * 8;
+        if (SDL_ISPIXELFORMAT_INDEXED(data->format)) {
+            int i, ncolors;
+            LOGPALETTE *palette;
+
+            bmi->bmiHeader.biCompression = BI_RGB;
+            ncolors = (1 << SDL_BITSPERPIXEL(data->format));
+            palette =
+                (LOGPALETTE *) SDL_malloc(sizeof(*palette) +
+                                          ncolors * sizeof(PALETTEENTRY));
+            if (!palette) {
+                SDL_free(bmi);
+                SDL_DIB_DestroyTexture(renderer, texture);
+                SDL_OutOfMemory();
+                return -1;
+            }
+            palette->palVersion = 0x300;
+            palette->palNumEntries = ncolors;
+            for (i = 0; i < ncolors; ++i) {
+                palette->palPalEntry[i].peRed = 0xFF;
+                palette->palPalEntry[i].peGreen = 0xFF;
+                palette->palPalEntry[i].peBlue = 0xFF;
+                palette->palPalEntry[i].peFlags = 0;
+            }
+            data->hpal = CreatePalette(palette);
+            SDL_free(palette);
+        } else {
+            int bpp;
+            Uint32 Rmask, Gmask, Bmask, Amask;
+
+            bmi->bmiHeader.biCompression = BI_BITFIELDS;
+            SDL_PixelFormatEnumToMasks(data->format, &bpp, &Rmask, &Gmask,
+                                       &Bmask, &Amask);
+            ((Uint32 *) bmi->bmiColors)[0] = Rmask;
+            ((Uint32 *) bmi->bmiColors)[1] = Gmask;
+            ((Uint32 *) bmi->bmiColors)[2] = Bmask;
+            data->hpal = NULL;
+        }
+        data->hbm =
+            CreateDIBSection(renderdata->memory_hdc, bmi, DIB_RGB_COLORS,
+                             &data->pixels, NULL, 0);
+    } else {
+        data->hbm =
+            CreateCompatibleBitmap(renderdata->window_hdc, texture->w,
+                                   texture->h);
+        data->pixels = NULL;
+    }
+    if (!data->hbm) {
+        SDL_DIB_DestroyTexture(renderer, texture);
+        WIN_SetError("Couldn't create bitmap");
+        return -1;
+    }
+    return 0;
+}
+
+static int
+SDL_DIB_QueryTexturePixels(SDL_Renderer * renderer, SDL_Texture * texture,
+                           void **pixels, int *pitch)
+{
+    SDL_DIB_TextureData *data = (SDL_DIB_TextureData *) texture->driverdata;
+
+    if (data->yuv) {
+        return SDL_SW_QueryYUVTexturePixels(data->yuv, pixels, pitch);
+    } else {
+        *pixels = data->pixels;
+        *pitch = texture->w * SDL_BYTESPERPIXEL(texture->format);
+        return 0;
+    }
+}
+
+static int
+SDL_DIB_SetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture,
+                          const SDL_Color * colors, int firstcolor,
+                          int ncolors)
+{
+    SDL_DIB_RenderData *renderdata =
+        (SDL_DIB_RenderData *) renderer->driverdata;
+    SDL_DIB_TextureData *data = (SDL_DIB_TextureData *) texture->driverdata;
+
+    if (data->yuv) {
+        SDL_SetError("YUV textures don't have a palette");
+        return -1;
+    } else {
+        PALETTEENTRY entries[256];
+        int i;
+
+        for (i = 0; i < ncolors; ++i) {
+            entries[i].peRed = colors[i].r;
+            entries[i].peGreen = colors[i].g;
+            entries[i].peBlue = colors[i].b;
+            entries[i].peFlags = 0;
+        }
+        if (!SetPaletteEntries(data->hpal, firstcolor, ncolors, entries)) {
+            WIN_SetError("SetPaletteEntries()");
+            return -1;
+        }
+        return 0;
+    }
+}
+
+static int
+SDL_DIB_GetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture,
+                          SDL_Color * colors, int firstcolor, int ncolors)
+{
+    SDL_DIB_TextureData *data = (SDL_DIB_TextureData *) texture->driverdata;
+
+    if (data->yuv) {
+        SDL_SetError("YUV textures don't have a palette");
+        return -1;
+    } else {
+        PALETTEENTRY entries[256];
+        int i;
+
+        if (!GetPaletteEntries(data->hpal, firstcolor, ncolors, entries)) {
+            WIN_SetError("GetPaletteEntries()");
+            return -1;
+        }
+        for (i = 0; i < ncolors; ++i) {
+            colors[i].r = entries[i].peRed;
+            colors[i].g = entries[i].peGreen;
+            colors[i].b = entries[i].peBlue;
+        }
+        return 0;
+    }
+}
+
+static int
+SDL_DIB_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
+                      const SDL_Rect * rect, const void *pixels, int pitch)
+{
+    SDL_DIB_TextureData *data = (SDL_DIB_TextureData *) texture->driverdata;
+
+    if (data->yuv) {
+        if (SDL_SW_UpdateYUVTexture(data->yuv, rect, pixels, pitch) < 0) {
+            return -1;
+        }
+        UpdateYUVTextureData(texture);
+        return 0;
+    } else {
+        SDL_DIB_RenderData *renderdata =
+            (SDL_DIB_RenderData *) renderer->driverdata;
+
+        if (data->pixels) {
+            Uint8 *src, *dst;
+            int row;
+            size_t length;
+
+            src = (Uint8 *) pixels;
+            dst =
+                (Uint8 *) data->pixels + rect->y * data->pitch +
+                rect->x * SDL_BYTESPERPIXEL(texture->format);
+            length = rect->w * SDL_BYTESPERPIXEL(texture->format);
+            for (row = 0; row < rect->h; ++row) {
+                SDL_memcpy(dst, src, length);
+                src += pitch;
+                dst += data->pitch;
+            }
+        } else if (rect->w == texture->w && pitch == data->pitch) {
+            if (!SetDIBits
+                (renderdata->window_hdc, data->hbm, rect->y, rect->h, pixels,
+                 renderdata->bmi, DIB_RGB_COLORS)) {
+                WIN_SetError("SetDIBits()");
+                return -1;
+            }
+        } else {
+            SDL_SetError
+                ("FIXME: Need to allocate temporary memory and do GetDIBits() followed by SetDIBits(), since we can only set blocks of scanlines at a time");
+            return -1;
+        }
+        return 0;
+    }
+}
+
+static int
+SDL_DIB_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
+                    const SDL_Rect * rect, int markDirty, void **pixels,
+                    int *pitch)
+{
+    SDL_DIB_TextureData *data = (SDL_DIB_TextureData *) texture->driverdata;
+
+    if (data->yuv) {
+        return SDL_SW_LockYUVTexture(data->yuv, rect, markDirty, pixels,
+                                     pitch);
+    } else {
+        GdiFlush();
+        *pixels =
+            (void *) ((Uint8 *) data->pixels + rect->y * data->pitch +
+                      rect->x * SDL_BYTESPERPIXEL(texture->format));
+        *pitch = data->pitch;
+        return 0;
+    }
+}
+
+static void
+SDL_DIB_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
+{
+    SDL_DIB_TextureData *data = (SDL_DIB_TextureData *) texture->driverdata;
+
+    if (data->yuv) {
+        SDL_SW_UnlockYUVTexture(data->yuv);
+        UpdateYUVTextureData(texture);
+    }
+}
+
+static void
+SDL_DIB_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture,
+                     int numrects, const SDL_Rect * rects)
+{
+}
+
+static void
+SDL_DIB_SelectRenderTexture(SDL_Renderer * renderer, SDL_Texture * texture)
+{
+    SDL_DIB_RenderData *data = (SDL_DIB_RenderData *) renderer->driverdata;
+
+    if (texture) {
+        SDL_DIB_TextureData *texturedata =
+            (SDL_DIB_TextureData *) texture->driverdata;
+        SelectObject(data->render_hdc, texturedata->hbm);
+        if (texturedata->hpal) {
+            SelectPalette(data->render_hdc, texturedata->hpal, TRUE);
+            RealizePalette(data->render_hdc);
+        }
+        data->current_hdc = data->render_hdc;
+    } else {
+        data->current_hdc = data->current_hdc;
+    }
+}
+
+static int
+SDL_DIB_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect,
+                   Uint32 color)
+{
+    SDL_DIB_RenderData *data = (SDL_DIB_RenderData *) renderer->driverdata;
+    Uint8 r, g, b;
+    RECT rc;
+    static HBRUSH brush;
+    int status;
+
+    r = (Uint8) ((color >> 16) & 0xFF);
+    g = (Uint8) ((color >> 8) & 0xFF);
+    b = (Uint8) (color & 0xFF);
+
+    rc.left = rect->x;
+    rc.top = rect->y;
+    rc.right = rect->x + rect->w + 1;
+    rc.bottom = rect->y + rect->h + 1;
+
+    /* Should we cache the brushes? .. it looks like GDI does for us. :) */
+    brush = CreateSolidBrush(RGB(r, g, b));
+    SelectObject(data->current_hdc, brush);
+    status = FillRect(data->current_hdc, &rc, brush);
+    DeleteObject(brush);
+
+    if (!status) {
+        WIN_SetError("FillRect()");
+        return -1;
+    }
+    return 0;
+}
+
+static int
+SDL_DIB_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
+                   const SDL_Rect * srcrect, const SDL_Rect * dstrect,
+                   int blendMode, int scaleMode)
+{
+    SDL_DIB_RenderData *data = (SDL_DIB_RenderData *) renderer->driverdata;
+    SDL_DIB_TextureData *texturedata =
+        (SDL_DIB_TextureData *) texture->driverdata;
+
+    SelectObject(data->memory_hdc, texturedata->hbm);
+    if (texturedata->hpal) {
+        SelectPalette(data->memory_hdc, texturedata->hpal, TRUE);
+        RealizePalette(data->memory_hdc);
+    }
+    if (blendMode & (SDL_TextureBlendMode_Mask | SDL_TextureBlendMode_Blend)) {
+        static BLENDFUNCTION blendFunc = {
+            AC_SRC_OVER,
+            0,
+            255,
+            AC_SRC_ALPHA
+        };
+        /* FIXME: GDI uses premultiplied alpha! */
+        if (!AlphaBlend
+            (data->current_hdc, dstrect->x, dstrect->y, dstrect->w,
+             dstrect->h, data->memory_hdc, srcrect->x, srcrect->y, srcrect->w,
+             srcrect->h, blendFunc)) {
+            WIN_SetError("AlphaBlend()");
+            return -1;
+        }
+    } else {
+        if (srcrect->w == dstrect->w && srcrect->h == dstrect->h) {
+            if (!BitBlt
+                (data->current_hdc, dstrect->x, dstrect->y, dstrect->w,
+                 srcrect->h, data->memory_hdc, srcrect->x, srcrect->y,
+                 SRCCOPY)) {
+                WIN_SetError("BitBlt()");
+                return -1;
+            }
+        } else {
+            if (!StretchBlt
+                (data->current_hdc, dstrect->x, dstrect->y, dstrect->w,
+                 srcrect->h, data->memory_hdc, srcrect->x, srcrect->y,
+                 srcrect->w, srcrect->h, SRCCOPY)) {
+                WIN_SetError("StretchBlt()");
+                return -1;
+            }
+        }
+    }
+    return 0;
+}
+
+static int
+CreateWindowDIB(SDL_DIB_RenderData * data, SDL_Window * window)
+{
+    data->window_pitch = window->w * (data->bmi->bmiHeader.biBitCount / 8);
+    data->bmi->bmiHeader.biWidth = window->w;
+    data->bmi->bmiHeader.biHeight = -window->h;
+    data->bmi->bmiHeader.biSizeImage =
+        window->h * (data->bmi->bmiHeader.biBitCount / 8);
+    data->window_bmp =
+        CreateDIBSection(data->window_hdc, data->bmi, DIB_RGB_COLORS,
+                         &data->window_pixels, NULL, 0);
+    if (!data->window_bmp) {
+        WIN_SetError("CreateDIBSection()");
+        return -1;
+    }
+    return 0;
+}
+
+static int
+SDL_DIB_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
+                         void *pixels, int pitch)
+{
+    SDL_Window *window = SDL_GetWindowFromID(renderer->window);
+    SDL_DIB_RenderData *data = (SDL_DIB_RenderData *) renderer->driverdata;
+
+    if (!data->window_bmp) {
+        if (CreateWindowDIB(data, window) < 0) {
+            return -1;
+        }
+    }
+
+    SelectObject(data->memory_hdc, data->window_bmp);
+    BitBlt(data->memory_hdc, rect->x, rect->y, rect->w, rect->h,
+           data->window_hdc, rect->x, rect->y, SRCCOPY);
+
+    {
+        int bpp = data->bmi->bmiHeader.biBitCount / 8;
+        Uint8 *src =
+            (Uint8 *) data->window_pixels + rect->y * data->window_pitch +
+            rect->x * bpp;
+        Uint8 *dst = (Uint8 *) pixels;
+        int row;
+
+        for (row = 0; row < rect->h; ++row) {
+            SDL_memcpy(dst, src, rect->w * bpp);
+            src += data->window_pitch;
+            dst += pitch;
+        }
+    }
+
+    return 0;
+}
+
+static int
+SDL_DIB_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect,
+                          const void *pixels, int pitch)
+{
+    SDL_Window *window = SDL_GetWindowFromID(renderer->window);
+    SDL_DIB_RenderData *data = (SDL_DIB_RenderData *) renderer->driverdata;
+
+    if (!data->window_bmp) {
+        if (CreateWindowDIB(data, window) < 0) {
+            return -1;
+        }
+    }
+
+    {
+        int bpp = data->bmi->bmiHeader.biBitCount / 8;
+        Uint8 *src = (Uint8 *) pixels;
+        Uint8 *dst =
+            (Uint8 *) data->window_pixels + rect->y * data->window_pitch +
+            rect->x * bpp;
+        int row;
+
+        for (row = 0; row < rect->h; ++row) {
+            SDL_memcpy(dst, src, rect->w * bpp);
+            src += pitch;
+            dst += data->window_pitch;
+        }
+    }
+
+    SelectObject(data->memory_hdc, data->window_bmp);
+    BitBlt(data->window_hdc, rect->x, rect->y, rect->w, rect->h,
+           data->memory_hdc, rect->x, rect->y, SRCCOPY);
+
+    return 0;
+}
+
+static void
+SDL_DIB_RenderPresent(SDL_Renderer * renderer)
+{
+}
+
+static void
+SDL_DIB_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
+{
+    SDL_DIB_TextureData *data = (SDL_DIB_TextureData *) texture->driverdata;
+
+    if (!data) {
+        return;
+    }
+    if (data->yuv) {
+        SDL_SW_DestroyYUVTexture(data->yuv);
+    }
+    if (data->hpal) {
+        DeleteObject(data->hpal);
+    }
+    if (data->hbm) {
+        DeleteObject(data->hbm);
+    }
+    SDL_free(data);
+    texture->driverdata = NULL;
+}
+
+void
+SDL_DIB_DestroyRenderer(SDL_Renderer * renderer)
+{
+    SDL_DIB_RenderData *data = (SDL_DIB_RenderData *) renderer->driverdata;
+
+    if (data) {
+        ReleaseDC(data->hwnd, data->window_hdc);
+        DeleteDC(data->render_hdc);
+        DeleteDC(data->memory_hdc);
+        if (data->bmi) {
+            SDL_free(data->bmi);
+        }
+        if (data->window_bmp) {
+            DeleteObject(data->window_bmp);
+        }
+        SDL_free(data);
+    }
+    SDL_free(renderer);
+}
+
+/* vi: set ts=4 sw=4 expandtab: */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/video/win32/SDL_dibrender.h	Thu Jul 06 07:17:11 2006 +0000
@@ -0,0 +1,28 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997-2006 Sam Lantinga
+
+    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.1 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+    Sam Lantinga
+    slouken@libsdl.org
+*/
+#include "SDL_config.h"
+
+/* SDL surface based renderer implementation */
+
+extern SDL_RenderDriver SDL_DIB_RenderDriver;
+
+/* vi: set ts=4 sw=4 expandtab: */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/video/win32/SDL_vkeys.h	Thu Jul 06 07:17:11 2006 +0000
@@ -0,0 +1,76 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997-2006 Sam Lantinga
+
+    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.1 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+    Sam Lantinga
+    slouken@libsdl.org
+*/
+
+#ifndef VK_0
+#define VK_0	'0'
+#define VK_1	'1'
+#define VK_2	'2'
+#define VK_3	'3'
+#define VK_4	'4'
+#define VK_5	'5'
+#define VK_6	'6'
+#define VK_7	'7'
+#define VK_8	'8'
+#define VK_9	'9'
+#define VK_A	'A'
+#define VK_B	'B'
+#define VK_C	'C'
+#define VK_D	'D'
+#define VK_E	'E'
+#define VK_F	'F'
+#define VK_G	'G'
+#define VK_H	'H'
+#define VK_I	'I'
+#define VK_J	'J'
+#define VK_K	'K'
+#define VK_L	'L'
+#define VK_M	'M'
+#define VK_N	'N'
+#define VK_O	'O'
+#define VK_P	'P'
+#define VK_Q	'Q'
+#define VK_R	'R'
+#define VK_S	'S'
+#define VK_T	'T'
+#define VK_U	'U'
+#define VK_V	'V'
+#define VK_W	'W'
+#define VK_X	'X'
+#define VK_Y	'Y'
+#define VK_Z	'Z'
+#endif /* VK_0 */
+
+/* These keys haven't been defined, but were experimentally determined */
+#define VK_SEMICOLON	0xBA
+#define VK_EQUALS	0xBB
+#define VK_COMMA	0xBC
+#define VK_MINUS	0xBD
+#define VK_PERIOD	0xBE
+#define VK_SLASH	0xBF
+#define VK_GRAVE	0xC0
+#define VK_LBRACKET	0xDB
+#define VK_BACKSLASH	0xDC
+#define VK_RBRACKET	0xDD
+#define VK_APOSTROPHE	0xDE
+#define VK_BACKTICK	0xDF
+#define VK_OEM_102	0xE2
+/* vi: set ts=4 sw=4 expandtab: */
--- a/src/video/win32/SDL_win32events.c	Thu Jul 06 05:53:32 2006 +0000
+++ b/src/video/win32/SDL_win32events.c	Thu Jul 06 07:17:11 2006 +0000
@@ -22,8 +22,370 @@
 #include "SDL_config.h"
 
 #include "SDL_win32video.h"
+#include "SDL_version.h"
+#include "SDL_syswm.h"
+#include "SDL_vkeys.h"
 #include "../../events/SDL_events_c.h"
 
+/*#define WMMSG_DEBUG*/
+#ifdef WMMSG_DEBUG
+#include "wmmsg.h"
+#endif
+
+/* Masks for processing the windows KEYDOWN and KEYUP messages */
+#define REPEATED_KEYMASK	(1<<30)
+#define EXTENDED_KEYMASK	(1<<24)
+
+
+static SDLKey
+TranslateKey(WPARAM vkey)
+{
+    SDLKey key;
+
+    /* FIXME: Assign vkey directly to key if in ASCII range */
+    switch (vkey) {
+    case VK_BACK:
+        key = SDLK_BACKSPACE;
+        break;
+    case VK_TAB:
+        key = SDLK_TAB;
+        break;
+    case VK_CLEAR:
+        key = SDLK_CLEAR;
+        break;
+    case VK_RETURN:
+        key = SDLK_RETURN;
+        break;
+    case VK_PAUSE:
+        key = SDLK_PAUSE;
+        break;
+    case VK_ESCAPE:
+        key = SDLK_ESCAPE;
+        break;
+    case VK_SPACE:
+        key = SDLK_SPACE;
+        break;
+    case VK_APOSTROPHE:
+        key = SDLK_QUOTE;
+        break;
+    case VK_COMMA:
+        key = SDLK_COMMA;
+        break;
+    case VK_MINUS:
+        key = SDLK_MINUS;
+        break;
+    case VK_PERIOD:
+        key = SDLK_PERIOD;
+        break;
+    case VK_SLASH:
+        key = SDLK_SLASH;
+        break;
+    case VK_0:
+        key = SDLK_0;
+        break;
+    case VK_1:
+        key = SDLK_1;
+        break;
+    case VK_2:
+        key = SDLK_2;
+        break;
+    case VK_3:
+        key = SDLK_3;
+        break;
+    case VK_4:
+        key = SDLK_4;
+        break;
+    case VK_5:
+        key = SDLK_5;
+        break;
+    case VK_6:
+        key = SDLK_6;
+        break;
+    case VK_7:
+        key = SDLK_7;
+        break;
+    case VK_8:
+        key = SDLK_8;
+        break;
+    case VK_9:
+        key = SDLK_9;
+        break;
+    case VK_SEMICOLON:
+        key = SDLK_SEMICOLON;
+        break;
+    case VK_EQUALS:
+        key = SDLK_EQUALS;
+        break;
+    case VK_LBRACKET:
+        key = SDLK_LEFTBRACKET;
+        break;
+    case VK_BACKSLASH:
+        key = SDLK_BACKSLASH;
+        break;
+    case VK_OEM_102:
+        key = SDLK_LESS;
+        break;
+    case VK_RBRACKET:
+        key = SDLK_RIGHTBRACKET;
+        break;
+    case VK_GRAVE:
+        key = SDLK_BACKQUOTE;
+        break;
+    case VK_BACKTICK:
+        key = SDLK_BACKQUOTE;
+        break;
+    case VK_A:
+        key = SDLK_a;
+        break;
+    case VK_B:
+        key = SDLK_b;
+        break;
+    case VK_C:
+        key = SDLK_c;
+        break;
+    case VK_D:
+        key = SDLK_d;
+        break;
+    case VK_E:
+        key = SDLK_e;
+        break;
+    case VK_F:
+        key = SDLK_f;
+        break;
+    case VK_G:
+        key = SDLK_g;
+        break;
+    case VK_H:
+        key = SDLK_h;
+        break;
+    case VK_I:
+        key = SDLK_i;
+        break;
+    case VK_J:
+        key = SDLK_j;
+        break;
+    case VK_K:
+        key = SDLK_k;
+        break;
+    case VK_L:
+        key = SDLK_l;
+        break;
+    case VK_M:
+        key = SDLK_m;
+        break;
+    case VK_N:
+        key = SDLK_n;
+        break;
+    case VK_O:
+        key = SDLK_o;
+        break;
+    case VK_P:
+        key = SDLK_p;
+        break;
+    case VK_Q:
+        key = SDLK_q;
+        break;
+    case VK_R:
+        key = SDLK_r;
+        break;
+    case VK_S:
+        key = SDLK_s;
+        break;
+    case VK_T:
+        key = SDLK_t;
+        break;
+    case VK_U:
+        key = SDLK_u;
+        break;
+    case VK_V:
+        key = SDLK_v;
+        break;
+    case VK_W:
+        key = SDLK_w;
+        break;
+    case VK_X:
+        key = SDLK_x;
+        break;
+    case VK_Y:
+        key = SDLK_y;
+        break;
+    case VK_Z:
+        key = SDLK_z;
+        break;
+    case VK_DELETE:
+        key = SDLK_DELETE;
+        break;
+    case VK_NUMPAD0:
+        key = SDLK_KP0;
+        break;
+    case VK_NUMPAD1:
+        key = SDLK_KP1;
+        break;
+    case VK_NUMPAD2:
+        key = SDLK_KP2;
+        break;
+    case VK_NUMPAD3:
+        key = SDLK_KP3;
+        break;
+    case VK_NUMPAD4:
+        key = SDLK_KP4;
+        break;
+    case VK_NUMPAD5:
+        key = SDLK_KP5;
+        break;
+    case VK_NUMPAD6:
+        key = SDLK_KP6;
+        break;
+    case VK_NUMPAD7:
+        key = SDLK_KP7;
+        break;
+    case VK_NUMPAD8:
+        key = SDLK_KP8;
+        break;
+    case VK_NUMPAD9:
+        key = SDLK_KP9;
+        break;
+    case VK_DECIMAL:
+        key = SDLK_KP_PERIOD;
+        break;
+    case VK_DIVIDE:
+        key = SDLK_KP_DIVIDE;
+        break;
+    case VK_MULTIPLY:
+        key = SDLK_KP_MULTIPLY;
+        break;
+    case VK_SUBTRACT:
+        key = SDLK_KP_MINUS;
+        break;
+    case VK_ADD:
+        key = SDLK_KP_PLUS;
+        break;
+    case VK_UP:
+        key = SDLK_UP;
+        break;
+    case VK_DOWN:
+        key = SDLK_DOWN;
+        break;
+    case VK_RIGHT:
+        key = SDLK_RIGHT;
+        break;
+    case VK_LEFT:
+        key = SDLK_LEFT;
+        break;
+    case VK_INSERT:
+        key = SDLK_INSERT;
+        break;
+    case VK_HOME:
+        key = SDLK_HOME;
+        break;
+    case VK_END:
+        key = SDLK_END;
+        break;
+    case VK_PRIOR:
+        key = SDLK_PAGEUP;
+        break;
+    case VK_NEXT:
+        key = SDLK_PAGEDOWN;
+        break;
+    case VK_F1:
+        key = SDLK_F1;
+        break;
+    case VK_F2:
+        key = SDLK_F2;
+        break;
+    case VK_F3:
+        key = SDLK_F3;
+        break;
+    case VK_F4:
+        key = SDLK_F4;
+        break;
+    case VK_F5:
+        key = SDLK_F5;
+        break;
+    case VK_F6:
+        key = SDLK_F6;
+        break;
+    case VK_F7:
+        key = SDLK_F7;
+        break;
+    case VK_F8:
+        key = SDLK_F8;
+        break;
+    case VK_F9:
+        key = SDLK_F9;
+        break;
+    case VK_F10:
+        key = SDLK_F10;
+        break;
+    case VK_F11:
+        key = SDLK_F11;
+        break;
+    case VK_F12:
+        key = SDLK_F12;
+        break;
+    case VK_F13:
+        key = SDLK_F13;
+        break;
+    case VK_F14:
+        key = SDLK_F14;
+        break;
+    case VK_F15:
+        key = SDLK_F15;
+        break;
+    case VK_NUMLOCK:
+        key = SDLK_NUMLOCK;
+        break;
+    case VK_CAPITAL:
+        key = SDLK_CAPSLOCK;
+        break;
+    case VK_SCROLL:
+        key = SDLK_SCROLLOCK;
+        break;
+    case VK_RSHIFT:
+        key = SDLK_RSHIFT;
+        break;
+    case VK_LSHIFT:
+        key = SDLK_LSHIFT;
+        break;
+    case VK_RCONTROL:
+        key = SDLK_RCTRL;
+        break;
+    case VK_LCONTROL:
+        key = SDLK_LCTRL;
+        break;
+    case VK_RMENU:
+        key = SDLK_RALT;
+        break;
+    case VK_LMENU:
+        key = SDLK_LALT;
+        break;
+    case VK_RWIN:
+        key = SDLK_RSUPER;
+        break;
+    case VK_LWIN:
+        key = SDLK_LSUPER;
+        break;
+    case VK_HELP:
+        key = SDLK_HELP;
+        break;
+    case VK_PRINT:
+        key = SDLK_PRINT;
+        break;
+    case VK_SNAPSHOT:
+        key = SDLK_PRINT;
+        break;
+    case VK_CANCEL:
+        key = SDLK_BREAK;
+        break;
+    case VK_APPS:
+        key = SDLK_MENU;
+        break;
+    default:
+        key = SDLK_UNKNOWN;
+        break;
+    }
+    return key;
+}
 
 LRESULT CALLBACK
 WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
@@ -35,33 +397,60 @@
     if (!data) {
         return CallWindowProc(DefWindowProc, hwnd, msg, wParam, lParam);
     }
-#if 0
+#ifdef WMMSG_DEBUG
+    fprintf(stderr, "Received windows message:  ");
+    if (msg > MAX_WMMSG) {
+        fprintf(stderr, "%d", msg);
+    } else {
+        fprintf(stderr, "%s", wmtab[msg]);
+    }
+    fprintf(stderr, " -- 0x%X, 0x%X\n", wParam, lParam);
+#endif
+
+    /* Send a SDL_SYSWMEVENT if the application wants them */
+    if (SDL_ProcessEvents[SDL_SYSWMEVENT] == SDL_ENABLE) {
+        SDL_SysWMmsg wmmsg;
+
+        SDL_VERSION(&wmmsg.version);
+        wmmsg.hwnd = hwnd;
+        wmmsg.msg = msg;
+        wmmsg.wParam = wParam;
+        wmmsg.lParam = lParam;
+        SDL_SendSysWMEvent(&wmmsg);
+    }
+
     switch (msg) {
 
     case WM_ACTIVATE:
         {
+            int index;
+            SDL_Keyboard *keyboard;
             BOOL minimized;
 
             minimized = HIWORD(wParam);
+            index = data->videodata->keyboard;
+            keyboard = SDL_GetKeyboard(index);
             if (!minimized && (LOWORD(wParam) != WA_INACTIVE)) {
-                SDL_PrivateWindowEvent(data->windowID, SDL_WINDOWEVENT_SHOWN,
-                                       0, 0);
-                SDL_PrivateWindowEvent(data->windowID,
-                                       SDL_WINDOWEVENT_RESTORED, 0, 0);
+                SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_SHOWN,
+                                    0, 0);
+                SDL_SendWindowEvent(data->windowID,
+                                    SDL_WINDOWEVENT_RESTORED, 0, 0);
                 if (IsZoomed(hwnd)) {
-                    SDL_PrivateWindowEvent(data->windowID,
-                                           SDL_WINDOWEVENT_MAXIMIZED, 0, 0);
+                    SDL_SendWindowEvent(data->windowID,
+                                        SDL_WINDOWEVENT_MAXIMIZED, 0, 0);
                 }
-                SDL_PrivateWindowEvent(data->windowID,
-                                       SDL_WINDOWEVENT_FOCUS_GAINED, 0, 0);
+                if (keyboard && keyboard->focus != data->windowID) {
+                    SDL_SetKeyboardFocus(index, data->windowID);
+                }
                 /* FIXME: Restore mode state (mode, gamma, grab) */
                 /* FIXME: Update keyboard state */
             } else {
-                SDL_PrivateWindowEvent(data->windowID,
-                                       SDL_WINDOWEVENT_FOCUS_LOST, 0, 0);
+                if (keyboard && keyboard->focus == data->windowID) {
+                    SDL_SetKeyboardFocus(index, 0);
+                }
                 if (minimized) {
-                    SDL_PrivateWindowEvent(data->windowID,
-                                           SDL_WINDOWEVENT_MINIMIZED, 0, 0);
+                    SDL_SendWindowEvent(data->windowID,
+                                        SDL_WINDOWEVENT_MINIMIZED, 0, 0);
                 }
                 /* FIXME: Restore desktop state (mode, gamma, grab) */
             }
@@ -73,11 +462,12 @@
         {
             int index;
             SDL_Mouse *mouse;
+            int x, y;
 
-            if (!
-                (SDL_GetWindowFlags(data->windowID) & SDL_WINDOW_MOUSE_FOCUS))
-            {
-                /* mouse has entered the window */
+            index = data->videodata->mouse;
+            mouse = SDL_GetMouse(index);
+
+            if (mouse->focus != data->windowID) {
                 TRACKMOUSEEVENT tme;
 
                 tme.cbSize = sizeof(tme);
@@ -85,41 +475,42 @@
                 tme.hwndTrack = hwnd;
                 TrackMouseEvent(&tme);
 
-                SDL_PrivateWindowEvent(data->windowID, SDL_WINDOWEVENT_ENTER,
-                                       0, 0);
+                SDL_SetMouseFocus(index, data->windowID);
             }
 
-            index = data->videodata->mouse;
-            mouse = SDL_GetMouse(index);
-            if (mouse) {
-                int x, y;
-                /* mouse has moved within the window */
-                x = LOWORD(lParam);
-                y = HIWORD(lParam);
-                if (mouse->relative_mode) {
-                    int w, h;
-                    POINT center;
-                    SDL_GetWindowSize(data->windowID, &w, &h);
-                    center.x = (w / 2);
-                    center.y = (h / 2);
-                    x -= center.x;
-                    y -= center.y;
-                    if (x || y) {
-                        ClientToScreen(SDL_Window, &center);
-                        SetCursorPos(center.x, center.y);
-                        SDL_SendMouseMotion(index, data->windowID, 1, x, y);
-                    }
-                } else {
-                    SDL_SendMouseMotion(index, data->windowID, 0, x, y);
+            /* mouse has moved within the window */
+            x = LOWORD(lParam);
+            y = HIWORD(lParam);
+            if (mouse->relative_mode) {
+                int w, h;
+                POINT center;
+                SDL_GetWindowSize(data->windowID, &w, &h);
+                center.x = (w / 2);
+                center.y = (h / 2);
+                x -= center.x;
+                y -= center.y;
+                if (x || y) {
+                    ClientToScreen(hwnd, &center);
+                    SetCursorPos(center.x, center.y);
+                    SDL_SendMouseMotion(index, 1, x, y);
                 }
+            } else {
+                SDL_SendMouseMotion(index, 0, x, y);
             }
         }
         return (0);
 
     case WM_MOUSELEAVE:
         {
-            SDL_PrivateWindowEvent(data->windowID, SDL_WINDOWEVENT_LEAVE, 0,
-                                   0);
+            int index;
+            SDL_Mouse *mouse;
+
+            index = data->videodata->mouse;
+            mouse = SDL_GetMouse(index);
+
+            if (mouse->focus == data->windowID) {
+                SDL_SetMouseFocus(index, 0);
+            }
         }
         return (0);
 
@@ -130,7 +521,8 @@
     case WM_RBUTTONDOWN:
     case WM_RBUTTONUP:
         {
-            int x, y;
+            int index;
+            SDL_Mouse *mouse;
             Uint8 button, state;
 
             /* DJM:
@@ -138,7 +530,10 @@
                it acts like a normal windows "component"
                (e.g. gains keyboard focus on a mouse click).
              */
-            SetFocus(SDL_Window);
+            SetFocus(hwnd);
+
+            index = data->videodata->mouse;
+            mouse = SDL_GetMouse(index);
 
             /* Figure out which button to use */
             switch (msg) {
@@ -172,85 +567,155 @@
             }
             if (state == SDL_PRESSED) {
                 /* Grab mouse so we get up events */
-                if (++mouse_pressed > 0) {
+                if (++data->mouse_pressed > 0) {
                     SetCapture(hwnd);
                 }
             } else {
                 /* Release mouse after all up events */
-                if (--mouse_pressed <= 0) {
+                if (--data->mouse_pressed <= 0) {
                     ReleaseCapture();
-                    mouse_pressed = 0;
+                    data->mouse_pressed = 0;
                 }
             }
-            x = LOWORD(lParam);
-            y = HIWORD(lParam);
-#ifdef _WIN32_WCE
-            if (SDL_VideoSurface)
-                GapiTransform(this->hidden->userOrientation,
-                              this->hidden->hiresFix, &x, &y);
-#endif
-            posted = SDL_PrivateMouseButton(state, button, x, y);
+
+            if (!mouse->relative_mode) {
+                int x, y;
+                x = LOWORD(lParam);
+                y = HIWORD(lParam);
+                SDL_SendMouseMotion(index, 0, x, y);
+            }
+            SDL_SendMouseButton(index, state, button);
         }
+        return (0);
 
+    case WM_MOUSEWHEEL:
+        {
+            int index;
+            int motion = (short) HIWORD(wParam);
+
+            index = data->videodata->mouse;
+            SDL_SendMouseWheel(index, motion);
+        }
         return (0);
 
+    case WM_SYSKEYDOWN:
+    case WM_KEYDOWN:
+        {
+            int index;
 
-#if (_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)
-    case WM_MOUSEWHEEL:
-        if (SDL_VideoSurface && !DINPUT_FULLSCREEN()) {
-            int move = (short) HIWORD(wParam);
-            if (move) {
-                Uint8 button;
-                if (move > 0)
-                    button = SDL_BUTTON_WHEELUP;
+            /* Ignore repeated keys */
+            if (lParam & REPEATED_KEYMASK) {
+                return (0);
+            }
+
+            index = data->videodata->keyboard;
+            switch (wParam) {
+            case VK_CONTROL:
+                if (lParam & EXTENDED_KEYMASK)
+                    wParam = VK_RCONTROL;
                 else
-                    button = SDL_BUTTON_WHEELDOWN;
-                posted = SDL_PrivateMouseButton(SDL_PRESSED, button, 0, 0);
-                posted |= SDL_PrivateMouseButton(SDL_RELEASED, button, 0, 0);
+                    wParam = VK_LCONTROL;
+                break;
+            case VK_SHIFT:
+                /* EXTENDED trick doesn't work here */
+                {
+                    Uint8 *state = SDL_GetKeyState(NULL);
+                    if (state[SDLK_LSHIFT] == SDL_RELEASED
+                        && (GetKeyState(VK_LSHIFT) & 0x8000)) {
+                        wParam = VK_LSHIFT;
+                    } else if (state[SDLK_RSHIFT] == SDL_RELEASED
+                               && (GetKeyState(VK_RSHIFT) & 0x8000)) {
+                        wParam = VK_RSHIFT;
+                    } else {
+                        /* Probably a key repeat */
+                        return (0);
+                    }
+                }
+                break;
+            case VK_MENU:
+                if (lParam & EXTENDED_KEYMASK)
+                    wParam = VK_RMENU;
+                else
+                    wParam = VK_LMENU;
+                break;
             }
+            SDL_SendKeyboardKey(index, SDL_PRESSED, (Uint8) HIWORD(lParam),
+                                TranslateKey(wParam));
         }
         return (0);
-#endif
+
+    case WM_SYSKEYUP:
+    case WM_KEYUP:
+        {
+            int index;
 
-#ifdef WM_GETMINMAXINFO
-        /* This message is sent as a way for us to "check" the values
-         * of a position change.  If we don't like it, we can adjust
-         * the values before they are changed.
-         */
+            index = data->videodata->keyboard;
+            switch (wParam) {
+            case VK_CONTROL:
+                if (lParam & EXTENDED_KEYMASK)
+                    wParam = VK_RCONTROL;
+                else
+                    wParam = VK_LCONTROL;
+                break;
+            case VK_SHIFT:
+                /* EXTENDED trick doesn't work here */
+                {
+                    Uint8 *state = SDL_GetKeyState(NULL);
+                    if (state[SDLK_LSHIFT] == SDL_PRESSED
+                        && !(GetKeyState(VK_LSHIFT) & 0x8000)) {
+                        wParam = VK_LSHIFT;
+                    } else if (state[SDLK_RSHIFT] == SDL_PRESSED
+                               && !(GetKeyState(VK_RSHIFT) & 0x8000)) {
+                        wParam = VK_RSHIFT;
+                    } else {
+                        /* Probably a key repeat */
+                        return (0);
+                    }
+                }
+                break;
+            case VK_MENU:
+                if (lParam & EXTENDED_KEYMASK)
+                    wParam = VK_RMENU;
+                else
+                    wParam = VK_LMENU;
+                break;
+            }
+            /* Windows only reports keyup for print screen */
+            if (wParam == VK_SNAPSHOT
+                && SDL_GetKeyState(NULL)[SDLK_PRINT] == SDL_RELEASED) {
+                SDL_SendKeyboardKey(index, SDL_PRESSED,
+                                    (Uint8) HIWORD(lParam),
+                                    TranslateKey(wParam));
+            }
+            SDL_SendKeyboardKey(index, SDL_RELEASED, (Uint8) HIWORD(lParam),
+                                TranslateKey(wParam));
+        }
+        return (0);
+
     case WM_GETMINMAXINFO:
         {
             MINMAXINFO *info;
             RECT size;
             int x, y;
+            int w, h;
             int style;
-            int width;
-            int height;
 
-            /* We don't want to clobber an internal resize */
-            if (SDL_resizing)
-                return (0);
-
-            /* We allow resizing with the SDL_RESIZABLE flag */
-            if (SDL_PublicSurface
-                && (SDL_PublicSurface->flags & SDL_RESIZABLE)) {
+            /* If we allow resizing, let the resize happen naturally */
+            if (SDL_GetWindowFlags(data->windowID) & SDL_WINDOW_RESIZABLE) {
                 return (0);
             }
 
             /* Get the current position of our window */
-            GetWindowRect(SDL_Window, &size);
+            GetWindowRect(hwnd, &size);
             x = size.left;
             y = size.top;
 
-            /* Calculate current width and height of our window */
+            /* Calculate current size of our window */
+            SDL_GetWindowSize(data->windowID, &w, &h);
             size.top = 0;
             size.left = 0;
-            if (SDL_PublicSurface != NULL) {
-                size.bottom = SDL_PublicSurface->h;
-                size.right = SDL_PublicSurface->w;
-            } else {
-                size.bottom = 0;
-                size.right = 0;
-            }
+            size.bottom = h;
+            size.right = w;
 
             /* DJM - according to the docs for GetMenu(), the
                return value is undefined if hwnd is a child window.
@@ -263,122 +728,111 @@
                              style & WS_CHILDWINDOW ? FALSE : GetMenu(hwnd) !=
                              NULL);
 
-            width = size.right - size.left;
-            height = size.bottom - size.top;
+            w = size.right - size.left;
+            h = size.bottom - size.top;
 
             /* Fix our size to the current size */
             info = (MINMAXINFO *) lParam;
-            info->ptMaxSize.x = width;
-            info->ptMaxSize.y = height;
+            info->ptMaxSize.x = w;
+            info->ptMaxSize.y = h;
             info->ptMaxPosition.x = x;
             info->ptMaxPosition.y = y;
-            info->ptMinTrackSize.x = width;
-            info->ptMinTrackSize.y = height;
-            info->ptMaxTrackSize.x = width;
-            info->ptMaxTrackSize.y = height;
+            info->ptMinTrackSize.x = w;
+            info->ptMinTrackSize.y = h;
+            info->ptMaxTrackSize.x = w;
+            info->ptMaxTrackSize.y = h;
         }
-
         return (0);
-#endif /* WM_GETMINMAXINFO */
 
     case WM_WINDOWPOSCHANGED:
         {
-            SDL_VideoDevice *this = current_video;
+            RECT rect;
+            int x, y;
             int w, h;
 
-            GetClientRect(SDL_Window, &SDL_bounds);
-            ClientToScreen(SDL_Window, (LPPOINT) & SDL_bounds);
-            ClientToScreen(SDL_Window, (LPPOINT) & SDL_bounds + 1);
-            if (!SDL_resizing && !IsZoomed(SDL_Window) &&
-                SDL_PublicSurface
-                && !(SDL_PublicSurface->flags & SDL_FULLSCREEN)) {
-                SDL_windowX = SDL_bounds.left;
-                SDL_windowY = SDL_bounds.top;
+            GetClientRect(hwnd, &rect);
+            ClientToScreen(hwnd, (LPPOINT) & rect);
+            ClientToScreen(hwnd, (LPPOINT) & rect + 1);
+
+            if (SDL_GetWindowFlags(data->windowID) & SDL_WINDOW_INPUT_GRABBED) {
+                ClipCursor(&rect);
             }
-            w = SDL_bounds.right - SDL_bounds.left;
-            h = SDL_bounds.bottom - SDL_bounds.top;
-            if (this->input_grab != SDL_GRAB_OFF) {
-                ClipCursor(&SDL_bounds);
-            }
-            if (SDL_PublicSurface
-                && (SDL_PublicSurface->flags & SDL_RESIZABLE)) {
-                SDL_PrivateResize(w, h);
-            }
+
+            x = rect.left;
+            y = rect.top;
+            SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_MOVED, x, y);
+
+            w = rect.right - rect.left;
+            h = rect.bottom - rect.top;
+            SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_RESIZED, w,
+                                h);
         }
-
         break;
 
-        /* We need to set the cursor */
     case WM_SETCURSOR:
         {
-            Uint16 hittest;
+            /*
+               Uint16 hittest;
 
-            hittest = LOWORD(lParam);
-            if (hittest == HTCLIENT) {
-                SetCursor(SDL_hcursor);
-                return (TRUE);
-            }
+               hittest = LOWORD(lParam);
+               if (hittest == HTCLIENT) {
+               SetCursor(SDL_hcursor);
+               return (TRUE);
+               }
+             */
         }
-
         break;
 
         /* We are about to get palette focus! */
     case WM_QUERYNEWPALETTE:
         {
-            WIN_RealizePalette(current_video);
-            return (TRUE);
+            /*
+               WIN_RealizePalette(current_video);
+               return (TRUE);
+             */
         }
-
         break;
 
         /* Another application changed the palette */
     case WM_PALETTECHANGED:
         {
-            WIN_PaletteChanged(current_video, (HWND) wParam);
+            /*
+               WIN_PaletteChanged(current_video, (HWND) wParam);
+             */
         }
-
         break;
 
         /* We were occluded, refresh our display */
     case WM_PAINT:
         {
-            HDC hdc;
-            PAINTSTRUCT ps;
-
-            hdc = BeginPaint(SDL_Window, &ps);
-            if (current_video->screen &&
-                !(current_video->screen->flags & SDL_INTERNALOPENGL)) {
-                WIN_WinPAINT(current_video, hdc);
+            RECT rect;
+            if (GetUpdateRect(hwnd, &rect, FALSE)) {
+                ValidateRect(hwnd, &rect);
+                SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_EXPOSED,
+                                    0, 0);
             }
-            EndPaint(SDL_Window, &ps);
         }
-
         return (0);
 
-        /* DJM: Send an expose event in this case */
-    case WM_ERASEBKGND:
+    case WM_SYSCOMMAND:
         {
-            posted = SDL_PrivateExpose();
+            /* Don't start the screensaver or blank the monitor in fullscreen apps */
+            if ((wParam & 0xFFF0) == SC_SCREENSAVE ||
+                (wParam & 0xFFF0) == SC_MONITORPOWER) {
+                if (SDL_GetWindowFlags(data->windowID) &
+                    SDL_WINDOW_FULLSCREEN) {
+                    return (0);
+                }
+            }
         }
-
-        return (0);
+        break;
 
     case WM_CLOSE:
         {
-            if ((posted = SDL_PrivateQuit()))
-                PostQuitMessage(0);
+            SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_CLOSE, 0, 0);
         }
-
-        return (0);
-
-    case WM_DESTROY:
-        {
-            PostQuitMessage(0);
-        }
-
         return (0);
     }
-#endif
     return CallWindowProc(data->wndproc, hwnd, msg, wParam, lParam);
 }
 
--- a/src/video/win32/SDL_win32keyboard.c	Thu Jul 06 05:53:32 2006 +0000
+++ b/src/video/win32/SDL_win32keyboard.c	Thu Jul 06 07:17:11 2006 +0000
@@ -35,4 +35,12 @@
     data->keyboard = SDL_AddKeyboard(&keyboard, -1);
 }
 
+void
+WIN_DelKeyboard(_THIS)
+{
+    SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
+
+    SDL_DelKeyboard(data->keyboard);
+}
+
 /* vi: set ts=4 sw=4 expandtab: */
--- a/src/video/win32/SDL_win32keyboard.h	Thu Jul 06 05:53:32 2006 +0000
+++ b/src/video/win32/SDL_win32keyboard.h	Thu Jul 06 07:17:11 2006 +0000
@@ -25,6 +25,7 @@
 #define _SDL_win32keyboard_h
 
 extern void WIN_AddKeyboard(_THIS);
+extern void WIN_DelKeyboard(_THIS);
 
 #endif /* _SDL_win32keyboard_h */
 
--- a/src/video/win32/SDL_win32mouse.c	Thu Jul 06 05:53:32 2006 +0000
+++ b/src/video/win32/SDL_win32mouse.c	Thu Jul 06 07:17:11 2006 +0000
@@ -35,4 +35,12 @@
     data->mouse = SDL_AddMouse(&mouse, -1);
 }
 
+void
+WIN_DelMouse(_THIS)
+{
+    SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
+
+    SDL_DelMouse(data->mouse);
+}
+
 /* vi: set ts=4 sw=4 expandtab: */
--- a/src/video/win32/SDL_win32mouse.h	Thu Jul 06 05:53:32 2006 +0000
+++ b/src/video/win32/SDL_win32mouse.h	Thu Jul 06 07:17:11 2006 +0000
@@ -25,6 +25,7 @@
 #define _SDL_win32mouse_h
 
 extern void WIN_AddMouse(_THIS);
+extern void WIN_DelMouse(_THIS);
 
 #endif /* _SDL_win32mouse_h */
 
--- a/src/video/win32/SDL_win32video.c	Thu Jul 06 05:53:32 2006 +0000
+++ b/src/video/win32/SDL_win32video.c	Thu Jul 06 07:17:11 2006 +0000
@@ -28,8 +28,7 @@
 #include "../SDL_pixels_c.h"
 
 #include "SDL_win32video.h"
-#include "SDL_win32events.h"
-#include "SDL_win32window.h"
+#include "SDL_dibrender.h"
 
 /* Initialization/Query functions */
 static int WIN_VideoInit(_THIS);
@@ -109,10 +108,51 @@
 int
 WIN_VideoInit(_THIS)
 {
+    int bmi_size;
+    LPBITMAPINFO bmi;
     SDL_DisplayMode mode;
 
-    SDL_AddBasicVideoDisplay(NULL);
-    //SDL_AddRenderDriver(0, &SDL_WIN_RenderDriver);
+    /* Find out the desktop mode */
+    mode.format = SDL_PixelFormat_Unknown;
+    mode.w = GetSystemMetrics(SM_CXSCREEN);
+    mode.h = GetSystemMetrics(SM_CYSCREEN);
+    mode.refresh_rate = 0;
+
+    bmi_size = sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD);
+    bmi = (LPBITMAPINFO) SDL_malloc(bmi_size);
+    if (bmi) {
+        HDC hdc;
+        HBITMAP hbm;
+
+        SDL_memset(bmi, 0, bmi_size);
+        bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+        hdc = GetDC(NULL);
+        hbm = CreateCompatibleBitmap(hdc, 1, 1);
+        GetDIBits(hdc, hbm, 0, 1, NULL, bmi, DIB_RGB_COLORS);
+        GetDIBits(hdc, hbm, 0, 1, NULL, bmi, DIB_RGB_COLORS);
+        DeleteObject(hbm);
+        ReleaseDC(NULL, hdc);
+        if (bmi->bmiHeader.biCompression == BI_BITFIELDS) {
+            switch (*(Uint32 *) bmi->bmiColors) {
+            case 0x00FF0000:
+                mode.format = SDL_PixelFormat_RGB888;
+                break;
+            case 0x000000FF:
+                mode.format = SDL_PixelFormat_BGR888;
+                break;
+            case 0xF800:
+                mode.format = SDL_PixelFormat_RGB565;
+                break;
+            case 0x7C00:
+                mode.format = SDL_PixelFormat_RGB555;
+                break;
+            }
+        } else if (bmi->bmiHeader.biBitCount == 8) {
+            mode.format = SDL_PixelFormat_Index8;
+        }
+    }
+    SDL_AddBasicVideoDisplay(&mode);
+    SDL_AddRenderDriver(0, &SDL_DIB_RenderDriver);
 
     SDL_zero(mode);
     SDL_AddDisplayMode(0, &mode);
@@ -134,6 +174,8 @@
 void
 WIN_VideoQuit(_THIS)
 {
+    WIN_DelKeyboard(_this);
+    WIN_DelMouse(_this);
 }
 
 /* vim: set ts=4 sw=4 expandtab: */
--- a/src/video/win32/SDL_win32video.h	Thu Jul 06 05:53:32 2006 +0000
+++ b/src/video/win32/SDL_win32video.h	Thu Jul 06 07:17:11 2006 +0000
@@ -28,6 +28,7 @@
 
 #define WIN32_LEAN_AND_MEAN
 #define UNICODE
+#define WINVER  0x0410          // 0x0410 needed for AlphaBlend()
 #include <windows.h>
 
 #include "SDL_win32events.h"
--- a/src/video/win32/SDL_win32window.c	Thu Jul 06 05:53:32 2006 +0000
+++ b/src/video/win32/SDL_win32window.c	Thu Jul 06 07:17:11 2006 +0000
@@ -43,6 +43,7 @@
     data->windowID = window->id;
     data->hwnd = hwnd;
     data->created = created;
+    data->mouse_pressed = SDL_FALSE;
     data->videodata = (SDL_VideoData *) SDL_GetVideoDevice()->driverdata;
 
     /* Associate the data with the window */
@@ -180,6 +181,8 @@
     hwnd = CreateWindow(SDL_Appname,
                         title ? title : TEXT(""),
                         style, x, y, w, h, NULL, NULL, SDL_Instance, NULL);
+    WIN_PumpEvents(_this);
+
     if (title) {
         SDL_free(title);
     }
--- a/src/video/win32/SDL_win32window.h	Thu Jul 06 05:53:32 2006 +0000
+++ b/src/video/win32/SDL_win32window.h	Thu Jul 06 07:17:11 2006 +0000
@@ -33,6 +33,7 @@
     HWND hwnd;
     WNDPROC wndproc;
     BOOL created;
+    int mouse_pressed;
     struct SDL_VideoData *videodata;
 } SDL_WindowData;
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/video/win32/wmmsg.h	Thu Jul 06 07:17:11 2006 +0000
@@ -0,0 +1,1032 @@
+
+#define MAX_WMMSG	(sizeof(wmtab)/sizeof(wmtab[0]))
+
+char *wmtab[] = {
+    "WM_NULL",
+    "WM_CREATE",
+    "WM_DESTROY",
+    "WM_MOVE",
+    "UNKNOWN (4)",
+    "WM_SIZE",
+    "WM_ACTIVATE",
+    "WM_SETFOCUS",
+    "WM_KILLFOCUS",
+    "UNKNOWN (9)",
+    "WM_ENABLE",
+    "WM_SETREDRAW",
+    "WM_SETTEXT",
+    "WM_GETTEXT",
+    "WM_GETTEXTLENGTH",
+    "WM_PAINT",
+    "WM_CLOSE",
+    "WM_QUERYENDSESSION",
+    "WM_QUIT",
+    "WM_QUERYOPEN",
+    "WM_ERASEBKGND",
+    "WM_SYSCOLORCHANGE",
+    "WM_ENDSESSION",
+    "UNKNOWN (23)",
+    "WM_SHOWWINDOW",
+    "UNKNOWN (25)",
+    "WM_SETTINGCHANGE",
+    "WM_DEVMODECHANGE",
+    "WM_ACTIVATEAPP",
+    "WM_FONTCHANGE",
+    "WM_TIMECHANGE",
+    "WM_CANCELMODE",
+    "WM_SETCURSOR",
+    "WM_MOUSEACTIVATE",
+    "WM_CHILDACTIVATE",
+    "WM_QUEUESYNC",
+    "WM_GETMINMAXINFO",
+    "UNKNOWN (37)",
+    "WM_PAINTICON",
+    "WM_ICONERASEBKGND",
+    "WM_NEXTDLGCTL",
+    "UNKNOWN (41)",
+    "WM_SPOOLERSTATUS",
+    "WM_DRAWITEM",
+    "WM_MEASUREITEM",
+    "WM_DELETEITEM",
+    "WM_VKEYTOITEM",
+    "WM_CHARTOITEM",
+    "WM_SETFONT",
+    "WM_GETFONT",
+    "WM_SETHOTKEY",
+    "WM_GETHOTKEY",
+    "UNKNOWN (52)",
+    "UNKNOWN (53)",
+    "UNKNOWN (54)",
+    "WM_QUERYDRAGICON",
+    "UNKNOWN (56)",
+    "WM_COMPAREITEM",
+    "UNKNOWN (58)",
+    "UNKNOWN (59)",
+    "UNKNOWN (60)",
+    "WM_GETOBJECT",
+    "UNKNOWN (62)",
+    "UNKNOWN (63)",
+    "UNKNOWN (64)",
+    "WM_COMPACTING",
+    "UNKNOWN (66)",
+    "UNKNOWN (67)",
+    "WM_COMMNOTIFY",
+    "UNKNOWN (69)",
+    "WM_WINDOWPOSCHANGING",
+    "WM_WINDOWPOSCHANGED",
+    "WM_POWER",
+    "UNKNOWN (73)",
+    "WM_COPYDATA",
+    "WM_CANCELJOURNAL",
+    "UNKNOWN (76)",
+    "UNKNOWN (77)",
+    "WM_NOTIFY",
+    "UNKNOWN (79)",
+    "WM_INPUTLANGCHANGEREQUEST",
+    "WM_INPUTLANGCHANGE",
+    "WM_TCARD",
+    "WM_HELP",
+    "WM_USERCHANGED",
+    "WM_NOTIFYFORMAT",
+    "UNKNOWN (86)",
+    "UNKNOWN (87)",
+    "UNKNOWN (88)",
+    "UNKNOWN (89)",
+    "UNKNOWN (90)",
+    "UNKNOWN (91)",
+    "UNKNOWN (92)",
+    "UNKNOWN (93)",
+    "UNKNOWN (94)",
+    "UNKNOWN (95)",
+    "UNKNOWN (96)",
+    "UNKNOWN (97)",
+    "UNKNOWN (98)",
+    "UNKNOWN (99)",
+    "UNKNOWN (100)",
+    "UNKNOWN (101)",
+    "UNKNOWN (102)",
+    "UNKNOWN (103)",
+    "UNKNOWN (104)",
+    "UNKNOWN (105)",
+    "UNKNOWN (106)",
+    "UNKNOWN (107)",
+    "UNKNOWN (108)",
+    "UNKNOWN (109)",
+    "UNKNOWN (110)",
+    "UNKNOWN (111)",
+    "UNKNOWN (112)",
+    "UNKNOWN (113)",
+    "UNKNOWN (114)",
+    "UNKNOWN (115)",
+    "UNKNOWN (116)",
+    "UNKNOWN (117)",
+    "UNKNOWN (118)",
+    "UNKNOWN (119)",
+    "UNKNOWN (120)",
+    "UNKNOWN (121)",
+    "UNKNOWN (122)",
+    "WM_CONTEXTMENU",
+    "WM_STYLECHANGING",
+    "WM_STYLECHANGED",
+    "WM_DISPLAYCHANGE",
+    "WM_GETICON",
+    "WM_SETICON",
+    "WM_NCCREATE",
+    "WM_NCDESTROY",
+    "WM_NCCALCSIZE",
+    "WM_NCHITTEST",
+    "WM_NCPAINT",
+    "WM_NCACTIVATE",
+    "WM_GETDLGCODE",
+    "WM_SYNCPAINT",
+    "UNKNOWN (137)",
+    "UNKNOWN (138)",
+    "UNKNOWN (139)",
+    "UNKNOWN (140)",
+    "UNKNOWN (141)",
+    "UNKNOWN (142)",
+    "UNKNOWN (143)",
+    "UNKNOWN (144)",
+    "UNKNOWN (145)",
+    "UNKNOWN (146)",
+    "UNKNOWN (147)",
+    "UNKNOWN (148)",
+    "UNKNOWN (149)",
+    "UNKNOWN (150)",
+    "UNKNOWN (151)",
+    "UNKNOWN (152)",
+    "UNKNOWN (153)",
+    "UNKNOWN (154)",
+    "UNKNOWN (155)",
+    "UNKNOWN (156)",
+    "UNKNOWN (157)",
+    "UNKNOWN (158)",
+    "UNKNOWN (159)",
+    "WM_NCMOUSEMOVE",
+    "WM_NCLBUTTONDOWN",
+    "WM_NCLBUTTONUP",
+    "WM_NCLBUTTONDBLCLK",
+    "WM_NCRBUTTONDOWN",
+    "WM_NCRBUTTONUP",
+    "WM_NCRBUTTONDBLCLK",
+    "WM_NCMBUTTONDOWN",
+    "WM_NCMBUTTONUP",
+    "WM_NCMBUTTONDBLCLK",
+    "UNKNOWN (170)",
+    "UNKNOWN (171)",
+    "UNKNOWN (172)",
+    "UNKNOWN (173)",
+    "UNKNOWN (174)",
+    "UNKNOWN (175)",
+    "UNKNOWN (176)",
+    "UNKNOWN (177)",
+    "UNKNOWN (178)",
+    "UNKNOWN (179)",
+    "UNKNOWN (180)",
+    "UNKNOWN (181)",
+    "UNKNOWN (182)",
+    "UNKNOWN (183)",
+    "UNKNOWN (184)",
+    "UNKNOWN (185)",
+    "UNKNOWN (186)",
+    "UNKNOWN (187)",
+    "UNKNOWN (188)",
+    "UNKNOWN (189)",
+    "UNKNOWN (190)",
+    "UNKNOWN (191)",
+    "UNKNOWN (192)",
+    "UNKNOWN (193)",
+    "UNKNOWN (194)",
+    "UNKNOWN (195)",
+    "UNKNOWN (196)",
+    "UNKNOWN (197)",
+    "UNKNOWN (198)",
+    "UNKNOWN (199)",
+    "UNKNOWN (200)",
+    "UNKNOWN (201)",
+    "UNKNOWN (202)",
+    "UNKNOWN (203)",
+    "UNKNOWN (204)",
+    "UNKNOWN (205)",
+    "UNKNOWN (206)",
+    "UNKNOWN (207)",
+    "UNKNOWN (208)",
+    "UNKNOWN (209)",
+    "UNKNOWN (210)",
+    "UNKNOWN (211)",
+    "UNKNOWN (212)",
+    "UNKNOWN (213)",
+    "UNKNOWN (214)",
+    "UNKNOWN (215)",
+    "UNKNOWN (216)",
+    "UNKNOWN (217)",
+    "UNKNOWN (218)",
+    "UNKNOWN (219)",
+    "UNKNOWN (220)",
+    "UNKNOWN (221)",
+    "UNKNOWN (222)",
+    "UNKNOWN (223)",
+    "UNKNOWN (224)",
+    "UNKNOWN (225)",
+    "UNKNOWN (226)",
+    "UNKNOWN (227)",
+    "UNKNOWN (228)",
+    "UNKNOWN (229)",
+    "UNKNOWN (230)",
+    "UNKNOWN (231)",
+    "UNKNOWN (232)",
+    "UNKNOWN (233)",
+    "UNKNOWN (234)",
+    "UNKNOWN (235)",
+    "UNKNOWN (236)",
+    "UNKNOWN (237)",
+    "UNKNOWN (238)",
+    "UNKNOWN (239)",
+    "UNKNOWN (240)",
+    "UNKNOWN (241)",
+    "UNKNOWN (242)",
+    "UNKNOWN (243)",
+    "UNKNOWN (244)",
+    "UNKNOWN (245)",
+    "UNKNOWN (246)",
+    "UNKNOWN (247)",
+    "UNKNOWN (248)",
+    "UNKNOWN (249)",
+    "UNKNOWN (250)",
+    "UNKNOWN (251)",
+    "UNKNOWN (252)",
+    "UNKNOWN (253)",
+    "UNKNOWN (254)",
+    "UNKNOWN (255)",
+    "WM_KEYDOWN",
+    "WM_KEYUP",
+    "WM_CHAR",
+    "WM_DEADCHAR",
+    "WM_SYSKEYDOWN",
+    "WM_SYSKEYUP",
+    "WM_SYSCHAR",
+    "WM_SYSDEADCHAR",
+    "WM_KEYLAST",
+    "UNKNOWN (265)",
+    "UNKNOWN (266)",
+    "UNKNOWN (267)",
+    "UNKNOWN (268)",
+    "UNKNOWN (269)",
+    "UNKNOWN (270)",
+    "UNKNOWN (271)",
+    "WM_INITDIALOG",
+    "WM_COMMAND",
+    "WM_SYSCOMMAND",
+    "WM_TIMER",
+    "WM_HSCROLL",
+    "WM_VSCROLL",
+    "WM_INITMENU",
+    "WM_INITMENUPOPUP",
+    "UNKNOWN (280)",
+    "UNKNOWN (281)",
+    "UNKNOWN (282)",
+    "UNKNOWN (283)",
+    "UNKNOWN (284)",
+    "UNKNOWN (285)",
+    "UNKNOWN (286)",
+    "WM_MENUSELECT",
+    "WM_MENUCHAR",
+    "WM_ENTERIDLE",
+    "WM_MENURBUTTONUP",
+    "WM_MENUDRAG",
+    "WM_MENUGETOBJECT",
+    "WM_UNINITMENUPOPUP",
+    "WM_MENUCOMMAND",
+    "UNKNOWN (295)",
+    "UNKNOWN (296)",
+    "UNKNOWN (297)",
+    "UNKNOWN (298)",
+    "UNKNOWN (299)",
+    "UNKNOWN (300)",
+    "UNKNOWN (301)",
+    "UNKNOWN (302)",
+    "UNKNOWN (303)",
+    "UNKNOWN (304)",
+    "UNKNOWN (305)",
+    "WM_CTLCOLORMSGBOX",
+    "WM_CTLCOLOREDIT",
+    "WM_CTLCOLORLISTBOX",
+    "WM_CTLCOLORBTN",
+    "WM_CTLCOLORDLG",
+    "WM_CTLCOLORSCROLLBAR",
+    "WM_CTLCOLORSTATIC",
+    "UNKNOWN (313)",
+    "UNKNOWN (314)",
+    "UNKNOWN (315)",
+    "UNKNOWN (316)",
+    "UNKNOWN (317)",
+    "UNKNOWN (318)",
+    "UNKNOWN (319)",
+    "UNKNOWN (320)",
+    "UNKNOWN (321)",
+    "UNKNOWN (322)",
+    "UNKNOWN (323)",
+    "UNKNOWN (324)",
+    "UNKNOWN (325)",
+    "UNKNOWN (326)",
+    "UNKNOWN (327)",
+    "UNKNOWN (328)",
+    "UNKNOWN (329)",
+    "UNKNOWN (330)",
+    "UNKNOWN (331)",
+    "UNKNOWN (332)",
+    "UNKNOWN (333)",
+    "UNKNOWN (334)",
+    "UNKNOWN (335)",
+    "UNKNOWN (336)",
+    "UNKNOWN (337)",
+    "UNKNOWN (338)",
+    "UNKNOWN (339)",
+    "UNKNOWN (340)",
+    "UNKNOWN (341)",
+    "UNKNOWN (342)",
+    "UNKNOWN (343)",
+    "UNKNOWN (344)",
+    "UNKNOWN (345)",
+    "UNKNOWN (346)",
+    "UNKNOWN (347)",
+    "UNKNOWN (348)",
+    "UNKNOWN (349)",
+    "UNKNOWN (350)",
+    "UNKNOWN (351)",
+    "UNKNOWN (352)",
+    "UNKNOWN (353)",
+    "UNKNOWN (354)",
+    "UNKNOWN (355)",
+    "UNKNOWN (356)",
+    "UNKNOWN (357)",
+    "UNKNOWN (358)",
+    "UNKNOWN (359)",
+    "UNKNOWN (360)",
+    "UNKNOWN (361)",
+    "UNKNOWN (362)",
+    "UNKNOWN (363)",
+    "UNKNOWN (364)",
+    "UNKNOWN (365)",
+    "UNKNOWN (366)",
+    "UNKNOWN (367)",
+    "UNKNOWN (368)",
+    "UNKNOWN (369)",
+    "UNKNOWN (370)",
+    "UNKNOWN (371)",
+    "UNKNOWN (372)",
+    "UNKNOWN (373)",
+    "UNKNOWN (374)",
+    "UNKNOWN (375)",
+    "UNKNOWN (376)",
+    "UNKNOWN (377)",
+    "UNKNOWN (378)",
+    "UNKNOWN (379)",
+    "UNKNOWN (380)",
+    "UNKNOWN (381)",
+    "UNKNOWN (382)",
+    "UNKNOWN (383)",
+    "UNKNOWN (384)",
+    "UNKNOWN (385)",
+    "UNKNOWN (386)",
+    "UNKNOWN (387)",
+    "UNKNOWN (388)",
+    "UNKNOWN (389)",
+    "UNKNOWN (390)",
+    "UNKNOWN (391)",
+    "UNKNOWN (392)",
+    "UNKNOWN (393)",
+    "UNKNOWN (394)",
+    "UNKNOWN (395)",
+    "UNKNOWN (396)",
+    "UNKNOWN (397)",
+    "UNKNOWN (398)",
+    "UNKNOWN (399)",
+    "UNKNOWN (400)",
+    "UNKNOWN (401)",
+    "UNKNOWN (402)",
+    "UNKNOWN (403)",
+    "UNKNOWN (404)",
+    "UNKNOWN (405)",
+    "UNKNOWN (406)",
+    "UNKNOWN (407)",
+    "UNKNOWN (408)",
+    "UNKNOWN (409)",
+    "UNKNOWN (410)",
+    "UNKNOWN (411)",
+    "UNKNOWN (412)",
+    "UNKNOWN (413)",
+    "UNKNOWN (414)",
+    "UNKNOWN (415)",
+    "UNKNOWN (416)",
+    "UNKNOWN (417)",
+    "UNKNOWN (418)",
+    "UNKNOWN (419)",
+    "UNKNOWN (420)",
+    "UNKNOWN (421)",
+    "UNKNOWN (422)",
+    "UNKNOWN (423)",
+    "UNKNOWN (424)",
+    "UNKNOWN (425)",
+    "UNKNOWN (426)",
+    "UNKNOWN (427)",
+    "UNKNOWN (428)",
+    "UNKNOWN (429)",
+    "UNKNOWN (430)",
+    "UNKNOWN (431)",
+    "UNKNOWN (432)",
+    "UNKNOWN (433)",
+    "UNKNOWN (434)",
+    "UNKNOWN (435)",
+    "UNKNOWN (436)",
+    "UNKNOWN (437)",
+    "UNKNOWN (438)",
+    "UNKNOWN (439)",
+    "UNKNOWN (440)",
+    "UNKNOWN (441)",
+    "UNKNOWN (442)",
+    "UNKNOWN (443)",
+    "UNKNOWN (444)",
+    "UNKNOWN (445)",
+    "UNKNOWN (446)",
+    "UNKNOWN (447)",
+    "UNKNOWN (448)",
+    "UNKNOWN (449)",
+    "UNKNOWN (450)",
+    "UNKNOWN (451)",
+    "UNKNOWN (452)",
+    "UNKNOWN (453)",
+    "UNKNOWN (454)",
+    "UNKNOWN (455)",
+    "UNKNOWN (456)",
+    "UNKNOWN (457)",
+    "UNKNOWN (458)",
+    "UNKNOWN (459)",
+    "UNKNOWN (460)",
+    "UNKNOWN (461)",
+    "UNKNOWN (462)",
+    "UNKNOWN (463)",
+    "UNKNOWN (464)",
+    "UNKNOWN (465)",
+    "UNKNOWN (466)",
+    "UNKNOWN (467)",
+    "UNKNOWN (468)",
+    "UNKNOWN (469)",
+    "UNKNOWN (470)",
+    "UNKNOWN (471)",
+    "UNKNOWN (472)",
+    "UNKNOWN (473)",
+    "UNKNOWN (474)",
+    "UNKNOWN (475)",
+    "UNKNOWN (476)",
+    "UNKNOWN (477)",
+    "UNKNOWN (478)",
+    "UNKNOWN (479)",
+    "UNKNOWN (480)",
+    "UNKNOWN (481)",
+    "UNKNOWN (482)",
+    "UNKNOWN (483)",
+    "UNKNOWN (484)",
+    "UNKNOWN (485)",
+    "UNKNOWN (486)",
+    "UNKNOWN (487)",
+    "UNKNOWN (488)",
+    "UNKNOWN (489)",
+    "UNKNOWN (490)",
+    "UNKNOWN (491)",
+    "UNKNOWN (492)",
+    "UNKNOWN (493)",
+    "UNKNOWN (494)",
+    "UNKNOWN (495)",
+    "UNKNOWN (496)",
+    "UNKNOWN (497)",
+    "UNKNOWN (498)",
+    "UNKNOWN (499)",
+    "UNKNOWN (500)",
+    "UNKNOWN (501)",
+    "UNKNOWN (502)",
+    "UNKNOWN (503)",
+    "UNKNOWN (504)",
+    "UNKNOWN (505)",
+    "UNKNOWN (506)",
+    "UNKNOWN (507)",
+    "UNKNOWN (508)",
+    "UNKNOWN (509)",
+    "UNKNOWN (510)",
+    "UNKNOWN (511)",
+    "WM_MOUSEMOVE",
+    "WM_LBUTTONDOWN",
+    "WM_LBUTTONUP",
+    "WM_LBUTTONDBLCLK",
+    "WM_RBUTTONDOWN",
+    "WM_RBUTTONUP",
+    "WM_RBUTTONDBLCLK",
+    "WM_MBUTTONDOWN",
+    "WM_MBUTTONUP",
+    "WM_MOUSELAST",
+    "WM_MOUSELAST",
+    "UNKNOWN (523)",
+    "UNKNOWN (524)",
+    "UNKNOWN (525)",
+    "UNKNOWN (526)",
+    "UNKNOWN (527)",
+    "WM_PARENTNOTIFY",
+    "WM_ENTERMENULOOP",
+    "WM_EXITMENULOOP",
+    "WM_NEXTMENU",
+    "WM_SIZING",
+    "WM_CAPTURECHANGED",
+    "WM_MOVING",
+    "UNKNOWN (535)",
+    "WM_POWERBROADCAST",
+    "WM_DEVICECHANGE",
+    "UNKNOWN (538)",
+    "UNKNOWN (539)",
+    "UNKNOWN (540)",
+    "UNKNOWN (541)",
+    "UNKNOWN (542)",
+    "UNKNOWN (543)",
+    "WM_MDICREATE",
+    "WM_MDIDESTROY",
+    "WM_MDIACTIVATE",
+    "WM_MDIRESTORE",
+    "WM_MDINEXT",
+    "WM_MDIMAXIMIZE",
+    "WM_MDITILE",
+    "WM_MDICASCADE",
+    "WM_MDIICONARRANGE",
+    "WM_MDIGETACTIVE",
+    "UNKNOWN (554)",
+    "UNKNOWN (555)",
+    "UNKNOWN (556)",
+    "UNKNOWN (557)",
+    "UNKNOWN (558)",
+    "UNKNOWN (559)",
+    "WM_MDISETMENU",
+    "WM_ENTERSIZEMOVE",
+    "WM_EXITSIZEMOVE",
+    "WM_DROPFILES",
+    "WM_MDIREFRESHMENU",
+    "UNKNOWN (565)",
+    "UNKNOWN (566)",
+    "UNKNOWN (567)",
+    "UNKNOWN (568)",
+    "UNKNOWN (569)",
+    "UNKNOWN (570)",
+    "UNKNOWN (571)",
+    "UNKNOWN (572)",
+    "UNKNOWN (573)",
+    "UNKNOWN (574)",
+    "UNKNOWN (575)",
+    "UNKNOWN (576)",
+    "UNKNOWN (577)",
+    "UNKNOWN (578)",
+    "UNKNOWN (579)",
+    "UNKNOWN (580)",
+    "UNKNOWN (581)",
+    "UNKNOWN (582)",
+    "UNKNOWN (583)",
+    "UNKNOWN (584)",
+    "UNKNOWN (585)",
+    "UNKNOWN (586)",
+    "UNKNOWN (587)",
+    "UNKNOWN (588)",
+    "UNKNOWN (589)",
+    "UNKNOWN (590)",
+    "UNKNOWN (591)",
+    "UNKNOWN (592)",
+    "UNKNOWN (593)",
+    "UNKNOWN (594)",
+    "UNKNOWN (595)",
+    "UNKNOWN (596)",
+    "UNKNOWN (597)",
+    "UNKNOWN (598)",
+    "UNKNOWN (599)",
+    "UNKNOWN (600)",
+    "UNKNOWN (601)",
+    "UNKNOWN (602)",
+    "UNKNOWN (603)",
+    "UNKNOWN (604)",
+    "UNKNOWN (605)",
+    "UNKNOWN (606)",
+    "UNKNOWN (607)",
+    "UNKNOWN (608)",
+    "UNKNOWN (609)",
+    "UNKNOWN (610)",
+    "UNKNOWN (611)",
+    "UNKNOWN (612)",
+    "UNKNOWN (613)",
+    "UNKNOWN (614)",
+    "UNKNOWN (615)",
+    "UNKNOWN (616)",
+    "UNKNOWN (617)",
+    "UNKNOWN (618)",
+    "UNKNOWN (619)",
+    "UNKNOWN (620)",
+    "UNKNOWN (621)",
+    "UNKNOWN (622)",
+    "UNKNOWN (623)",
+    "UNKNOWN (624)",
+    "UNKNOWN (625)",
+    "UNKNOWN (626)",
+    "UNKNOWN (627)",
+    "UNKNOWN (628)",
+    "UNKNOWN (629)",
+    "UNKNOWN (630)",
+    "UNKNOWN (631)",
+    "UNKNOWN (632)",
+    "UNKNOWN (633)",
+    "UNKNOWN (634)",
+    "UNKNOWN (635)",
+    "UNKNOWN (636)",
+    "UNKNOWN (637)",
+    "UNKNOWN (638)",
+    "UNKNOWN (639)",
+    "UNKNOWN (640)",
+    "UNKNOWN (641)",
+    "UNKNOWN (642)",
+    "UNKNOWN (643)",
+    "UNKNOWN (644)",
+    "UNKNOWN (645)",
+    "UNKNOWN (646)",
+    "UNKNOWN (647)",
+    "UNKNOWN (648)",
+    "UNKNOWN (649)",
+    "UNKNOWN (650)",
+    "UNKNOWN (651)",
+    "UNKNOWN (652)",
+    "UNKNOWN (653)",
+    "UNKNOWN (654)",
+    "UNKNOWN (655)",
+    "UNKNOWN (656)",
+    "UNKNOWN (657)",
+    "UNKNOWN (658)",
+    "UNKNOWN (659)",
+    "UNKNOWN (660)",
+    "UNKNOWN (661)",
+    "UNKNOWN (662)",
+    "UNKNOWN (663)",
+    "UNKNOWN (664)",
+    "UNKNOWN (665)",
+    "UNKNOWN (666)",
+    "UNKNOWN (667)",
+    "UNKNOWN (668)",
+    "UNKNOWN (669)",
+    "UNKNOWN (670)",
+    "UNKNOWN (671)",
+    "UNKNOWN (672)",
+    "WM_MOUSEHOVER",
+    "UNKNOWN (674)",
+    "WM_MOUSELEAVE",
+    "UNKNOWN (676)",
+    "UNKNOWN (677)",
+    "UNKNOWN (678)",
+    "UNKNOWN (679)",
+    "UNKNOWN (680)",
+    "UNKNOWN (681)",
+    "UNKNOWN (682)",
+    "UNKNOWN (683)",
+    "UNKNOWN (684)",
+    "UNKNOWN (685)",
+    "UNKNOWN (686)",
+    "UNKNOWN (687)",
+    "UNKNOWN (688)",
+    "UNKNOWN (689)",
+    "UNKNOWN (690)",
+    "UNKNOWN (691)",
+    "UNKNOWN (692)",
+    "UNKNOWN (693)",
+    "UNKNOWN (694)",
+    "UNKNOWN (695)",
+    "UNKNOWN (696)",
+    "UNKNOWN (697)",
+    "UNKNOWN (698)",
+    "UNKNOWN (699)",
+    "UNKNOWN (700)",
+    "UNKNOWN (701)",
+    "UNKNOWN (702)",
+    "UNKNOWN (703)",
+    "UNKNOWN (704)",
+    "UNKNOWN (705)",
+    "UNKNOWN (706)",
+    "UNKNOWN (707)",
+    "UNKNOWN (708)",
+    "UNKNOWN (709)",
+    "UNKNOWN (710)",
+    "UNKNOWN (711)",
+    "UNKNOWN (712)",
+    "UNKNOWN (713)",
+    "UNKNOWN (714)",
+    "UNKNOWN (715)",
+    "UNKNOWN (716)",
+    "UNKNOWN (717)",
+    "UNKNOWN (718)",
+    "UNKNOWN (719)",
+    "UNKNOWN (720)",
+    "UNKNOWN (721)",
+    "UNKNOWN (722)",
+    "UNKNOWN (723)",
+    "UNKNOWN (724)",
+    "UNKNOWN (725)",
+    "UNKNOWN (726)",
+    "UNKNOWN (727)",
+    "UNKNOWN (728)",
+    "UNKNOWN (729)",
+    "UNKNOWN (730)",
+    "UNKNOWN (731)",
+    "UNKNOWN (732)",
+    "UNKNOWN (733)",
+    "UNKNOWN (734)",
+    "UNKNOWN (735)",
+    "UNKNOWN (736)",
+    "UNKNOWN (737)",
+    "UNKNOWN (738)",
+    "UNKNOWN (739)",
+    "UNKNOWN (740)",
+    "UNKNOWN (741)",
+    "UNKNOWN (742)",
+    "UNKNOWN (743)",
+    "UNKNOWN (744)",
+    "UNKNOWN (745)",
+    "UNKNOWN (746)",
+    "UNKNOWN (747)",
+    "UNKNOWN (748)",
+    "UNKNOWN (749)",
+    "UNKNOWN (750)",
+    "UNKNOWN (751)",
+    "UNKNOWN (752)",
+    "UNKNOWN (753)",
+    "UNKNOWN (754)",
+    "UNKNOWN (755)",
+    "UNKNOWN (756)",
+    "UNKNOWN (757)",
+    "UNKNOWN (758)",
+    "UNKNOWN (759)",
+    "UNKNOWN (760)",
+    "UNKNOWN (761)",
+    "UNKNOWN (762)",
+    "UNKNOWN (763)",
+    "UNKNOWN (764)",
+    "UNKNOWN (765)",
+    "UNKNOWN (766)",
+    "UNKNOWN (767)",
+    "WM_CUT",
+    "WM_COPY",
+    "WM_PASTE",
+    "WM_CLEAR",
+    "WM_UNDO",
+    "WM_RENDERFORMAT",
+    "WM_RENDERALLFORMATS",
+    "WM_DESTROYCLIPBOARD",
+    "WM_DRAWCLIPBOARD",
+    "WM_PAINTCLIPBOARD",
+    "WM_VSCROLLCLIPBOARD",
+    "WM_SIZECLIPBOARD",
+    "WM_ASKCBFORMATNAME",
+    "WM_CHANGECBCHAIN",
+    "WM_HSCROLLCLIPBOARD",
+    "WM_QUERYNEWPALETTE",
+    "WM_PALETTEISCHANGING",
+    "WM_PALETTECHANGED",
+    "WM_HOTKEY",
+    "UNKNOWN (787)",
+    "UNKNOWN (788)",
+    "UNKNOWN (789)",
+    "UNKNOWN (790)",
+    "WM_PRINT",
+    "WM_PRINTCLIENT",
+    "UNKNOWN (793)",
+    "UNKNOWN (794)",
+    "UNKNOWN (795)",
+    "UNKNOWN (796)",
+    "UNKNOWN (797)",
+    "UNKNOWN (798)",
+    "UNKNOWN (799)",
+    "UNKNOWN (800)",
+    "UNKNOWN (801)",
+    "UNKNOWN (802)",
+    "UNKNOWN (803)",
+    "UNKNOWN (804)",
+    "UNKNOWN (805)",
+    "UNKNOWN (806)",
+    "UNKNOWN (807)",
+    "UNKNOWN (808)",
+    "UNKNOWN (809)",
+    "UNKNOWN (810)",
+    "UNKNOWN (811)",
+    "UNKNOWN (812)",
+    "UNKNOWN (813)",
+    "UNKNOWN (814)",
+    "UNKNOWN (815)",
+    "UNKNOWN (816)",
+    "UNKNOWN (817)",
+    "UNKNOWN (818)",
+    "UNKNOWN (819)",
+    "UNKNOWN (820)",
+    "UNKNOWN (821)",
+    "UNKNOWN (822)",
+    "UNKNOWN (823)",
+    "UNKNOWN (824)",
+    "UNKNOWN (825)",
+    "UNKNOWN (826)",
+    "UNKNOWN (827)",
+    "UNKNOWN (828)",
+    "UNKNOWN (829)",
+    "UNKNOWN (830)",
+    "UNKNOWN (831)",
+    "UNKNOWN (832)",
+    "UNKNOWN (833)",
+    "UNKNOWN (834)",
+    "UNKNOWN (835)",
+    "UNKNOWN (836)",
+    "UNKNOWN (837)",
+    "UNKNOWN (838)",
+    "UNKNOWN (839)",
+    "UNKNOWN (840)",
+    "UNKNOWN (841)",
+    "UNKNOWN (842)",
+    "UNKNOWN (843)",
+    "UNKNOWN (844)",
+    "UNKNOWN (845)",
+    "UNKNOWN (846)",
+    "UNKNOWN (847)",
+    "UNKNOWN (848)",
+    "UNKNOWN (849)",
+    "UNKNOWN (850)",
+    "UNKNOWN (851)",
+    "UNKNOWN (852)",
+    "UNKNOWN (853)",
+    "UNKNOWN (854)",
+    "UNKNOWN (855)",
+    "WM_HANDHELDFIRST",
+    "UNKNOWN (857)",
+    "UNKNOWN (858)",
+    "UNKNOWN (859)",
+    "UNKNOWN (860)",
+    "UNKNOWN (861)",
+    "UNKNOWN (862)",
+    "WM_HANDHELDLAST",
+    "WM_AFXFIRST",
+    "UNKNOWN (865)",
+    "UNKNOWN (866)",
+    "UNKNOWN (867)",
+    "UNKNOWN (868)",
+    "UNKNOWN (869)",
+    "UNKNOWN (870)",
+    "UNKNOWN (871)",
+    "UNKNOWN (872)",
+    "UNKNOWN (873)",
+    "UNKNOWN (874)",
+    "UNKNOWN (875)",
+    "UNKNOWN (876)",
+    "UNKNOWN (877)",
+    "UNKNOWN (878)",
+    "UNKNOWN (879)",
+    "UNKNOWN (880)",
+    "UNKNOWN (881)",
+    "UNKNOWN (882)",
+    "UNKNOWN (883)",
+    "UNKNOWN (884)",
+    "UNKNOWN (885)",
+    "UNKNOWN (886)",
+    "UNKNOWN (887)",
+    "UNKNOWN (888)",
+    "UNKNOWN (889)",
+    "UNKNOWN (890)",
+    "UNKNOWN (891)",
+    "UNKNOWN (892)",
+    "UNKNOWN (893)",
+    "UNKNOWN (894)",
+    "WM_AFXLAST",
+    "WM_PENWINFIRST",
+    "UNKNOWN (897)",
+    "UNKNOWN (898)",
+    "UNKNOWN (899)",
+    "UNKNOWN (900)",
+    "UNKNOWN (901)",
+    "UNKNOWN (902)",
+    "UNKNOWN (903)",
+    "UNKNOWN (904)",
+    "UNKNOWN (905)",
+    "UNKNOWN (906)",
+    "UNKNOWN (907)",
+    "UNKNOWN (908)",
+    "UNKNOWN (909)",
+    "UNKNOWN (910)",
+    "WM_PENWINLAST",
+    "UNKNOWN (912)",
+    "UNKNOWN (913)",
+    "UNKNOWN (914)",
+    "UNKNOWN (915)",
+    "UNKNOWN (916)",
+    "UNKNOWN (917)",
+    "UNKNOWN (918)",
+    "UNKNOWN (919)",
+    "UNKNOWN (920)",
+    "UNKNOWN (921)",
+    "UNKNOWN (922)",
+    "UNKNOWN (923)",
+    "UNKNOWN (924)",
+    "UNKNOWN (925)",
+    "UNKNOWN (926)",
+    "UNKNOWN (927)",
+    "UNKNOWN (928)",
+    "UNKNOWN (929)",
+    "UNKNOWN (930)",
+    "UNKNOWN (931)",
+    "UNKNOWN (932)",
+    "UNKNOWN (933)",
+    "UNKNOWN (934)",
+    "UNKNOWN (935)",
+    "UNKNOWN (936)",
+    "UNKNOWN (937)",
+    "UNKNOWN (938)",
+    "UNKNOWN (939)",
+    "UNKNOWN (940)",
+    "UNKNOWN (941)",
+    "UNKNOWN (942)",
+    "UNKNOWN (943)",
+    "UNKNOWN (944)",
+    "UNKNOWN (945)",
+    "UNKNOWN (946)",
+    "UNKNOWN (947)",
+    "UNKNOWN (948)",
+    "UNKNOWN (949)",
+    "UNKNOWN (950)",
+    "UNKNOWN (951)",
+    "UNKNOWN (952)",
+    "UNKNOWN (953)",
+    "UNKNOWN (954)",
+    "UNKNOWN (955)",
+    "UNKNOWN (956)",
+    "UNKNOWN (957)",
+    "UNKNOWN (958)",
+    "UNKNOWN (959)",
+    "UNKNOWN (960)",
+    "UNKNOWN (961)",
+    "UNKNOWN (962)",
+    "UNKNOWN (963)",
+    "UNKNOWN (964)",
+    "UNKNOWN (965)",
+    "UNKNOWN (966)",
+    "UNKNOWN (967)",
+    "UNKNOWN (968)",
+    "UNKNOWN (969)",
+    "UNKNOWN (970)",
+    "UNKNOWN (971)",
+    "UNKNOWN (972)",
+    "UNKNOWN (973)",
+    "UNKNOWN (974)",
+    "UNKNOWN (975)",
+    "UNKNOWN (976)",
+    "UNKNOWN (977)",
+    "UNKNOWN (978)",
+    "UNKNOWN (979)",
+    "UNKNOWN (980)",
+    "UNKNOWN (981)",
+    "UNKNOWN (982)",
+    "UNKNOWN (983)",
+    "UNKNOWN (984)",
+    "UNKNOWN (985)",
+    "UNKNOWN (986)",
+    "UNKNOWN (987)",
+    "UNKNOWN (988)",
+    "UNKNOWN (989)",
+    "UNKNOWN (990)",
+    "UNKNOWN (991)",
+    "UNKNOWN (992)",
+    "UNKNOWN (993)",
+    "UNKNOWN (994)",
+    "UNKNOWN (995)",
+    "UNKNOWN (996)",
+    "UNKNOWN (997)",
+    "UNKNOWN (998)",
+    "UNKNOWN (999)",
+    "UNKNOWN (1000)",
+    "UNKNOWN (1001)",
+    "UNKNOWN (1002)",
+    "UNKNOWN (1003)",
+    "UNKNOWN (1004)",
+    "UNKNOWN (1005)",
+    "UNKNOWN (1006)",
+    "UNKNOWN (1007)",
+    "UNKNOWN (1008)",
+    "UNKNOWN (1009)",
+    "UNKNOWN (1010)",
+    "UNKNOWN (1011)",
+    "UNKNOWN (1012)",
+    "UNKNOWN (1013)",
+    "UNKNOWN (1014)",
+    "UNKNOWN (1015)",
+    "UNKNOWN (1016)",
+    "UNKNOWN (1017)",
+    "UNKNOWN (1018)",
+    "UNKNOWN (1019)",
+    "UNKNOWN (1020)",
+    "UNKNOWN (1021)",
+    "UNKNOWN (1022)",
+    "UNKNOWN (1023)",
+    "WM_USER"
+};
+
+/* vi: set ts=4 sw=4 expandtab: */
--- a/test/graywin.c	Thu Jul 06 05:53:32 2006 +0000
+++ b/test/graywin.c	Thu Jul 06 07:17:11 2006 +0000
@@ -228,8 +228,11 @@
             DrawBackground(screen);
             break;
         case SDL_VIDEORESIZE:
-            screen = CreateScreen(event.resize.w, event.resize.h,
-                                  screen->format->BitsPerPixel, videoflags);
+            printf("Screen resized to %dx%d\n", event.resize.w,
+                   event.resize.h);
+            screen =
+                CreateScreen(event.resize.w, event.resize.h,
+                             screen->format->BitsPerPixel, videoflags);
             if (screen == NULL) {
                 fprintf(stderr, "Couldn't resize video mode\n");
                 done = 1;
--- a/test/testsprite2.c	Thu Jul 06 05:53:32 2006 +0000
+++ b/test/testsprite2.c	Thu Jul 06 07:17:11 2006 +0000
@@ -5,11 +5,12 @@
 
 #include "SDL.h"
 
-#define NUM_WINDOWS 2
+#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 int num_sprites;
@@ -85,8 +86,6 @@
 
     SDL_SelectRenderer(window);
 
-    SDL_RenderFill(NULL, 0);
-
     /* Query the sizes */
     SDL_GetWindowSize(window, &window_w, &window_h);
 
@@ -94,6 +93,10 @@
     n = 0;
     for (i = 0; i < num_sprites; ++i) {
         position = &positions[i];
+        SDL_RenderFill(position, BACKGROUND);
+    }
+    for (i = 0; i < num_sprites; ++i) {
+        position = &positions[i];
         velocity = &velocities[i];
         position->x += velocity->x;
         if ((position->x < 0) || (position->x >= (window_w - sprite_w))) {
@@ -168,7 +171,8 @@
 
         SDL_snprintf(title, sizeof(title), "testsprite %d", i + 1);
         windows[i] =
-            SDL_CreateWindow(title, -1, -1, window_w, window_h,
+            SDL_CreateWindow(title, SDL_WINDOWPOS_UNDEFINED,
+                             SDL_WINDOWPOS_UNDEFINED, window_w, window_h,
                              SDL_WINDOW_SHOWN);
         if (!windows[i]) {
             fprintf(stderr, "Couldn't create window: %s\n", SDL_GetError());
@@ -179,6 +183,7 @@
             fprintf(stderr, "Couldn't create renderer: %s\n", SDL_GetError());
             quit(2);
         }
+        SDL_RenderFill(NULL, BACKGROUND);
     }
     if (LoadSprite("icon.bmp") < 0) {
         quit(2);
@@ -214,6 +219,17 @@
         ++frames;
         while (SDL_PollEvent(&event)) {
             switch (event.type) {
+            case SDL_WINDOWEVENT:
+                switch (event.window.event) {
+                case SDL_WINDOWEVENT_EXPOSED:
+                    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:
--- a/test/testwm.c	Thu Jul 06 05:53:32 2006 +0000
+++ b/test/testwm.c	Thu Jul 06 07:17:11 2006 +0000
@@ -176,7 +176,7 @@
 }
 
 int SDLCALL
-FilterEvents(SDL_Event * event)
+FilterEvents(void *userdata, SDL_Event * event)
 {
     static int reallyquit = 0;
 
@@ -344,7 +344,7 @@
     }
 
     /* Set an event filter that discards everything but QUIT */
-    SDL_SetEventFilter(FilterEvents);
+    SDL_SetEventFilter(FilterEvents, NULL);
 
     /* Ignore key up events, they don't even get filtered */
     SDL_EventState(SDL_KEYUP, SDL_IGNORE);
--- a/test/threadwin.c	Thu Jul 06 05:53:32 2006 +0000
+++ b/test/threadwin.c	Thu Jul 06 07:17:11 2006 +0000
@@ -80,7 +80,7 @@
 }
 
 int SDLCALL
-FilterEvents(SDL_Event * event)
+FilterEvents(void *userdata, SDL_Event * event)
 {
     static int reallyquit = 0;
 
@@ -296,7 +296,7 @@
     SDL_EnableUNICODE(1);
 
     /* Set an event filter that discards everything but QUIT */
-    SDL_SetEventFilter(FilterEvents);
+    SDL_SetEventFilter(FilterEvents, NULL);
 
     /* Create the event handling threads */
     mouse_thread = SDL_CreateThread(HandleMouse, NULL);