changeset 1670:eef792d31de8 SDL-1.3

Work in progress. :)
author Sam Lantinga <slouken@libsdl.org>
date Wed, 07 Jun 2006 16:10:28 +0000
parents 9857d21967bb
children 89f7510fe17a
files Makefile.in include/SDL_compat.h include/SDL_mouse.h include/SDL_video.h src/SDL_compat.c src/events/SDL_events_c.h src/events/SDL_keyboard.c src/events/SDL_mouse.c src/events/SDL_mouse_c.h src/events/SDL_quit.c src/video/SDL_blit.c src/video/SDL_bmp.c src/video/SDL_cursor.c src/video/SDL_cursor_c.h src/video/SDL_pixels.c src/video/SDL_pixels_c.h src/video/SDL_surface.c src/video/SDL_sysvideo.h src/video/SDL_video.c
diffstat 19 files changed, 2426 insertions(+), 1668 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile.in	Mon May 29 05:08:33 2006 +0000
+++ b/Makefile.in	Wed Jun 07 16:10:28 2006 +0000
@@ -125,14 +125,6 @@
 	    rm -f $(mandir)/man3/$$file; \
 	done
 
-indent:
-	cd $(srcdir) && \
-	find . \( \
-	    -name '*.h' -o \
-	    -name '*.c' -o \
-	    -name '*.cc' \) \
-	    -exec indent {} \;
-
 clean:
 	rm -rf $(objects)
 	if test -f test/Makefile; then (cd test; $(MAKE) $@); fi
@@ -173,6 +165,29 @@
 rpm: $(distfile)
 	rpmbuild -ta $?
 
+# Run indent on the source to standardize coding style
+indent:
+	@echo "Running indent... modified files:"
+	@cd $(srcdir) && \
+	find . \( \
+	    -name '*.h' -o \
+	    -name '*.c' -o \
+	    -name '*.cc' \) \
+	    -print | \
+	while read file; do \
+	    indent "$$file" -o "$$file.indent"; \
+	    if cmp "$$file" "$$file.indent" >/dev/null; then \
+	        rm -f "$$file.indent"; \
+	    else \
+	        echo "$$file"; \
+	        mv -f "$$file.indent" "$$file"; \
+	    fi; \
+	done
+
+# Run indent and then commit modified files
+commit: indent
+	svn commit
+
 # Create a SVN snapshot that people can run update on
 snapshot:
 	svn co svn://libsdl.org/trunk/SDL
--- a/include/SDL_compat.h	Mon May 29 05:08:33 2006 +0000
+++ b/include/SDL_compat.h	Wed Jun 07 16:10:28 2006 +0000
@@ -36,22 +36,18 @@
 /* *INDENT-ON* */
 #endif
 
-#define SDL_SWSURFACE	0x00000000
-#define SDL_HWSURFACE	0x00000001
-#define SDL_ASYNCBLIT	0x00000004
-#define SDL_ANYFORMAT	0x10000000
-#define SDL_HWPALETTE	0x20000000
-#define SDL_DOUBLEBUF	0x40000000
-#define SDL_FULLSCREEN	0x80000000
-#define SDL_OPENGL      0x00000002
-#define SDL_INTERNALOPENGL 0x00000008
-#define SDL_RESIZABLE	0x00000010
-#define SDL_NOFRAME	0x00000020
-#define SDL_HWACCEL	0x00000100
-#define SDL_SRCCOLORKEY	0x00001000
-#define SDL_RLEACCELOK	0x00002000
-#define SDL_RLEACCEL	0x00004000
-#define SDL_SRCALPHA	0x00010000
+#define SDL_SWSURFACE       0x00000000
+#define SDL_ANYFORMAT       0x00100000
+#define SDL_HWPALETTE       0x00200000
+#define SDL_DOUBLEBUF       0x00400000
+#define SDL_FULLSCREEN      0x00800000
+#define SDL_RESIZABLE       0x01000000
+#define SDL_NOFRAME         0x02000000
+#define SDL_OPENGL          0x04000000
+#define SDL_ASYNCBLIT       0x00000000
+#define SDL_HWACCEL         0x00000000
+#define SDL_SCREEN_SURFACE  0x10000000  /* Surface is a window screen surface */
+#define SDL_SHADOW_SURFACE  0x20000000  /* Surface is a window shadow surface */
 
 #define SDL_APPMOUSEFOCUS	0x01
 #define SDL_APPINPUTFOCUS	0x02
@@ -64,6 +60,25 @@
 #define SDL_VIDEORESIZE	SDL_EVENT_RESERVED2
 #define SDL_VIDEOEXPOSE	SDL_EVENT_RESERVED3
 
+typedef struct SDL_VideoInfo
+{
+    Uint32 hw_available:1;
+    Uint32 wm_available:1;
+    Uint32 UnusedBits1:6;
+    Uint32 UnusedBits2:1;
+    Uint32 blit_hw:1;
+    Uint32 blit_hw_CC:1;
+    Uint32 blit_hw_A:1;
+    Uint32 blit_sw:1;
+    Uint32 blit_sw_CC:1;
+    Uint32 blit_sw_A:1;
+    Uint32 blit_fill:1;
+    Uint32 UnusedBits3:16;
+    Uint32 video_mem;
+
+    SDL_PixelFormat *vfmt;
+} SDL_VideoInfo;
+
 typedef enum
 {
     SDL_GRAB_QUERY = -1,
@@ -71,9 +86,12 @@
     SDL_GRAB_ON = 1
 } SDL_GrabMode;
 
+#define SDL_AllocSurface    SDL_CreateRGBSurface
+
 extern DECLSPEC const SDL_version *SDLCALL SDL_Linked_Version(void);
 extern DECLSPEC char *SDLCALL SDL_AudioDriverName(char *namebuf, int maxlen);
 extern DECLSPEC char *SDLCALL SDL_VideoDriverName(char *namebuf, int maxlen);
+extern DECLSPEC const SDL_VideoInfo *SDLCALL SDL_GetVideoInfo(void);
 extern DECLSPEC int SDLCALL SDL_VideoModeOK(int width, int height, int bpp,
                                             Uint32 flags);
 extern DECLSPEC SDL_Rect **SDLCALL SDL_ListModes(SDL_PixelFormat * format,
@@ -81,6 +99,14 @@
 extern DECLSPEC SDL_Surface *SDLCALL SDL_SetVideoMode(int width, int height,
                                                       int bpp, Uint32 flags);
 extern DECLSPEC SDL_Surface *SDLCALL SDL_GetVideoSurface(void);
+extern DECLSPEC void SDLCALL SDL_UpdateRects(SDL_Surface * screen,
+                                             int numrects, SDL_Rect * rects);
+extern DECLSPEC void SDLCALL SDL_UpdateRect(SDL_Surface * screen, Sint32 x,
+                                            Sint32 y, Uint32 w, Uint32 h);
+extern DECLSPEC int SDLCALL SDL_Flip(SDL_Surface * screen);
+extern DECLSPEC SDL_Surface *SDLCALL SDL_DisplayFormat(SDL_Surface * surface);
+extern DECLSPEC SDL_Surface *SDLCALL SDL_DisplayFormatAlpha(SDL_Surface *
+                                                            surface);
 extern DECLSPEC void SDLCALL SDL_WM_SetCaption(const char *title,
                                                const char *icon);
 extern DECLSPEC void SDLCALL SDL_WM_GetCaption(char **title, char **icon);
@@ -92,6 +118,9 @@
 extern DECLSPEC int SDLCALL SDL_SetPalette(SDL_Surface * surface, int flags,
                                            SDL_Color * colors,
                                            int firstcolor, int ncolors);
+extern DECLSPEC int SDLCALL SDL_SetScreenColors(SDL_Surface * screen,
+                                                SDL_Color * colors,
+                                                int firstcolor, int ncolors);
 extern DECLSPEC int SDLCALL SDL_GetWMInfo(SDL_SysWMinfo * info);
 
 /* Ends C function definitions when using C++ */
@@ -103,3 +132,6 @@
 #include "close_code.h"
 
 #endif /* _SDL_compat_h */
+
+/* vi: set ts=4 sw=4 expandtab: */
+extern DECLSPEC void SDLCALL SDL_WarpMouse(Uint16 x, Uint16 y);
--- a/include/SDL_mouse.h	Mon May 29 05:08:33 2006 +0000
+++ b/include/SDL_mouse.h	Wed Jun 07 16:10:28 2006 +0000
@@ -41,28 +41,53 @@
 /* *INDENT-ON* */
 #endif
 
-typedef struct WMcursor WMcursor;       /* Implementation dependent */
-typedef struct SDL_Cursor
-{
-    SDL_Rect area;              /* The area of the mouse cursor */
-    Sint16 hot_x, hot_y;        /* The "tip" of the cursor */
-    Uint8 *data;                /* B/W cursor data */
-    Uint8 *mask;                /* B/W cursor mask */
-    Uint8 *save[2];             /* Place to save cursor area */
-    WMcursor *wm_cursor;        /* Window-manager cursor */
-} SDL_Cursor;
+typedef struct SDL_Cursor SDL_Cursor;   /* Implementation dependent */
 
 /* Function prototypes */
+
+/* \fn int SDL_GetNumMice(void)
+ *
+ * \brief Get the number of mouse input devices available.
+ *
+ * \sa SDL_SelectMouse()
+ */
+extern DECLSPEC int SDLCALL SDL_GetNumMice(void);
+
+/* \fn int SDL_SelectMouse(int index)
+ *
+ * \brief Set the index of the currently selected mouse.
+ *
+ * \return The index of the currently selected mouse.
+ *
+ * \note You can query the currently selected mouse by passing an index of -1.
+ *
+ * \sa SDL_GetNumMice()
+ */
+extern DECLSPEC int SDLCALL SDL_SelectMouse(int index);
+
+/* \fn SDL_WindowID SDL_GetMouseFocusWindow(void)
+ *
+ * \brief Get the window which currently has focus for the currently selected mouse.
+ */
+extern DECLSPEC SDL_WindowID SDLCALL SDL_GetMouseFocusWindow(void);
+
 /*
- * Retrieve the current state of the mouse.
+ * \fn Uint8 SDL_GetMouseState(int *x, int *y)
+ *
+ * \brief Retrieve the current state of the mouse.
+ *
  * The current button state is returned as a button bitmask, which can
  * be tested using the SDL_BUTTON(X) macros, and x and y are set to the
- * current mouse cursor position.  You can pass NULL for either x or y.
+ * mouse cursor position relative to the focus window for the currently
+ * selected mouse.  You can pass NULL for either x or y.
  */
 extern DECLSPEC Uint8 SDLCALL SDL_GetMouseState(int *x, int *y);
 
 /*
- * Retrieve the current state of the mouse.
+ * \fn Uint8 SDL_GetRelativeMouseState(int *x, int *y)
+ *
+ * \brief Retrieve the current state of the mouse.
+ *
  * The current button state is returned as a button bitmask, which can
  * be tested using the SDL_BUTTON(X) macros, and x and y are set to the
  * mouse deltas since the last call to SDL_GetRelativeMouseState().
@@ -70,9 +95,18 @@
 extern DECLSPEC Uint8 SDLCALL SDL_GetRelativeMouseState(int *x, int *y);
 
 /*
- * Set the position of the mouse cursor (generates a mouse motion event)
+ * \fn void SDL_WarpMouseInWindow(SDL_WindowID windowID, int x, int y)
+ *
+ * \brief Moves the currently selected mouse to the given position within the window.
+ *
+ * \param windowID The window to move the mouse into, or 0 for the current mouse focus
+ * \param x The x coordinate within the window
+ * \param y The y coordinate within the window
+ *
+ * \note This function generates a mouse motion event
  */
-extern DECLSPEC void SDLCALL SDL_WarpMouse(Uint16 x, Uint16 y);
+extern DECLSPEC void SDLCALL SDL_WarpMouseInWindow(SDL_WindowID windowID,
+                                                   int x, int y);
 
 /*
  * Create a cursor using the specified data and mask (in MSB format).
--- a/include/SDL_video.h	Mon May 29 05:08:33 2006 +0000
+++ b/include/SDL_video.h	Wed Jun 07 16:10:28 2006 +0000
@@ -46,111 +46,17 @@
 #define SDL_ALPHA_OPAQUE 255
 #define SDL_ALPHA_TRANSPARENT 0
 
-/* Useful data types */
+/**
+ * \struct SDL_Rect
+ *
+ * \brief A rectangle, with the origin at the upper left.
+ */
 typedef struct SDL_Rect
 {
     Sint16 x, y;
     Uint16 w, h;
 } SDL_Rect;
 
-/* This structure should be treated as read-only, except for 'pixels',
-   which, if not NULL, contains the raw pixel data for the surface.
-*/
-typedef struct SDL_Surface
-{
-    Uint32 flags;               /* Read-only */
-    SDL_PixelFormat *format;    /* Read-only */
-    int w, h;                   /* Read-only */
-    Uint16 pitch;               /* Read-only */
-    void *pixels;               /* Read-write */
-    int offset;                 /* Private */
-
-    /* Hardware-specific surface info */
-    struct private_hwdata *hwdata;
-
-    /* clipping information */
-    SDL_Rect clip_rect;         /* Read-only */
-    Uint32 unused1;             /* for binary compatibility */
-
-    /* Allow recursive locks */
-    Uint32 locked;              /* Private */
-
-    /* info for fast blit mapping to other surfaces */
-    struct SDL_BlitMap *map;    /* Private */
-
-    /* format version, bumped at every change to invalidate blit maps */
-    unsigned int format_version;        /* Private */
-
-    /* Reference count -- used when freeing surface */
-    int refcount;               /* Read-mostly */
-} SDL_Surface;
-
-/* The most common video overlay formats.
-   For an explanation of these pixel formats, see:
-	http://www.webartz.com/fourcc/indexyuv.htm
-
-   For information on the relationship between color spaces, see:
-   http://www.neuro.sfc.keio.ac.jp/~aly/polygon/info/color-space-faq.html
- */
-#define SDL_YV12_OVERLAY  0x32315659    /* Planar mode: Y + V + U  (3 planes) */
-#define SDL_IYUV_OVERLAY  0x56555949    /* Planar mode: Y + U + V  (3 planes) */
-#define SDL_YUY2_OVERLAY  0x32595559    /* Packed mode: Y0+U0+Y1+V0 (1 plane) */
-#define SDL_UYVY_OVERLAY  0x59565955    /* Packed mode: U0+Y0+V0+Y1 (1 plane) */
-#define SDL_YVYU_OVERLAY  0x55595659    /* Packed mode: Y0+V0+Y1+U0 (1 plane) */
-
-/* The YUV hardware video overlay */
-typedef struct SDL_Overlay
-{
-    Uint32 format;              /* Read-only */
-    int w, h;                   /* Read-only */
-    int planes;                 /* Read-only */
-    Uint16 *pitches;            /* Read-only */
-    Uint8 **pixels;             /* Read-write */
-
-    /* Hardware-specific surface info */
-    struct private_yuvhwfuncs *hwfuncs;
-    struct private_yuvhwdata *hwdata;
-
-    /* Special flags */
-    Uint32 hw_overlay:1;        /* Flag: This overlay hardware accelerated? */
-    Uint32 UnusedBits:31;
-} SDL_Overlay;
-
-/* Evaluates to true if the surface needs to be locked before access */
-#define SDL_MUSTLOCK(surface)	\
-  (surface->offset ||		\
-  ((surface->flags & (SDL_HWSURFACE|SDL_RLEACCEL)) != 0))
-
-/* typedef for private surface blitting functions */
-typedef int (*SDL_blit) (struct SDL_Surface * src, SDL_Rect * srcrect,
-                         struct SDL_Surface * dst, SDL_Rect * dstrect);
-
-
-/**
- * \struct SDL_VideoInfo
- *
- * \brief Useful for determining the video hardware capabilities
- */
-typedef struct SDL_VideoInfo
-{
-    Uint32 hw_available:1;  /**< Flag: Can you create hardware surfaces? */
-    Uint32 wm_available:1;  /**< Flag: Can you talk to a window manager? */
-    Uint32 UnusedBits1:6;
-    Uint32 UnusedBits2:1;
-    Uint32 blit_hw:1;       /**< Flag: Accelerated blits HW --> HW */
-    Uint32 blit_hw_CC:1;    /**< Flag: Accelerated blits with Colorkey */
-    Uint32 blit_hw_A:1;     /**< Flag: Accelerated blits with Alpha */
-    Uint32 blit_sw:1;       /**< Flag: Accelerated blits SW --> HW */
-    Uint32 blit_sw_CC:1;    /**< Flag: Accelerated blits with Colorkey */
-    Uint32 blit_sw_A:1;     /**< Flag: Accelerated blits with Alpha */
-    Uint32 blit_fill:1;     /**< Flag: Accelerated color fill */
-    Uint32 UnusedBits3:16;
-    Uint32 video_mem;           /* The total amount of video memory (in K) */
-
-    /* Here for backwards compatibility */
-    SDL_PixelFormat *vfmt;
-} SDL_VideoInfo;
-
 /**
  * \struct SDL_DisplayMode
  *
@@ -204,6 +110,8 @@
  * \enum SDL_WindowFlags
  *
  * \brief The flags on a window
+ *
+ * \sa SDL_GetWindowFlags()
  */
 typedef enum
 {
@@ -241,6 +149,163 @@
 } SDL_WindowEventID;
 
 /**
+ * \enum SDL_RendererFlags
+ *
+ * \brief Flags used when initializing a render manager.
+ */
+typedef enum
+{
+    SDL_Renderer_PresentDiscard = 0x00000001,   /**< Present leaves the contents of the backbuffer undefined */
+    SDL_Renderer_PresentCopy = 0x00000002,      /**< Present uses a copy from back buffer to the front buffer */
+    SDL_Renderer_PresentFlip2 = 0x00000004,     /**< Present uses a flip, swapping back buffer and front buffer */
+    SDL_Renderer_PresentFlip3 = 0x00000008,     /**< Present uses a flip, rotating between two back buffers and a front buffer */
+    SDL_Renderer_PresentVSync = 0x00000010,     /**< Present is synchronized with the refresh rate */
+    SDL_Renderer_RenderTarget = 0x00000020,     /**< The renderer can create texture render targets */
+    SDL_Renderer_Accelerated = 0x00000040,      /**< The renderer uses hardware acceleration */
+    SDL_Renderer_Minimal = 0x00000080,          /**< The renderer only supports the read/write pixel and present functions */
+} SDL_RendererFlags;
+
+/**
+ * \struct SDL_RendererInfo
+ *
+ * \brief Information on the capabilities of a render manager.
+ */
+typedef struct SDL_RendererInfo
+{
+    const char *name;           /**< The name of the renderer */
+    Uint32 flags;               /**< Supported SDL_RendererFlags */
+    Uint32 blend_modes;         /**< A mask of supported blend modes */
+    Uint32 scale_modes;         /**< A mask of supported scale modes */
+    Uint32 num_texture_formats; /**< The number of available texture formats */
+    Uint32 texture_formats[32]; /**< The available texture formats */
+    int max_texture_width;      /**< The maximimum texture width */
+    int max_texture_height;     /**< The maximimum texture height */
+} SDL_RendererInfo;
+
+/**
+ * \enum SDL_TextureAccess
+ *
+ * \brief The access pattern allowed for a texture
+ */
+typedef enum
+{
+    SDL_TextureAccess_Render,   /**< Unlockable video memory, rendering allowed */
+    SDL_TextureAccess_Remote,   /**< Unlockable video memory */
+    SDL_TextureAccess_Local,    /**< Lockable system memory */
+} SDL_TextureAccess;
+
+/**
+ * \enum SDL_TextureBlendMode
+ *
+ * \brief The blend mode used in SDL_RenderCopy()
+ */
+typedef enum
+{
+    SDL_TextureBlendMode_None,  /**< No blending */
+    SDL_TextureBlendMode_Mask,  /**< dst = A ? src : dst (alpha is mask) */
+    SDL_TextureBlendMode_Blend, /**< dst = (src * A) + (dst * (1-A)) */
+    SDL_TextureBlendMode_Add,   /**< dst = (src * A) + dst */
+    SDL_TextureBlendMode_Mod,   /**< dst = src * dst */
+} SDL_TextureBlendMode;
+
+/**
+ * \enum SDL_TextureScaleMode
+ *
+ * \brief The scale mode used in SDL_RenderCopy()
+ */
+typedef enum
+{
+    SDL_TextureScaleMode_None,  /**< No scaling, rectangles must match dimensions */
+    SDL_TextureScaleMode_Fast,  /**< Point sampling or equivalent algorithm */
+    SDL_TextureScaleMode_Slow,  /**< Linear filtering or equivalent algorithm */
+    SDL_TextureScaleMode_Best,  /**< Bicubic filtering or equivalent algorithm */
+} SDL_TextureScaleMode;
+
+/**
+ * \typedef SDL_TextureID
+ *
+ * \brief An efficient driver-specific representation of pixel data
+ */
+typedef Uint32 SDL_TextureID;
+
+
+/* These are the currently supported flags for the SDL_surface */
+/* Used internally (read-only) */
+#define SDL_HWSURFACE       0x00000001  /* Surface represents a texture */
+#define SDL_PREALLOC        0x00000002  /* Surface uses preallocated memory */
+#define SDL_SRCALPHA        0x00000004  /* Blit uses source alpha blending */
+#define SDL_SRCCOLORKEY     0x00000008  /* Blit uses a source color key */
+#define SDL_RLEACCELOK      0x00000010  /* Private flag */
+#define SDL_RLEACCEL        0x00000020  /* Surface is RLE encoded */
+
+/* Evaluates to true if the surface needs to be locked before access */
+#define SDL_MUSTLOCK(S)	(((S)->flags & (SDL_HWSURFACE|SDL_RLEACCEL)) != 0)
+
+/* This structure should be treated as read-only, except for 'pixels',
+   which, if not NULL, contains the raw pixel data for the surface.
+*/
+typedef struct SDL_Surface
+{
+    Uint32 flags;               /* Read-only */
+    SDL_PixelFormat *format;    /* Read-only */
+    int w, h;                   /* Read-only */
+    int pitch;                  /* Read-only */
+    void *pixels;               /* Read-write */
+
+    /* information needed for surfaces requiring locks */
+    int locked;
+    void *lock_data;
+
+    /* clipping information */
+    SDL_Rect clip_rect;         /* Read-only */
+
+    /* info for fast blit mapping to other surfaces */
+    struct SDL_BlitMap *map;    /* Private */
+
+    /* format version, bumped at every change to invalidate blit maps */
+    unsigned int format_version;        /* Private */
+
+    /* Reference count -- used when freeing surface */
+    int refcount;               /* Read-mostly */
+} SDL_Surface;
+
+/* typedef for private surface blitting functions */
+typedef int (*SDL_blit) (struct SDL_Surface * src, SDL_Rect * srcrect,
+                         struct SDL_Surface * dst, SDL_Rect * dstrect);
+
+
+/* The most common video overlay formats.
+   For an explanation of these pixel formats, see:
+   http://www.webartz.com/fourcc/indexyuv.htm
+
+   For information on the relationship between color spaces, see:
+   http://www.neuro.sfc.keio.ac.jp/~aly/polygon/info/color-space-faq.html
+ */
+#define SDL_YV12_OVERLAY  0x32315659    /* Planar mode: Y + V + U  (3 planes) */
+#define SDL_IYUV_OVERLAY  0x56555949    /* Planar mode: Y + U + V  (3 planes) */
+#define SDL_YUY2_OVERLAY  0x32595559    /* Packed mode: Y0+U0+Y1+V0 (1 plane) */
+#define SDL_UYVY_OVERLAY  0x59565955    /* Packed mode: U0+Y0+V0+Y1 (1 plane) */
+#define SDL_YVYU_OVERLAY  0x55595659    /* Packed mode: Y0+V0+Y1+U0 (1 plane) */
+
+/* The YUV hardware video overlay */
+typedef struct SDL_Overlay
+{
+    Uint32 format;              /* Read-only */
+    int w, h;                   /* Read-only */
+    int planes;                 /* Read-only */
+    Uint16 *pitches;            /* Read-only */
+    Uint8 **pixels;             /* Read-write */
+
+    /* Hardware-specific surface info */
+    struct private_yuvhwfuncs *hwfuncs;
+    struct private_yuvhwdata *hwdata;
+
+    /* Special flags */
+    Uint32 hw_overlay:1;        /* Flag: This overlay hardware accelerated? */
+    Uint32 UnusedBits:31;
+} SDL_Overlay;
+
+/**
  * \enum SDL_GLattr
  *
  * \brief OpenGL configuration attributes
@@ -266,22 +331,6 @@
     SDL_GL_SWAP_CONTROL
 } SDL_GLattr;
 
-/* These are the currently supported flags for the SDL_surface */
-#define SDL_SWSURFACE	0x00000000      /* Surface is in system memory */
-#define SDL_HWSURFACE	0x00000001      /* Surface is in video memory */
-/* Available for SDL_CreateWindowSurface() */
-#define SDL_ANYFORMAT	0x10000000      /* Allow any video depth/pixel-format */
-#define SDL_HWPALETTE	0x20000000      /* Surface has exclusive palette */
-#define SDL_DOUBLEBUF	0x40000000      /* Set up double-buffered surface */
-/* Used internally (read-only) */
-#define SDL_HWACCEL	0x00000100      /* Blit uses hardware acceleration */
-#define SDL_SRCCOLORKEY	0x00001000      /* Blit uses a source color key */
-#define SDL_RLEACCELOK	0x00002000      /* Private flag */
-#define SDL_RLEACCEL	0x00004000      /* Surface is RLE encoded */
-#define SDL_SRCALPHA	0x00010000      /* Blit uses source alpha blending */
-#define SDL_PREALLOC	0x00100000      /* Surface uses preallocated memory */
-#define SDL_SCREEN_SURFACE 0x01000000   /* Surface is a window screen surface */
-#define SDL_SHADOW_SURFACE 0x02000000   /* Surface is a window shadow surface */
 
 /* Function prototypes */
 
@@ -350,16 +399,6 @@
 extern DECLSPEC const char *SDLCALL SDL_GetCurrentVideoDriver(void);
 
 /**
- * \fn const SDL_VideoInfo *SDL_GetVideoInfo(void)
- *
- * \brief Returns information about the currently initialized video driver.
- *
- * \return A read-only pointer to information about the video hardware,
- *         or NULL if no video driver has been initialized.
- */
-extern DECLSPEC const SDL_VideoInfo *SDLCALL SDL_GetVideoInfo(void);
-
-/**
  * \fn int SDL_GetNumVideoDisplays(void)
  *
  * \brief Returns the number of available video displays.
@@ -373,6 +412,8 @@
  *
  * \brief Set the index of the currently selected display.
  *
+ * \return The index of the currently selected display.
+ *
  * \note You can query the currently selected display by passing an index of -1.
  *
  * \sa SDL_GetNumVideoDisplays()
@@ -452,6 +493,16 @@
 extern DECLSPEC int SDLCALL SDL_SetDisplayMode(const SDL_DisplayMode * mode);
 
 /**
+ * \fn int SDL_SetDisplayColormap(SDL_Color *colors, int firstcolor, int ncolors)
+ *
+ * \brief Set the colormap for indexed display modes.
+ *
+ * \return 0 on success, or -1 if not all the colors could be set.
+ */
+extern DECLSPEC int SDLCALL SDL_SetDisplayColors(SDL_Color * colors,
+                                                 int firstcolor, int ncolors);
+
+/**
  * \fn SDL_WindowID SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags)
  *
  * \brief Create a window with the specified position, dimensions, and flags.
@@ -673,37 +724,294 @@
 extern DECLSPEC void SDLCALL SDL_DestroyWindow(SDL_WindowID windowID);
 
 /**
- * \fn SDL_Surface *SDL_CreateWindowSurface (SDL_WindowID windowID, Uint32 format, Uint32 flags)
+ * \fn int SDL_GetNumRenderers(void)
+ *
+ * \brief Get the number of render managers on the current display.
+ *
+ * A render manager is a set of code that handles rendering and texture
+ * management on a particular display.  Normally there is only one, but
+ * some drivers may have several available with different capabilities.
+ *
+ * \sa SDL_GetRendererInfo()
+ * \sa SDL_CreateRenderer()
+ */
+extern DECLSPEC int SDLCALL SDL_GetNumRenderers(void);
+
+/**
+ * \fn SDL_RendererInfo *SDL_GetRendererInfo(int index)
+ *
+ * \brief Get information about a specific render manager on the current
+ *        display.
+ *
+ * \sa SDL_CreateRenderer()
+ */
+extern DECLSPEC int SDLCALL SDL_GetRendererInfo(int index,
+                                                SDL_RendererInfo * info);
+
+/**
+ * \fn int SDL_CreateRenderer(SDL_WindowID window, int index, Uint32 flags)
+ *
+ * \brief Create and make active a 2D rendering context for a window.
+ *
+ * \param windowID The window used for rendering.
+ * \param index The index of the render manager to initialize, or -1 to initialize the first one supporting the requested flags.
+ * \param flags SDL_RendererFlags
  *
- * \brief Create an SDL_Surface representing the drawing area of the window.
+ * \return 0 on success, -1 if the flags were not supported, or -2 if
+ *         there isn't enough memory to support the requested flags
+ *
+ * \sa SDL_SelectRenderer()
+ * \sa SDL_DestroyRenderer()
+ */
+extern DECLSPEC int SDLCALL SDL_CreateRenderer(SDL_WindowID windowID,
+                                               int index, Uint32 flags);
+
+/**
+ * \fn int SDL_SelectRenderer(SDL_WindowID windowID)
+ *
+ * \brief Select the rendering context for a particular window.
+ *
+ * \return 0 on success, -1 if the selected window doesn't have a
+ *         rendering context.
+ */
+extern DECLSPEC int SDLCALL SDL_SelectRenderer(SDL_WindowID windowID);
+
+/**
+ * \fn SDL_TextureID SDL_CreateTexture(Uint32 format, int access, int w, int h)
+ *
+ * \brief Create a texture
+ *
+ * \param format The format of the texture
+ * \param access One of the enumerated values in SDL_TextureAccess
+ * \param w The width of the texture in pixels
+ * \param h The height of the texture in pixels
+ *
+ * \return The created texture is returned, or 0 if no render manager was active,  the format was unsupported, or the width or height were out of range.
+ *
+ * \sa SDL_QueryTexture()
+ * \sa SDL_DestroyTexture()
  */
-extern DECLSPEC SDL_Surface *SDLCALL SDL_CreateWindowSurface(SDL_WindowID
-                                                             windowID,
-                                                             Uint32 format,
-                                                             Uint32 flags);
+extern DECLSPEC SDL_TextureID SDLCALL SDL_CreateTexture(Uint32 format,
+                                                        int access, int w,
+                                                        int h);
+
+/**
+ * \fn SDL_TextureID SDL_CreateTextureFromSurface(Uint32 format, int access, SDL_Surface *surface)
+ *
+ * \brief Create a texture from an existing surface
+ *
+ * \param format The format of the texture, or 0 to pick an appropriate format
+ * \param access One of the enumerated values in SDL_TextureAccess
+ * \param surface The surface containing pixel data used to fill the texture
+ *
+ * \return The created texture is returned, or 0 if no render manager was active,  the format was unsupported, or the surface width or height were out of range.
+ *
+ * \note The surface is not modified or freed by this function.
+ *
+ * \sa SDL_QueryTexture()
+ * \sa SDL_DestroyTexture()
+ */
+extern DECLSPEC SDL_TextureID SDLCALL SDL_CreateTextureFromSurface(Uint32
+                                                                   format,
+                                                                   int access,
+                                                                   SDL_Surface
+                                                                   * surface);
 
-/*
- * Makes sure the given list of rectangles is updated on the given screen.
- * If 'x', 'y', 'w' and 'h' are all 0, SDL_UpdateRect will update the entire
- * screen.
- * These functions should not be called while 'screen' is locked.
+/**
+ * \fn int SDL_QueryTexture(SDL_TextureID textureID, Uint32 *format, int *access, int *w, int *h)
+ *
+ * \brief Query the attributes of a texture
+ *
+ * \param texture A texture to be queried
+ * \param format A pointer filled in with the raw format of the texture.  The actual format may differ, but pixel transfers will use this format.
+ * \param access A pointer filled in with the actual access to the texture.
+ * \param w A pointer filled in with the width of the texture in pixels
+ * \param h A pointer filled in with the height of the texture in pixels
+ *
+ * \return 0 on success, or -1 if the texture is not valid
+ */
+extern DECLSPEC int SDLCALL SDL_QueryTexture(SDL_TextureID textureID,
+                                             Uint32 * format, int *access,
+                                             int *w, int *h);
+
+/**
+ * \fn int SDL_SetTexturePalette(SDL_TextureID textureID, SDL_Color * colors, int firstcolor, int ncolors)
+ *
+ * \brief Update an indexed texture with a color palette
+ *
+ * \param texture The texture to update
+ * \param colors The array of RGB color data
+ * \param firstcolor The first index to update
+ * \param ncolors The number of palette entries to fill with the color data
+ *
+ * \return 0 on success, or -1 if the texture is not valid or not an indexed texture
+ */
+extern DECLSPEC int SDLCALL SDL_SetTexturePalette(SDL_TextureID textureID,
+                                                  SDL_Color * colors,
+                                                  int firstcolor,
+                                                  int ncolors);
+
+/**
+ * \fn int SDL_UpdateTexture(SDL_TextureID textureID, SDL_Rect *rect, const void *pixels, int pitch)
+ *
+ * \brief Update the given texture rectangle with new pixel data.
+ *
+ * \param texture The texture to update
+ * \param rect A pointer to the rectangle of pixels to update, or NULL to update the entire texture.
+ * \param pixels The raw pixel data
+ * \param pitch The number of bytes between rows of pixel data
+ *
+ * \return 0 on success, or -1 if the texture is not valid
+ *
+ * \note This is a very slow function for textures not created with SDL_TextureAccess_Local.
  */
-extern DECLSPEC void SDLCALL SDL_UpdateRects
-    (SDL_Surface * screen, int numrects, SDL_Rect * rects);
-extern DECLSPEC void SDLCALL SDL_UpdateRect
-    (SDL_Surface * screen, Sint32 x, Sint32 y, Uint32 w, Uint32 h);
+extern DECLSPEC int SDLCALL SDL_UpdateTexture(SDL_TextureID textureID,
+                                              SDL_Rect * rect,
+                                              const void *pixels, int pitch);
+
+/**
+ * \fn void SDL_LockTexture(SDL_TextureID textureID, SDL_Rect *rect, int markDirty, void **pixels, int *pitch)
+ *
+ * \brief Lock a portion of the texture for pixel access.
+ *
+ * \param texture The texture to lock for access, which must have been created with SDL_TextureAccess_Local.
+ * \param rect A pointer to the rectangle to lock for access. If the rect is NULL, the entire texture will be locked.
+ * \param markDirty If this is nonzero, the locked area will be marked dirty when the texture is unlocked.
+ * \param pixels This is filled in with a pointer to the locked pixels, appropriately offset by the locked area.
+ * \param pitch This is filled in with the pitch of the locked pixels.
+ *
+ * \return 0 on success, or -1 if the texture is not valid or was created with SDL_TextureAccess_Remote
+ *
+ * \sa SDL_DirtyTexture()
+ * \sa SDL_UnlockTexture()
+ */
+extern DECLSPEC int SDLCALL SDL_LockTexture(SDL_TextureID textureID,
+                                            SDL_Rect * rect, int markDirty,
+                                            void **pixels, int *pitch);
+
+/**
+ * \fn void SDL_UnlockTexture(SDL_TextureID textureID)
+ *
+ * \brief Unlock a texture, uploading the changes to video memory, if needed.
+ *
+ * \sa SDL_LockTexture()
+ * \sa SDL_DirtyTexture()
+ */
+extern DECLSPEC void SDLCALL SDL_UnlockTexture(SDL_TextureID textureID);
+
+/**
+ * \fn void SDL_DirtyTexture(SDL_TextureID textureID, int numrects, SDL_Rect * rects)
+ *
+ * \brief Mark the specified rectangles of the texture as dirty.
+ *
+ * \note The texture must have been created with SDL_TextureAccess_Local.
+ *
+ * \sa SDL_LockTexture()
+ * \sa SDL_UnlockTexture()
+ */
+extern DECLSPEC void SDLCALL SDL_DirtyTexture(SDL_TextureID textureID,
+                                              int numrects, SDL_Rect * rects);
+
+/**
+ * \fn void SDL_SelectRenderTexture(SDL_TextureID textureID)
+ *
+ * \brief Select a texture as the rendering target, or 0 to reselect the current window.
+ *
+ * \note The texture must have been created with SDL_TextureAccess_Render.
+ */
+extern DECLSPEC void SDLCALL SDL_SelectRenderTexture(SDL_TextureID textureID);
+
+/**
+ * \fn void SDL_RenderFill(SDL_Rect *rect, Uint32 color)
+ *
+ * \brief Fill the current rendering target with the specified color.
+ *
+ * \param rect A pointer to the destination rectangle, or NULL for the entire rendering target.
+ * \param color An ARGB color value.
+ *
+ * \return 0 on success, or -1 if there is no renderer current
+ */
+extern DECLSPEC int SDLCALL SDL_RenderFill(SDL_Rect * rect, Uint32 color);
 
-/*
- * On hardware that supports double-buffering, this function sets up a flip
- * and returns.  The hardware will wait for vertical retrace, and then swap
- * video buffers before the next video surface blit or lock will return.
- * On hardware that doesn not support double-buffering, this is equivalent
- * to calling SDL_UpdateRect(screen, 0, 0, 0, 0);
- * The SDL_DOUBLEBUF flag must have been passed to SDL_SetVideoMode() when
- * setting the video mode for this function to perform hardware flipping.
- * This function returns 0 if successful, or -1 if there was an error.
+/**
+ * \fn int SDL_RenderCopy(SDL_TextureID textureID, SDL_Rect *srcrect, SDL_Rect *dstrect, Uint32 blendMode, Uint32 scaleMode)
+ *
+ * \brief Copy a portion of the texture to the current rendering target.
+ *
+ * \param texture The source texture.
+ * \param srcrect A pointer to the source rectangle, or NULL for the entire texture.
+ * \param dstrect A pointer to the destination rectangle, or NULL for the entire rendering target.
+ * \param blendMode SDL_TextureBlendMode to be used if the source texture has an alpha channel.
+ * \param scaleMode SDL_TextureScaleMode to be used if the source and destination rectangles don't have the same width and height.
+ *
+ * \return 0 on success, or -1 if there is no renderer current, or the driver doesn't support the requested operation.
+ *
+ * \note You can check the video driver info to see what operations are supported.
+ */
+extern DECLSPEC int SDLCALL SDL_RenderCopy(SDL_TextureID textureID,
+                                           SDL_Rect * srcrect,
+                                           SDL_Rect * dstrect, int blendMode,
+                                           int scaleMode);
+
+/**
+ * \fn int SDL_RenderReadPixels(SDL_Rect *rect, void *pixels, int pitch)
+ *
+ * \brief Read pixels from the current rendering target.
+ *
+ * \param rect A pointer to the rectangle to read, or NULL for the entire render target
+ * \param pixels A pointer to be filled in with the pixel data
+ * \param pitch The pitch of the pixels parameter
+ *
+ * \return 0 on success, or -1 if pixel reading is not supported.
+ *
+ * \warning This is a very slow operation, and should not be used frequently.
  */
-extern DECLSPEC int SDLCALL SDL_Flip(SDL_Surface * screen);
+extern DECLSPEC int SDLCALL SDL_RenderReadPixels(SDL_Rect * rect,
+                                                 void *pixels, int pitch);
+
+/**
+ * \fn int SDL_RenderWritePixels(SDL_Rect *rect, const void *pixels, int pitch)
+ *
+ * \brief Write pixels to the current rendering target.
+ *
+ * \param rect A pointer to the rectangle to write, or NULL for the entire render target
+ * \param pixels A pointer to the pixel data to write
+ * \param pitch The pitch of the pixels parameter
+ *
+ * \return 0 on success, or -1 if pixel writing is not supported.
+ *
+ * \warning This is a very slow operation, and should not be used frequently.
+ */
+extern DECLSPEC int SDLCALL SDL_RenderWritePixels(SDL_Rect * rect,
+                                                  const void *pixels,
+                                                  int pitch);
+
+/**
+ * \fn void SDL_RenderPresent(void)
+ *
+ * \brief Update the screen with rendering performed.
+ */
+extern DECLSPEC void SDLCALL SDL_RenderPresent(void);
+
+/**
+ * \fn void SDL_DestroyTexture(SDL_TextureID textureID);
+ *
+ * \brief Destroy the specified texture.
+ *
+ * \sa SDL_CreateTexture()
+ * \sa SDL_CreateTextureFromSurface()
+ */
+extern DECLSPEC void SDLCALL SDL_DestroyTexture(SDL_TextureID textureID);
+
+/**
+ * \fn void SDL_DestroyRenderer(SDL_WindowID windowID);
+ *
+ * \brief Destroy the rendering context for a window and free associated
+ *        textures.
+ *
+ * \sa SDL_CreateRenderer()
+ */
+extern DECLSPEC void SDLCALL SDL_DestroyRenderer(SDL_WindowID windowID);
 
 /*
  * Set the gamma correction for each of the color channels.
@@ -796,33 +1104,9 @@
  * If the function runs out of memory, it will return NULL.
  *
  * The 'flags' tell what kind of surface to create.
- * SDL_SWSURFACE means that the surface should be created in system memory.
- * SDL_HWSURFACE means that the surface should be created in video memory,
- * with the same format as the display surface.  This is useful for surfaces
- * that will not change much, to take advantage of hardware acceleration
- * when being blitted to the display surface.
- * SDL_ASYNCBLIT means that SDL will try to perform asynchronous blits with
- * this surface, but you must always lock it before accessing the pixels.
- * SDL will wait for current blits to finish before returning from the lock.
  * SDL_SRCCOLORKEY indicates that the surface will be used for colorkey blits.
- * If the hardware supports acceleration of colorkey blits between
- * two surfaces in video memory, SDL will try to place the surface in
- * video memory. If this isn't possible or if there is no hardware
- * acceleration available, the surface will be placed in system memory.
- * SDL_SRCALPHA means that the surface will be used for alpha blits and 
- * if the hardware supports hardware acceleration of alpha blits between
- * two surfaces in video memory, to place the surface in video memory
- * if possible, otherwise it will be placed in system memory.
- * If the surface is created in video memory, blits will be _much_ faster,
- * but the surface format must be identical to the video surface format,
- * and the only way to access the pixels member of the surface is to use
- * the SDL_LockSurface() and SDL_UnlockSurface() calls.
- * If the requested surface actually resides in video memory, SDL_HWSURFACE
- * will be set in the flags member of the returned surface.  If for some
- * reason the surface could not be placed in video memory, it will not have
- * the SDL_HWSURFACE flag set, and will be created in system memory instead.
+ * SDL_SRCALPHA means that the surface will be used for alpha blits.
  */
-#define SDL_AllocSurface    SDL_CreateRGBSurface
 extern DECLSPEC SDL_Surface *SDLCALL SDL_CreateRGBSurface
     (Uint32 flags, int width, int height, int depth,
      Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask);
@@ -835,6 +1119,8 @@
                                                               Uint32 Gmask,
                                                               Uint32 Bmask,
                                                               Uint32 Amask);
+extern DECLSPEC SDL_Surface *SDLCALL
+SDL_CreateRGBSurfaceFromTexture(SDL_TextureID textureID);
 extern DECLSPEC void SDLCALL SDL_FreeSurface(SDL_Surface * surface);
 
 /*
@@ -846,9 +1132,7 @@
  *
  * Not all surfaces require locking.  If SDL_MUSTLOCK(surface) evaluates
  * to 0, then you can read and write to the surface at any time, and the
- * pixel format of the surface will not change.  In particular, if the
- * SDL_HWSURFACE flag is not given when calling SDL_SetVideoMode(), you
- * will not need to lock the display surface before accessing it.
+ * pixel format of the surface will not change.
  * 
  * No operating system or library calls should be made between lock/unlock
  * pairs, as critical system locks may be held during this time.
@@ -951,6 +1235,18 @@
     (SDL_Surface * src, SDL_PixelFormat * fmt, Uint32 flags);
 
 /*
+ * This function performs a fast fill of the given rectangle with 'color'
+ * The given rectangle is clipped to the destination surface clip area
+ * and the final fill rectangle is saved in the passed in pointer.
+ * If 'dstrect' is NULL, the whole surface will be filled with 'color'
+ * The color should be a pixel of the format used by the surface, and 
+ * can be generated by the SDL_MapRGB() function.
+ * This function returns 0 on success, or -1 on error.
+ */
+extern DECLSPEC int SDLCALL SDL_FillRect
+    (SDL_Surface * dst, SDL_Rect * dstrect, Uint32 color);
+
+/*
  * This performs a fast blit from the source surface to the destination
  * surface.  It assumes that the source and destination rectangles are
  * the same size.  If either 'srcrect' or 'dstrect' are NULL, the entire
@@ -1034,45 +1330,16 @@
     (SDL_Surface * src, SDL_Rect * srcrect,
      SDL_Surface * dst, SDL_Rect * dstrect);
 
-/*
- * This function performs a fast fill of the given rectangle with 'color'
- * The given rectangle is clipped to the destination surface clip area
- * and the final fill rectangle is saved in the passed in pointer.
- * If 'dstrect' is NULL, the whole surface will be filled with 'color'
- * The color should be a pixel of the format used by the surface, and 
- * can be generated by the SDL_MapRGB() function.
- * This function returns 0 on success, or -1 on error.
- */
-extern DECLSPEC int SDLCALL SDL_FillRect
-    (SDL_Surface * dst, SDL_Rect * dstrect, Uint32 color);
-
-/* 
- * This function takes a surface and copies it to a new surface of the
- * pixel format and colors of the video framebuffer, suitable for fast
- * blitting onto the display surface.  It calls SDL_ConvertSurface()
+/**
+ * \fn int SDL_SoftStretch(SDL_Surface * src, SDL_Rect * srcrect, SDL_Surface * dst, SDL_Rect * dstrect)
  *
- * If you want to take advantage of hardware colorkey or alpha blit
- * acceleration, you should set the colorkey and alpha value before
- * calling this function.
- *
- * If the conversion fails or runs out of memory, it returns NULL
+ * \brief Perform a fast, low quality, stretch blit between two surfaces of the same pixel format.
+ * \note This function uses a static buffer, and is not thread-safe.
  */
-extern DECLSPEC SDL_Surface *SDLCALL SDL_DisplayFormat(SDL_Surface * surface);
-
-/* 
- * This function takes a surface and copies it to a new surface of the
- * pixel format and colors of the video framebuffer (if possible),
- * suitable for fast alpha blitting onto the display surface.
- * The new surface will always have an alpha channel.
- *
- * If you want to take advantage of hardware colorkey or alpha blit
- * acceleration, you should set the colorkey and alpha value before
- * calling this function.
- *
- * If the conversion fails or runs out of memory, it returns NULL
- */
-extern DECLSPEC SDL_Surface *SDLCALL SDL_DisplayFormatAlpha(SDL_Surface *
-                                                            surface);
+extern DECLSPEC int SDLCALL SDL_SoftStretch(SDL_Surface * src,
+                                            SDL_Rect * srcrect,
+                                            SDL_Surface * dst,
+                                            SDL_Rect * dstrect);
 
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
@@ -1145,12 +1412,6 @@
  */
 extern DECLSPEC void SDLCALL SDL_GL_SwapBuffers(void);
 
-/* Not in public API at the moment - do not use! */
-extern DECLSPEC int SDLCALL SDL_SoftStretch(SDL_Surface * src,
-                                            SDL_Rect * srcrect,
-                                            SDL_Surface * dst,
-                                            SDL_Rect * dstrect);
-
 /* Ends C function definitions when using C++ */
 #ifdef __cplusplus
 /* *INDENT-OFF* */
--- a/src/SDL_compat.c	Mon May 29 05:08:33 2006 +0000
+++ b/src/SDL_compat.c	Wed Jun 07 16:10:28 2006 +0000
@@ -53,6 +53,23 @@
     return NULL;
 }
 
+const SDL_VideoInfo *
+SDL_GetVideoInfo(void)
+{
+    static SDL_VideoInfo info;
+
+    /* Memory leak, compatibility code, who cares? */
+    if (!info.vfmt && SDL_GetDesktopDisplayMode()) {
+        int bpp;
+        Uint32 Rmask, Gmask, Bmask, Amask;
+
+        SDL_PixelFormatEnumToMasks(SDL_GetDesktopDisplayMode()->format, &bpp,
+                                   &Rmask, &Gmask, &Bmask, &Amask);
+        info.vfmt = SDL_AllocFormat(bpp, Rmask, Gmask, Bmask, Amask);
+    }
+    return &info;
+}
+
 int
 SDL_VideoModeOK(int width, int height, int bpp, Uint32 flags)
 {
@@ -296,6 +313,91 @@
 }
 
 SDL_Surface *
+SDL_CreateWindowSurface(SDL_WindowID windowID, Uint32 format, Uint32 flags)
+{
+    SDL_Window *window = SDL_GetWindowFromID(windowID);
+    Uint32 black;
+    SDL_Surface *surface;
+
+    if (!window) {
+        return NULL;
+    }
+
+    if (!_this->CreateWindowSurface) {
+        return NULL;
+    }
+
+    if (!window->surface) {
+        _this->CreateWindowSurface(_this, window, flags);
+        if (!window->surface) {
+            return NULL;
+        }
+        window->surface->flags |= SDL_SCREEN_SURFACE;
+
+        /* If we have a palettized surface, create a default palette */
+        if (window->surface->format->palette) {
+            SDL_Color colors[256];
+            SDL_PixelFormat *vf = window->surface->format;
+            SDL_DitherColors(colors, vf->BitsPerPixel);
+            SDL_SetColors(window->surface, colors, 0, vf->palette->ncolors);
+        }
+    }
+    surface = window->surface;
+
+    if (window->shadow) {
+        SDL_FreeSurface(window->shadow);
+        window->shadow = NULL;
+    }
+
+    /* Create a shadow surface if necessary */
+    if ((!(flags & SDL_ANYFORMAT)
+         && (format != SDL_GetCurrentDisplayMode()->format))
+        || ((flags & SDL_HWPALETTE)
+            && !(window->surface->flags & SDL_HWPALETTE))) {
+        int bpp;
+        Uint32 Rmask, Gmask, Bmask, Amask;
+
+        SDL_PixelFormatEnumToMasks(format, &bpp, &Amask, &Gmask, &Bmask,
+                                   &Amask);
+        window->shadow =
+            SDL_CreateRGBSurface(SDL_SWSURFACE, surface->w, surface->h, bpp,
+                                 Rmask, Gmask, Bmask, Amask);
+        if (window->shadow == NULL) {
+            return NULL;
+        }
+        window->shadow->flags |= SDL_SHADOW_SURFACE;
+
+        surface = window->shadow;
+
+        /* 8-bit shadow surfaces report that they have exclusive palette */
+        if (surface->format->palette) {
+            surface->flags |= SDL_HWPALETTE;
+            if (format == SDL_GetCurrentDisplayMode()->format) {
+                SDL_memcpy(surface->format->palette->colors,
+                           window->surface->format->palette->colors,
+                           window->surface->format->palette->ncolors *
+                           sizeof(SDL_Color));
+            } else {
+                SDL_DitherColors(surface->format->palette->colors, bpp);
+            }
+        }
+    }
+
+    /* Clear the surface for display */
+    {
+        Uint32 black = SDL_MapRGB(surface->format, 0, 0, 0);
+        SDL_FillRect(surface, NULL, black);
+        if (surface->flags & SDL_DOUBLEBUF) {
+            SDL_Flip(surface);
+            SDL_FillRect(surface, NULL, black);
+        }
+        SDL_Flip(surface);
+    }
+
+    return surface;
+}
+
+SDL_Surface *
 SDL_GetVideoSurface(void)
 {
     SDL_VideoDevice *_this = SDL_GetVideoDevice();
@@ -303,6 +405,201 @@
     return SDL_VideoSurface;
 }
 
+SDL_Surface *
+SDL_DisplayFormat(SDL_Surface * surface)
+{
+    Uint32 flags;
+
+    if (!SDL_PublicSurface) {
+        SDL_SetError("No video mode has been set");
+        return (NULL);
+    }
+    /* Set the flags appropriate for copying to display surface */
+    if (((SDL_PublicSurface->flags & SDL_HWSURFACE) == SDL_HWSURFACE)
+        && _this->info.blit_hw)
+        flags = SDL_HWSURFACE;
+    else
+        flags = SDL_SWSURFACE;
+#ifdef AUTORLE_DISPLAYFORMAT
+    flags |= (surface->flags & (SDL_SRCCOLORKEY | SDL_SRCALPHA));
+    flags |= SDL_RLEACCELOK;
+#else
+    flags |=
+        surface->flags & (SDL_SRCCOLORKEY | SDL_SRCALPHA | SDL_RLEACCELOK);
+#endif
+    return (SDL_ConvertSurface(surface, SDL_PublicSurface->format, flags));
+}
+
+SDL_Surface *
+SDL_DisplayFormatAlpha(SDL_Surface * surface)
+{
+    SDL_PixelFormat *vf;
+    SDL_PixelFormat *format;
+    SDL_Surface *converted;
+    Uint32 flags;
+    /* default to ARGB8888 */
+    Uint32 amask = 0xff000000;
+    Uint32 rmask = 0x00ff0000;
+    Uint32 gmask = 0x0000ff00;
+    Uint32 bmask = 0x000000ff;
+
+    if (!SDL_PublicSurface) {
+        SDL_SetError("No video mode has been set");
+        return (NULL);
+    }
+    vf = SDL_PublicSurface->format;
+
+    switch (vf->BytesPerPixel) {
+    case 2:
+        /* For XGY5[56]5, use, AXGY8888, where {X, Y} = {R, B}.
+           For anything else (like ARGB4444) it doesn't matter
+           since we have no special code for it anyway */
+        if ((vf->Rmask == 0x1f) &&
+            (vf->Bmask == 0xf800 || vf->Bmask == 0x7c00)) {
+            rmask = 0xff;
+            bmask = 0xff0000;
+        }
+        break;
+
+    case 3:
+    case 4:
+        /* Keep the video format, as long as the high 8 bits are
+           unused or alpha */
+        if ((vf->Rmask == 0xff) && (vf->Bmask == 0xff0000)) {
+            rmask = 0xff;
+            bmask = 0xff0000;
+        }
+        break;
+
+    default:
+        /* We have no other optimised formats right now. When/if a new
+           optimised alpha format is written, add the converter here */
+        break;
+    }
+    format = SDL_AllocFormat(32, rmask, gmask, bmask, amask);
+    flags = SDL_PublicSurface->flags & SDL_HWSURFACE;
+    flags |= surface->flags & (SDL_SRCALPHA | SDL_RLEACCELOK);
+    converted = SDL_ConvertSurface(surface, format, flags);
+    SDL_FreeFormat(format);
+    return (converted);
+}
+
+void
+SDL_UpdateRect(SDL_Surface * screen, Sint32 x, Sint32 y, Uint32 w, Uint32 h)
+{
+    if (screen) {
+        SDL_Rect rect;
+
+        /* Perform some checking */
+        if (w == 0)
+            w = screen->w;
+        if (h == 0)
+            h = screen->h;
+        if ((int) (x + w) > screen->w)
+            return;
+        if ((int) (y + h) > screen->h)
+            return;
+
+        /* Fill the rectangle */
+        rect.x = (Sint16) x;
+        rect.y = (Sint16) y;
+        rect.w = (Uint16) w;
+        rect.h = (Uint16) h;
+        SDL_UpdateRects(screen, 1, &rect);
+    }
+}
+void
+SDL_UpdateRects(SDL_Surface * screen, int numrects, SDL_Rect * rects)
+{
+    int i;
+    SDL_Window *window;
+
+    /* Find the window corresponding to this surface */
+    window = SDL_GetWindowFromSurface(screen);
+    if (!window) {
+        SDL_SetError("Couldn't find window associated with surface");
+        return;
+    }
+
+    if (screen->flags & SDL_SHADOW_SURFACE) {
+        if (SHOULD_DRAWCURSOR(SDL_cursorstate)) {
+            SDL_LockCursor();
+            SDL_DrawCursor(screen);
+            for (i = 0; i < numrects; ++i) {
+                SDL_LowerBlit(screen, &rects[i], window->surface, &rects[i]);
+            }
+            SDL_EraseCursor(screen);
+            SDL_UnlockCursor();
+        } else {
+            for (i = 0; i < numrects; ++i) {
+                SDL_LowerBlit(screen, &rects[i], window->surface, &rects[i]);
+            }
+        }
+
+        /* Fall through to video surface update */
+        screen = window->surface;
+    }
+    if ((screen->flags & SDL_SCREEN_SURFACE) && _this->UpdateWindowSurface) {
+        /* Update the video surface */
+        if (screen->offset) {
+            int offset_y = screen->offset / screen->pitch;
+            int offset_x = screen->offset % screen->pitch;
+            for (i = 0; i < numrects; ++i) {
+                rects[i].x += offset_x;
+                rects[i].y += offset_y;
+            }
+            _this->UpdateWindowSurface(_this, window, numrects, rects);
+            for (i = 0; i < numrects; ++i) {
+                rects[i].x -= offset_x;
+                rects[i].y -= offset_y;
+            }
+        } else {
+            _this->UpdateWindowSurface(_this, window, numrects, rects);
+        }
+    }
+}
+
+int
+SDL_Flip(SDL_Surface * screen)
+{
+    SDL_Window *window;
+
+    /* Find the window corresponding to this surface */
+    window = SDL_GetWindowFromSurface(screen);
+    if (!window) {
+        SDL_SetError("Couldn't find window associated with surface");
+        return;
+    }
+
+    /* Copy the shadow surface to the video surface */
+    if (screen->flags & SDL_SHADOW_SURFACE) {
+        SDL_Rect rect;
+
+        rect.x = 0;
+        rect.y = 0;
+        rect.w = screen->w;
+        rect.h = screen->h;
+        if (SHOULD_DRAWCURSOR(SDL_cursorstate)) {
+            SDL_LockCursor();
+            SDL_DrawCursor(screen);
+            SDL_LowerBlit(screen, &rect, window->surface, &rect);
+            SDL_EraseCursor(screen);
+            SDL_UnlockCursor();
+        } else {
+            SDL_LowerBlit(screen, &rect, window->surface, &rect);
+        }
+
+        /* Fall through to video surface update */
+        screen = window->surface;
+    }
+    if (screen->flags & SDL_DOUBLEBUF) {
+        _this->FlipWindowSurface(_this, window);
+    } else {
+        SDL_UpdateRect(screen, 0, 0, 0, 0);
+    }
+    return (0);
+}
+
 void
 SDL_WM_SetCaption(const char *title, const char *icon)
 {
@@ -387,9 +684,555 @@
 }
 
 int
+SDL_SetScreenColors(SDL_Surface * screen, SDL_Color * colors, int firstcolor,
+                    int ncolors)
+{
+    SDL_Window *window = NULL;
+    SDL_Palette *pal;
+    int gotall;
+    int palsize;
+
+    /* Verify the parameters */
+    pal = screen->format->palette;
+    if (!pal) {
+        return 0;               /* not a palettized surface */
+    }
+    gotall = 1;
+    palsize = 1 << screen->format->BitsPerPixel;
+    if (ncolors > (palsize - firstcolor)) {
+        ncolors = (palsize - firstcolor);
+        gotall = 0;
+    }
+
+    if (screen->flags & (SDL_SHADOW_SURFACE | SDL_SCREEN_SURFACE)) {
+        window = SDL_GetWindowFromSurface(screen);
+        if (!window) {
+            return 0;
+        }
+    }
+
+    if (screen->flags & SDL_SHADOW_SURFACE) {
+        SDL_Palette *vidpal;
+
+        vidpal = window->surface->format->palette;
+        if (vidpal && vidpal->ncolors == pal->ncolors) {
+            /* This is a shadow surface, and the physical
+             * framebuffer is also indexed. Propagate the
+             * changes to its logical palette so that
+             * updates are always identity blits
+             */
+            SDL_memcpy(vidpal->colors + firstcolor, colors,
+                       ncolors * sizeof(*colors));
+        }
+        if (window->surface->flags & SDL_HWPALETTE) {
+            /* Set the physical palette */
+            screen = window->surface;
+        } else {
+            SDL_UpdateRect(screen, 0, 0, 0, 0);
+        }
+    }
+
+    if (screen->flags & SDL_SCREEN_SURFACE) {
+        if (_this->SetWindowColors) {
+            gotall =
+                _this->SetWindowColors(_this, window, firstcolor, ncolors,
+                                       colors);
+            if (!gotall) {
+                /* The video flags shouldn't have SDL_HWPALETTE, and
+                   the video driver is responsible for copying back the
+                   correct colors into the video surface palette.
+                 */
+                ;
+            }
+        }
+        SDL_CursorPaletteChanged();
+    }
+
+    return gotall;
+}
+
+int
 SDL_GetWMInfo(SDL_SysWMinfo * info)
 {
     return SDL_GetWindowWMInfo(window, info);
 }
 
+void
+SDL_MoveCursor(int x, int y)
+{
+    SDL_VideoDevice *_this = SDL_GetVideoDevice();
+
+    /* Erase and update the current mouse position */
+    if (SHOULD_DRAWCURSOR(SDL_cursorstate)) {
+        /* Erase and redraw mouse cursor in new position */
+        SDL_LockCursor();
+        SDL_EraseCursor(SDL_VideoSurface);
+        SDL_cursor->area.x = (x - SDL_cursor->hot_x);
+        SDL_cursor->area.y = (y - SDL_cursor->hot_y);
+        SDL_DrawCursor(SDL_VideoSurface);
+        SDL_UnlockCursor();
+    } else if (_this->MoveWMCursor) {
+        _this->MoveWMCursor(_this, x, y);
+    }
+}
+
+/* Keep track of the current cursor colors */
+static int palette_changed = 1;
+static Uint8 pixels8[2];
+
+void
+SDL_CursorPaletteChanged(void)
+{
+    palette_changed = 1;
+}
+
+void
+SDL_MouseRect(SDL_Rect * area)
+{
+    SDL_VideoDevice *_this = SDL_GetVideoDevice();
+    int clip_diff;
+
+    *area = SDL_cursor->area;
+    if (area->x < 0) {
+        area->w += area->x;
+        area->x = 0;
+    }
+    if (area->y < 0) {
+        area->h += area->y;
+        area->y = 0;
+    }
+    clip_diff = (area->x + area->w) - SDL_VideoSurface->w;
+    if (clip_diff > 0) {
+        area->w = area->w < clip_diff ? 0 : area->w - clip_diff;
+    }
+    clip_diff = (area->y + area->h) - SDL_VideoSurface->h;
+    if (clip_diff > 0) {
+        area->h = area->h < clip_diff ? 0 : area->h - clip_diff;
+    }
+}
+
+static void
+SDL_DrawCursorFast(SDL_Surface * screen, SDL_Rect * area)
+{
+    const Uint32 pixels[2] = { 0xFFFFFFFF, 0x00000000 };
+    int i, w, h;
+    Uint8 *data, datab;
+    Uint8 *mask, maskb;
+
+    data = SDL_cursor->data + area->y * SDL_cursor->area.w / 8;
+    mask = SDL_cursor->mask + area->y * SDL_cursor->area.w / 8;
+    switch (screen->format->BytesPerPixel) {
+
+    case 1:
+        {
+            Uint8 *dst;
+            int dstskip;
+
+            if (palette_changed) {
+                pixels8[0] =
+                    (Uint8) SDL_MapRGB(screen->format, 255, 255, 255);
+                pixels8[1] = (Uint8) SDL_MapRGB(screen->format, 0, 0, 0);
+                palette_changed = 0;
+            }
+            dst = (Uint8 *) screen->pixels +
+                (SDL_cursor->area.y + area->y) * screen->pitch +
+                SDL_cursor->area.x;
+            dstskip = screen->pitch - area->w;
+
+            for (h = area->h; h; h--) {
+                for (w = area->w / 8; w; w--) {
+                    maskb = *mask++;
+                    datab = *data++;
+                    for (i = 0; i < 8; ++i) {
+                        if (maskb & 0x80) {
+                            *dst = pixels8[datab >> 7];
+                        }
+                        maskb <<= 1;
+                        datab <<= 1;
+                        dst++;
+                    }
+                }
+                dst += dstskip;
+            }
+        }
+        break;
+
+    case 2:
+        {
+            Uint16 *dst;
+            int dstskip;
+
+            dst = (Uint16 *) screen->pixels +
+                (SDL_cursor->area.y + area->y) * screen->pitch / 2 +
+                SDL_cursor->area.x;
+            dstskip = (screen->pitch / 2) - area->w;
+
+            for (h = area->h; h; h--) {
+                for (w = area->w / 8; w; w--) {
+                    maskb = *mask++;
+                    datab = *data++;
+                    for (i = 0; i < 8; ++i) {
+                        if (maskb & 0x80) {
+                            *dst = (Uint16) pixels[datab >> 7];
+                        }
+                        maskb <<= 1;
+                        datab <<= 1;
+                        dst++;
+                    }
+                }
+                dst += dstskip;
+            }
+        }
+        break;
+
+    case 3:
+        {
+            Uint8 *dst;
+            int dstskip;
+
+            dst = (Uint8 *) screen->pixels +
+                (SDL_cursor->area.y + area->y) * screen->pitch +
+                SDL_cursor->area.x * 3;
+            dstskip = screen->pitch - area->w * 3;
+
+            for (h = area->h; h; h--) {
+                for (w = area->w / 8; w; w--) {
+                    maskb = *mask++;
+                    datab = *data++;
+                    for (i = 0; i < 8; ++i) {
+                        if (maskb & 0x80) {
+                            SDL_memset(dst, pixels[datab >> 7], 3);
+                        }
+                        maskb <<= 1;
+                        datab <<= 1;
+                        dst += 3;
+                    }
+                }
+                dst += dstskip;
+            }
+        }
+        break;
+
+    case 4:
+        {
+            Uint32 *dst;
+            int dstskip;
+
+            dst = (Uint32 *) screen->pixels +
+                (SDL_cursor->area.y + area->y) * screen->pitch / 4 +
+                SDL_cursor->area.x;
+            dstskip = (screen->pitch / 4) - area->w;
+
+            for (h = area->h; h; h--) {
+                for (w = area->w / 8; w; w--) {
+                    maskb = *mask++;
+                    datab = *data++;
+                    for (i = 0; i < 8; ++i) {
+                        if (maskb & 0x80) {
+                            *dst = pixels[datab >> 7];
+                        }
+                        maskb <<= 1;
+                        datab <<= 1;
+                        dst++;
+                    }
+                }
+                dst += dstskip;
+            }
+        }
+        break;
+    }
+}
+
+static void
+SDL_DrawCursorSlow(SDL_Surface * screen, SDL_Rect * area)
+{
+    const Uint32 pixels[2] = { 0xFFFFFF, 0x000000 };
+    int h;
+    int x, minx, maxx;
+    Uint8 *data, datab = 0;
+    Uint8 *mask, maskb = 0;
+    Uint8 *dst;
+    int dstbpp, dstskip;
+
+    data = SDL_cursor->data + area->y * SDL_cursor->area.w / 8;
+    mask = SDL_cursor->mask + area->y * SDL_cursor->area.w / 8;
+    dstbpp = screen->format->BytesPerPixel;
+    dst = (Uint8 *) screen->pixels +
+        (SDL_cursor->area.y + area->y) * screen->pitch +
+        SDL_cursor->area.x * dstbpp;
+    dstskip = screen->pitch - SDL_cursor->area.w * dstbpp;
+
+    minx = area->x;
+    maxx = area->x + area->w;
+    if (screen->format->BytesPerPixel == 1) {
+        if (palette_changed) {
+            pixels8[0] = (Uint8) SDL_MapRGB(screen->format, 255, 255, 255);
+            pixels8[1] = (Uint8) SDL_MapRGB(screen->format, 0, 0, 0);
+            palette_changed = 0;
+        }
+        for (h = area->h; h; h--) {
+            for (x = 0; x < SDL_cursor->area.w; ++x) {
+                if ((x % 8) == 0) {
+                    maskb = *mask++;
+                    datab = *data++;
+                }
+                if ((x >= minx) && (x < maxx)) {
+                    if (maskb & 0x80) {
+                        SDL_memset(dst, pixels8[datab >> 7], dstbpp);
+                    }
+                }
+                maskb <<= 1;
+                datab <<= 1;
+                dst += dstbpp;
+            }
+            dst += dstskip;
+        }
+    } else {
+        for (h = area->h; h; h--) {
+            for (x = 0; x < SDL_cursor->area.w; ++x) {
+                if ((x % 8) == 0) {
+                    maskb = *mask++;
+                    datab = *data++;
+                }
+                if ((x >= minx) && (x < maxx)) {
+                    if (maskb & 0x80) {
+                        SDL_memset(dst, pixels[datab >> 7], dstbpp);
+                    }
+                }
+                maskb <<= 1;
+                datab <<= 1;
+                dst += dstbpp;
+            }
+            dst += dstskip;
+        }
+    }
+}
+
+/* This handles the ugly work of converting the saved cursor background from
+   the pixel format of the shadow surface to that of the video surface.
+   This is only necessary when blitting from a shadow surface of a different
+   pixel format than the video surface, and using a software rendered cursor.
+*/
+static void
+SDL_ConvertCursorSave(SDL_Surface * screen, int w, int h)
+{
+    SDL_VideoDevice *_this = SDL_GetVideoDevice();
+    SDL_BlitInfo info;
+    SDL_loblit RunBlit;
+
+    /* Make sure we can steal the blit mapping */
+    if (screen->map->dst != SDL_VideoSurface) {
+        return;
+    }
+
+    /* Set up the blit information */
+    info.s_pixels = SDL_cursor->save[1];
+    info.s_width = w;
+    info.s_height = h;
+    info.s_skip = 0;
+    info.d_pixels = SDL_cursor->save[0];
+    info.d_width = w;
+    info.d_height = h;
+    info.d_skip = 0;
+    info.aux_data = screen->map->sw_data->aux_data;
+    info.src = screen->format;
+    info.table = screen->map->table;
+    info.dst = SDL_VideoSurface->format;
+    RunBlit = screen->map->sw_data->blit;
+
+    /* Run the actual software blit */
+    RunBlit(&info);
+}
+
+void
+SDL_DrawCursorNoLock(SDL_Surface * screen)
+{
+    SDL_VideoDevice *_this = SDL_GetVideoDevice();
+    SDL_Rect area;
+
+    /* Get the mouse rectangle, clipped to the screen */
+    SDL_MouseRect(&area);
+    if ((area.w == 0) || (area.h == 0)) {
+        return;
+    }
+
+    /* Copy mouse background */
+    {
+        int w, h, screenbpp;
+        Uint8 *src, *dst;
+
+        /* Set up the copy pointers */
+        screenbpp = screen->format->BytesPerPixel;
+        if ((screen == SDL_VideoSurface) ||
+            FORMAT_EQUAL(screen->format, SDL_VideoSurface->format)) {
+            dst = SDL_cursor->save[0];
+        } else {
+            dst = SDL_cursor->save[1];
+        }
+        src = (Uint8 *) screen->pixels + area.y * screen->pitch +
+            area.x * screenbpp;
+
+        /* Perform the copy */
+        w = area.w * screenbpp;
+        h = area.h;
+        while (h--) {
+            SDL_memcpy(dst, src, w);
+            dst += w;
+            src += screen->pitch;
+        }
+    }
+
+    /* Draw the mouse cursor */
+    area.x -= SDL_cursor->area.x;
+    area.y -= SDL_cursor->area.y;
+    if ((area.x == 0) && (area.w == SDL_cursor->area.w)) {
+        SDL_DrawCursorFast(screen, &area);
+    } else {
+        SDL_DrawCursorSlow(screen, &area);
+    }
+}
+
+void
+SDL_DrawCursor(SDL_Surface * screen)
+{
+    /* Lock the screen if necessary */
+    if (screen == NULL) {
+        return;
+    }
+    if (SDL_MUSTLOCK(screen)) {
+        if (SDL_LockSurface(screen) < 0) {
+            return;
+        }
+    }
+
+    SDL_DrawCursorNoLock(screen);
+
+    /* Unlock the screen and update if necessary */
+    if (SDL_MUSTLOCK(screen)) {
+        SDL_UnlockSurface(screen);
+    }
+    if ((screen->flags & SDL_SCREEN_SURFACE) &&
+        !(screen->flags & SDL_HWSURFACE)) {
+        SDL_VideoDevice *_this = SDL_GetVideoDevice();
+        SDL_Window *window;
+        SDL_Rect area;
+
+        window = SDL_GetWindowFromSurface(screen);
+        if (!window) {
+            return;
+        }
+
+        SDL_MouseRect(&area);
+
+        if (_this->UpdateWindowSurface) {
+            _this->UpdateWindowSurface(_this, window, 1, &area);
+        }
+    }
+}
+
+void
+SDL_EraseCursorNoLock(SDL_Surface * screen)
+{
+    SDL_VideoDevice *_this = SDL_GetVideoDevice();
+    SDL_Window *window;
+    SDL_Rect area;
+
+    /* Get the window associated with the surface */
+    window = SDL_GetWindowFromSurface(screen);
+    if (!window || !window->surface) {
+        return;
+    }
+
+    /* Get the mouse rectangle, clipped to the screen */
+    SDL_MouseRect(&area);
+    if ((area.w == 0) || (area.h == 0)) {
+        return;
+    }
+
+    /* Copy mouse background */
+    {
+        int w, h, screenbpp;
+        Uint8 *src, *dst;
+
+        /* Set up the copy pointers */
+        screenbpp = screen->format->BytesPerPixel;
+        if ((screen->flags & SDL_SCREEN_SURFACE) ||
+            FORMAT_EQUAL(screen->format, window->surface->format)) {
+            src = SDL_cursor->save[0];
+        } else {
+            src = SDL_cursor->save[1];
+        }
+        dst = (Uint8 *) screen->pixels + area.y * screen->pitch +
+            area.x * screenbpp;
+
+        /* Perform the copy */
+        w = area.w * screenbpp;
+        h = area.h;
+        while (h--) {
+            SDL_memcpy(dst, src, w);
+            src += w;
+            dst += screen->pitch;
+        }
+
+        /* Perform pixel conversion on cursor background */
+        if (src > SDL_cursor->save[1]) {
+            SDL_ConvertCursorSave(screen, area.w, area.h);
+        }
+    }
+}
+
+void
+SDL_EraseCursor(SDL_Surface * screen)
+{
+    /* Lock the screen if necessary */
+    if (screen == NULL) {
+        return;
+    }
+    if (SDL_MUSTLOCK(screen)) {
+        if (SDL_LockSurface(screen) < 0) {
+            return;
+        }
+    }
+
+    SDL_EraseCursorNoLock(screen);
+
+    /* Unlock the screen and update if necessary */
+    if (SDL_MUSTLOCK(screen)) {
+        SDL_UnlockSurface(screen);
+    }
+    if ((screen->flags & SDL_SCREEN_SURFACE) &&
+        !(screen->flags & SDL_HWSURFACE)) {
+        SDL_VideoDevice *_this = SDL_GetVideoDevice();
+        SDL_Window *window;
+        SDL_Rect area;
+
+        window = SDL_GetWindowFromSurface(screen);
+        if (!window) {
+            return;
+        }
+
+        SDL_MouseRect(&area);
+
+        if (_this->UpdateWindowSurface) {
+            _this->UpdateWindowSurface(_this, window, 1, &area);
+        }
+    }
+}
+
+/* Reset the cursor on video mode change
+   FIXME:  Keep track of all cursors, and reset them all.
+ */
+void
+SDL_ResetCursor(void)
+{
+    int savelen;
+
+    if (SDL_cursor) {
+        savelen = SDL_cursor->area.w * 4 * SDL_cursor->area.h;
+        SDL_cursor->area.x = 0;
+        SDL_cursor->area.y = 0;
+        SDL_memset(SDL_cursor->save[0], 0, savelen);
+    }
+}
+
 /* vi: set ts=4 sw=4 expandtab: */
--- a/src/events/SDL_events_c.h	Mon May 29 05:08:33 2006 +0000
+++ b/src/events/SDL_events_c.h	Wed Jun 07 16:10:28 2006 +0000
@@ -23,6 +23,7 @@
 
 /* Useful functions and variables from SDL_events.c */
 #include "SDL_events.h"
+#include "SDL_mouse_c.h"
 
 /* Start and stop the event processing loop */
 extern int SDL_StartEventLoop(Uint32 flags);
@@ -33,41 +34,25 @@
 extern void SDL_Unlock_EventThread(void);
 extern Uint32 SDL_EventThreadID(void);
 
-/* Event handler init routines */
 extern int SDL_KeyboardInit(void);
-extern int SDL_MouseInit(void);
-extern int SDL_QuitInit(void);
+extern int SDL_SendKeyboard(Uint8 state, SDL_keysym * key);
+extern void SDL_KeyboardQuit(void);
 
-/* Event handler quit routines */
-extern void SDL_KeyboardQuit(void);
-extern void SDL_MouseQuit(void);
+extern int SDL_QuitInit(void);
+extern int SDL_SendQuit(void);
 extern void SDL_QuitQuit(void);
 
+extern int SDL_SendWindowEvent(SDL_WindowID windowID, Uint8 windowevent,
+                               int data1, int data2);
+
+extern int SDL_SendSysWMEvent(SDL_SysWMmsg * message);
+
 /* The event filter function */
 extern SDL_EventFilter SDL_EventOK;
 
 /* The array of event processing states */
 extern Uint8 SDL_ProcessEvents[SDL_NUMEVENTS];
 
-/* Internal event queueing functions
-   (from SDL_mouse.c, SDL_keyboard.c, SDL_quit.c, SDL_events.c, SDL_windowevents.c)
- */
-extern int SDL_PrivateWindowEvent(SDL_WindowID windowID, Uint8 windowevent,
-                                  int data1, int data2);
-extern int SDL_PrivateMouseMotion(Uint8 buttonstate, int relative, Sint16 x,
-                                  Sint16 y);
-extern int SDL_PrivateMouseButton(Uint8 state, Uint8 button, Sint16 x,
-                                  Sint16 y);
-extern int SDL_PrivateKeyboard(Uint8 state, SDL_keysym * key);
-extern int SDL_PrivateQuit(void);
-extern int SDL_PrivateSysWMEvent(SDL_SysWMmsg * message);
-
-/* Used by the activity event handler to remove mouse focus */
-extern void SDL_ResetMouse(void);
-
-/* Used by the activity event handler to remove keyboard focus */
-extern void SDL_ResetKeyboard(void);
-
 /* Used by the event loop to queue pending keyboard repeat events */
 extern void SDL_CheckKeyRepeat(void);
 
--- a/src/events/SDL_keyboard.c	Mon May 29 05:08:33 2006 +0000
+++ b/src/events/SDL_keyboard.c	Wed Jun 07 16:10:28 2006 +0000
@@ -326,7 +326,7 @@
     for (key = SDLK_FIRST; key < SDLK_LAST; ++key) {
         if (SDL_KeyState[key] == SDL_PRESSED) {
             keysym.sym = key;
-            SDL_PrivateKeyboard(SDL_RELEASED, &keysym);
+            SDL_SendKeyboard(SDL_RELEASED, &keysym);
         }
     }
     SDL_KeyRepeat.timestamp = 0;
@@ -382,7 +382,7 @@
 
 /* These are global for SDL_eventloop.c */
 int
-SDL_PrivateKeyboard(Uint8 state, SDL_keysym * keysym)
+SDL_SendKeyboard(Uint8 state, SDL_keysym * keysym)
 {
     SDL_Event event;
     int posted, repeatable;
--- a/src/events/SDL_mouse.c	Mon May 29 05:08:33 2006 +0000
+++ b/src/events/SDL_mouse.c	Wed Jun 07 16:10:28 2006 +0000
@@ -25,249 +25,261 @@
 
 #include "SDL_events.h"
 #include "SDL_events_c.h"
-#include "../video/SDL_cursor_c.h"
-#include "../video/SDL_sysvideo.h"
+#include "SDL_mouse_c.h"
 
 
-/* These are static for our mouse handling code */
-static Sint16 SDL_MouseX = 0;
-static Sint16 SDL_MouseY = 0;
-static Sint16 SDL_DeltaX = 0;
-static Sint16 SDL_DeltaY = 0;
-static Uint8 SDL_ButtonState = 0;
+static int SDL_num_mice;
+static int SDL_current_mouse;
+static SDL_Mouse *SDL_mice;
 
 
 /* Public functions */
 int
 SDL_MouseInit(void)
 {
-    /* The mouse is at (0,0) */
-    SDL_MouseX = 0;
-    SDL_MouseY = 0;
-    SDL_DeltaX = 0;
-    SDL_DeltaY = 0;
-    SDL_ButtonState = 0;
+    return (0);
+}
+
+int
+SDL_AddMouse(SDL_WindowID focus, int x, int y, Uint8 buttonstate)
+{
+    SDL_Mouse *new_mice;
+    int index;
+    SDL_Mouse *mouse;
+
+    new_mice =
+        (SDL_Mouse *) SDL_realloc(SDL_mice,
+                                  (SDL_num_mice + 1) * sizeof(*new_mice));
+    if (!new_mice) {
+        SDL_OutOfMemory();
+        return -1;
+    }
 
-    /* That's it! */
-    return (0);
+    index = SDL_num_mice++;
+    mouse = &SDL_mice[index];
+    mouse->focus = focus;
+    mouse->x = x;
+    mouse->y = y;
+    mouse->xdelta = 0;
+    mouse->ydelta = 0;
+    mouse->buttonstate = buttonstate;
+
+    return index;
+}
+
+SDL_Mouse *
+SDL_GetMouse(int index)
+{
+    if (index < 0 || index >= SDL_num_mice) {
+        return NULL;
+    }
+    return &SDL_mice[index];
 }
 
 void
 SDL_MouseQuit(void)
 {
+    SDL_num_mice = 0;
+    SDL_current_mouse = 0;
+
+    if (SDL_mice) {
+        SDL_free(SDL_mice);
+        SDL_mice = NULL;
+    }
+}
+
+int
+SDL_GetNumMice(void)
+{
+    return SDL_num_mice;
 }
 
-/* We lost the mouse, so post button up messages for all pressed buttons */
-void
-SDL_ResetMouse(void)
+int
+SDL_SelectMouse(int index)
 {
-    Uint8 i;
-    for (i = 0; i < sizeof(SDL_ButtonState) * 8; ++i) {
-        if (SDL_ButtonState & SDL_BUTTON(i)) {
-            SDL_PrivateMouseButton(SDL_RELEASED, i, 0, 0);
-        }
+    if (index >= 0 && index < SDL_num_mice) {
+        SDL_current_mouse = index;
     }
+    return SDL_current_mouse;
+}
+
+SDL_WindowID
+SDL_GetMouseFocusWindow()
+{
+    SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
+
+    if (!mouse) {
+        return 0;
+    }
+    return mouse->focus;
 }
 
 Uint8
 SDL_GetMouseState(int *x, int *y)
 {
+    SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
+
+    if (!mouse) {
+        if (x) {
+            *x = 0;
+        }
+        if (y) {
+            *y = 0;
+        }
+        return 0;
+    }
+
     if (x) {
-        *x = SDL_MouseX;
+        *x = mouse->x;
     }
     if (y) {
-        *y = SDL_MouseY;
+        *y = mouse->y;
     }
-    return (SDL_ButtonState);
+    return mouse->buttonstate;
 }
 
 Uint8
 SDL_GetRelativeMouseState(int *x, int *y)
 {
-    if (x)
-        *x = SDL_DeltaX;
-    if (y)
-        *y = SDL_DeltaY;
-    SDL_DeltaX = 0;
-    SDL_DeltaY = 0;
-    return (SDL_ButtonState);
-}
-
-static void
-ClipOffset(Sint16 * x, Sint16 * y)
-{
-    SDL_VideoDevice *_this = SDL_GetVideoDevice();
+    SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
 
-    /* This clips absolute mouse coordinates when the apparent
-       display surface is smaller than the real display surface.
-     */
-    if (SDL_VideoSurface->offset) {
-        *y -= SDL_VideoSurface->offset / SDL_VideoSurface->pitch;
-        *x -= (SDL_VideoSurface->offset % SDL_VideoSurface->pitch) /
-            SDL_VideoSurface->format->BytesPerPixel;
-    }
-}
-
-/* These are global for SDL_eventloop.c */
-int
-SDL_PrivateMouseMotion(Uint8 buttonstate, int relative, Sint16 x, Sint16 y)
-{
-    SDL_VideoDevice *_this = SDL_GetVideoDevice();
-    int posted;
-    Uint16 X, Y;
-    Sint16 Xrel;
-    Sint16 Yrel;
-
-    /* Don't handle mouse motion if there's no cursor surface */
-    if (SDL_VideoSurface == NULL) {
-        return (0);
+    if (!mouse) {
+        if (x) {
+            *x = 0;
+        }
+        if (y) {
+            *y = 0;
+        }
+        return 0;
     }
 
-    /* Default buttonstate is the current one */
-    if (!buttonstate) {
-        buttonstate = SDL_ButtonState;
+    if (x) {
+        *x = mouse->xdelta;
     }
+    if (y) {
+        *y = mouse->ydelta;
+    }
+    mouse->xdelta = 0;
+    mouse->ydelta = 0;
+    return mouse->buttonstate;
+}
 
-    Xrel = x;
-    Yrel = y;
-    if (relative) {
-        /* Push the cursor around */
-        x = (SDL_MouseX + x);
-        y = (SDL_MouseY + y);
-    } else {
-        /* Do we need to clip {x,y} ? */
-        ClipOffset(&x, &y);
+int
+SDL_SendMouseMotion(int index, SDL_WindowID windowID, int relative, int x,
+                    int y)
+{
+    SDL_Mouse *mouse = SDL_GetMouse(index);
+    int posted;
+    int xrel;
+    int yrel;
+
+    if (!mouse) {
+        return 0;
     }
 
-    /* Mouse coordinates range from 0 - width-1 and 0 - height-1 */
-    if (x < 0)
-        X = 0;
-    else if (x >= SDL_VideoSurface->w)
-        X = SDL_VideoSurface->w - 1;
-    else
-        X = (Uint16) x;
+    if (windowID) {
+        mouse->focus = windowID;
+    }
 
-    if (y < 0)
-        Y = 0;
-    else if (y >= SDL_VideoSurface->h)
-        Y = SDL_VideoSurface->h - 1;
-    else
-        Y = (Uint16) y;
-
-    /* If not relative mode, generate relative motion from clamped X/Y.
-       This prevents lots of extraneous large delta relative motion when
-       the screen is windowed mode and the mouse is outside the window.
-     */
-    if (!relative) {
-        Xrel = X - SDL_MouseX;
-        Yrel = Y - SDL_MouseY;
+    if (relative) {
+        /* Push the cursor around */
+        xrel = x;
+        yrel = y;
+        x = (mouse->x + xrel);
+        y = (mouse->y + yrel);
+    } else {
+        xrel = x - mouse->x;
+        yrel = y - mouse->y;
     }
 
     /* Drop events that don't change state */
-    if (!Xrel && !Yrel) {
+    if (!xrel && !yrel) {
 #if 0
         printf("Mouse event didn't change state - dropped!\n");
 #endif
-        return (0);
+        return 0;
     }
 
     /* Update internal mouse state */
-    SDL_ButtonState = buttonstate;
-    SDL_MouseX = X;
-    SDL_MouseY = Y;
-    SDL_DeltaX += Xrel;
-    SDL_DeltaY += Yrel;
-    SDL_MoveCursor(SDL_MouseX, SDL_MouseY);
+    mouse->xdelta += xrel;
+    mouse->ydelta += yrel;
 
     /* Post the event, if desired */
     posted = 0;
     if (SDL_ProcessEvents[SDL_MOUSEMOTION] == SDL_ENABLE) {
         SDL_Event event;
-        SDL_memset(&event, 0, sizeof(event));
-        event.type = SDL_MOUSEMOTION;
-        event.motion.state = buttonstate;
-        event.motion.x = X;
-        event.motion.y = Y;
-        event.motion.xrel = Xrel;
-        event.motion.yrel = Yrel;
+        event.motion.type = SDL_MOUSEMOTION;
+        event.motion.which = (Uint8) index;
+        event.motion.state = mouse->buttonstate;
+        event.motion.x = mouse->x;
+        event.motion.y = mouse->y;
+        event.motion.xrel = xrel;
+        event.motion.yrel = yrel;
+        event.motion.windowID = mouse->focus;
         if ((SDL_EventOK == NULL) || (*SDL_EventOK) (&event)) {
             posted = 1;
             SDL_PushEvent(&event);
         }
     }
-    return (posted);
+    return posted;
 }
 
 int
-SDL_PrivateMouseButton(Uint8 state, Uint8 button, Sint16 x, Sint16 y)
+SDL_PrivateMouseButton(int index, SDL_WindowID windowID, Uint8 state,
+                       Uint8 button)
 {
-    SDL_VideoDevice *_this = SDL_GetVideoDevice();
-    SDL_Event event;
+    SDL_Mouse *mouse = SDL_GetMouse(index);
     int posted;
-    int move_mouse;
-    Uint8 buttonstate;
-
-    SDL_memset(&event, 0, sizeof(event));
+    Uint8 type;
 
-    /* Check parameters */
-    if (x || y) {
-        ClipOffset(&x, &y);
-        move_mouse = 1;
-        /* Mouse coordinates range from 0 - width-1 and 0 - height-1 */
-        if (x < 0)
-            x = 0;
-        else if (x >= SDL_VideoSurface->w)
-            x = SDL_VideoSurface->w - 1;
+    if (!mouse) {
+        return 0;
+    }
 
-        if (y < 0)
-            y = 0;
-        else if (y >= SDL_VideoSurface->h)
-            y = SDL_VideoSurface->h - 1;
-    } else {
-        move_mouse = 0;
+    if (windowID) {
+        mouse->focus = windowID;
     }
-    if (!x)
-        x = SDL_MouseX;
-    if (!y)
-        y = SDL_MouseY;
 
     /* Figure out which event to perform */
-    buttonstate = SDL_ButtonState;
     switch (state) {
     case SDL_PRESSED:
-        event.type = SDL_MOUSEBUTTONDOWN;
-        buttonstate |= SDL_BUTTON(button);
+        if (mouse->buttonstate & SDL_BUTTON(button)) {
+            /* Ignore this event, no state change */
+            return 0;
+        }
+        type = SDL_MOUSEBUTTONDOWN;
+        mouse->buttonstate |= SDL_BUTTON(button);
         break;
     case SDL_RELEASED:
-        event.type = SDL_MOUSEBUTTONUP;
-        buttonstate &= ~SDL_BUTTON(button);
+        if (!(mouse->buttonstate & SDL_BUTTON(button))) {
+            /* Ignore this event, no state change */
+            return 0;
+        }
+        type = SDL_MOUSEBUTTONUP;
+        mouse->buttonstate &= ~SDL_BUTTON(button);
         break;
     default:
         /* Invalid state -- bail */
-        return (0);
-    }
-
-    /* Update internal mouse state */
-    SDL_ButtonState = buttonstate;
-    if (move_mouse) {
-        SDL_MouseX = x;
-        SDL_MouseY = y;
-        SDL_MoveCursor(SDL_MouseX, SDL_MouseY);
+        return 0;
     }
 
     /* Post the event, if desired */
     posted = 0;
-    if (SDL_ProcessEvents[event.type] == SDL_ENABLE) {
+    if (SDL_ProcessEvents[type] == SDL_ENABLE) {
+        SDL_Event event;
+        event.type = type;
+        event.button.which = (Uint8) index;
         event.button.state = state;
         event.button.button = button;
-        event.button.x = x;
-        event.button.y = y;
+        event.button.x = mouse->x;
+        event.button.y = mouse->y;
+        event.button.windowID = windowID;
         if ((SDL_EventOK == NULL) || (*SDL_EventOK) (&event)) {
             posted = 1;
             SDL_PushEvent(&event);
         }
     }
-    return (posted);
+    return posted;
 }
 
 /* vi: set ts=4 sw=4 expandtab: */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/events/SDL_mouse_c.h	Wed Jun 07 16:10:28 2006 +0000
@@ -0,0 +1,48 @@
+/*
+    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"
+
+#ifndef _SDL_mouse_c_h
+#define _SDL_mouse_c_h
+
+typedef struct
+{
+    SDL_WindowID focus;
+    int x;
+    int y;
+    int xdelta;
+    int ydelta;
+    Uint8 buttonstate;
+} SDL_Mouse;
+
+extern int SDL_MouseInit(void);
+extern int SDL_AddMouse(SDL_WindowID focus, int x, int y, Uint8 buttonstate);
+extern SDL_Mouse *SDL_GetMouse(int index);
+extern int SDL_SendMouseMotion(int index, SDL_WindowID windowID, int relative,
+                               int x, int y);
+extern int SDL_SendMouseButton(int index, SDL_WindowID windowID, Uint8 state,
+                               Uint8 button);
+extern void SDL_MouseQuit(void);
+
+#endif /* _SDL_mouse_c_h */
+
+/* vi: set ts=4 sw=4 expandtab: */
--- a/src/events/SDL_quit.c	Mon May 29 05:08:33 2006 +0000
+++ b/src/events/SDL_quit.c	Wed Jun 07 16:10:28 2006 +0000
@@ -39,7 +39,7 @@
     signal(sig, SDL_HandleSIG);
 
     /* Signal a quit interrupt */
-    SDL_PrivateQuit();
+    SDL_SendQuit();
 }
 #endif /* HAVE_SIGNAL_H */
 
@@ -80,7 +80,7 @@
 
 /* This function returns 1 if it's okay to close the application window */
 int
-SDL_PrivateQuit(void)
+SDL_SendQuit(void)
 {
     int posted;
 
--- a/src/video/SDL_blit.c	Mon May 29 05:08:33 2006 +0000
+++ b/src/video/SDL_blit.c	Wed Jun 07 16:10:28 2006 +0000
@@ -217,8 +217,6 @@
 int
 SDL_CalculateBlit(SDL_Surface * surface)
 {
-    SDL_VideoDevice *_this = SDL_GetVideoDevice();
-    const SDL_VideoInfo *info = SDL_GetVideoInfo();
     int blit_index;
 
     /* Clean everything out to start */
@@ -227,52 +225,6 @@
     }
     surface->map->sw_blit = NULL;
 
-    /* Figure out if an accelerated hardware blit is possible */
-    surface->flags &= ~SDL_HWACCEL;
-    if (surface->map->identity) {
-        int hw_blit_ok;
-
-        if ((surface->flags & SDL_HWSURFACE) == SDL_HWSURFACE) {
-            /* We only support accelerated blitting to hardware */
-            if (surface->map->dst->flags & SDL_HWSURFACE) {
-                hw_blit_ok = info->blit_hw;
-            } else {
-                hw_blit_ok = 0;
-            }
-            if (hw_blit_ok && (surface->flags & SDL_SRCCOLORKEY)) {
-                hw_blit_ok = info->blit_hw_CC;
-            }
-            if (hw_blit_ok && (surface->flags & SDL_SRCALPHA)) {
-                hw_blit_ok = info->blit_hw_A;
-            }
-        } else {
-            /* We only support accelerated blitting to hardware */
-            if (surface->map->dst->flags & SDL_HWSURFACE) {
-                hw_blit_ok = info->blit_sw;
-            } else {
-                hw_blit_ok = 0;
-            }
-            if (hw_blit_ok && (surface->flags & SDL_SRCCOLORKEY)) {
-                hw_blit_ok = info->blit_sw_CC;
-            }
-            if (hw_blit_ok && (surface->flags & SDL_SRCALPHA)) {
-                hw_blit_ok = info->blit_sw_A;
-            }
-        }
-        if (hw_blit_ok) {
-            _this->CheckHWBlit(_this, surface, surface->map->dst);
-        }
-    }
-
-    /* if an alpha pixel format is specified, we can accelerate alpha blits */
-    if (((surface->flags & SDL_HWSURFACE) == SDL_HWSURFACE)
-        && (_this->displayformatalphapixel)) {
-        if ((surface->flags & SDL_SRCALPHA))
-            if (info->blit_hw_A) {
-                _this->CheckHWBlit(_this, surface, surface->map->dst);
-            }
-    }
-
     /* Get the blit function index, based on surface mode */
     /* { 0 = nothing, 1 = colorkey, 2 = alpha, 3 = colorkey+alpha } */
     blit_index = 0;
@@ -321,9 +273,7 @@
     }
 
     /* Choose software blitting function */
-    if (surface->flags & SDL_RLEACCELOK
-        && (surface->flags & SDL_HWACCEL) != SDL_HWACCEL) {
-
+    if (surface->flags & SDL_RLEACCELOK) {
         if (surface->map->identity
             && (blit_index == 1
                 || (blit_index == 3 && !surface->format->Amask))) {
--- a/src/video/SDL_bmp.c	Mon May 29 05:08:33 2006 +0000
+++ b/src/video/SDL_bmp.c	Wed Jun 07 16:10:28 2006 +0000
@@ -203,9 +203,9 @@
     }
 
     /* Create a compatible surface, note that the colors are RGB ordered */
-    surface = SDL_CreateRGBSurface(SDL_SWSURFACE,
-                                   biWidth, biHeight, biBitCount, Rmask,
-                                   Gmask, Bmask, 0);
+    surface =
+        SDL_CreateRGBSurface(0, biWidth, biHeight, biBitCount, Rmask, Gmask,
+                             Bmask, 0);
     if (surface == NULL) {
         was_error = 1;
         goto done;
@@ -386,8 +386,7 @@
             SDL_Rect bounds;
 
             /* Convert to 24 bits per pixel */
-            surface = SDL_CreateRGBSurface(SDL_SWSURFACE,
-                                           saveme->w, saveme->h, 24,
+            surface = SDL_CreateRGBSurface(0, saveme->w, saveme->h, 24,
 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
                                            0x00FF0000, 0x0000FF00, 0x000000FF,
 #else
--- a/src/video/SDL_cursor.c	Mon May 29 05:08:33 2006 +0000
+++ b/src/video/SDL_cursor.c	Wed Jun 07 16:10:28 2006 +0000
@@ -23,22 +23,17 @@
 
 /* General cursor handling code for SDL */
 
-#include "SDL_mutex.h"
 #include "SDL_video.h"
 #include "SDL_mouse.h"
-#include "SDL_blit.h"
 #include "SDL_sysvideo.h"
 #include "SDL_cursor_c.h"
-#include "SDL_pixels_c.h"
 #include "default_cursor.h"
-#include "../events/SDL_sysevents.h"
-#include "../events/SDL_events_c.h"
 
 /* These are static for our cursor handling code */
+/* FIXME: Add support for multiple simultaneous cursors */
 volatile int SDL_cursorstate = CURSOR_VISIBLE;
 SDL_Cursor *SDL_cursor = NULL;
 static SDL_Cursor *SDL_defcursor = NULL;
-SDL_mutex *SDL_cursorlock = NULL;
 
 /* Public functions */
 void
@@ -58,13 +53,10 @@
             SDL_FreeCursor(cursor);
         }
     }
-    if (SDL_cursorlock != NULL) {
-        SDL_DestroyMutex(SDL_cursorlock);
-        SDL_cursorlock = NULL;
-    }
 }
+
 int
-SDL_CursorInit(Uint32 multithreaded)
+SDL_CursorInit(void)
 {
     /* We don't have mouse focus, and the cursor isn't drawn yet */
 #ifndef IPOD
@@ -79,43 +71,15 @@
         SDL_SetCursor(SDL_defcursor);
     }
 
-    /* Create a lock if necessary */
-    if (multithreaded) {
-        SDL_cursorlock = SDL_CreateMutex();
-    }
-
     /* That's it! */
     return (0);
 }
 
-/* Multi-thread support for cursors */
-#ifndef SDL_LockCursor
-void
-SDL_LockCursor(void)
-{
-    if (SDL_cursorlock) {
-        SDL_mutexP(SDL_cursorlock);
-    }
-}
-#endif
-#ifndef SDL_UnlockCursor
-void
-SDL_UnlockCursor(void)
-{
-    if (SDL_cursorlock) {
-        SDL_mutexV(SDL_cursorlock);
-    }
-}
-#endif
-
-/* Software cursor drawing support */
 SDL_Cursor *
 SDL_CreateCursor(Uint8 * data, Uint8 * mask,
                  int w, int h, int hot_x, int hot_y)
 {
     SDL_VideoDevice *_this = SDL_GetVideoDevice();
-    int savelen;
-    int i;
     SDL_Cursor *cursor;
 
     /* Make sure the width is a multiple of 8 */
@@ -127,41 +91,10 @@
         return (NULL);
     }
 
-    /* Allocate memory for the cursor */
-    cursor = (SDL_Cursor *) SDL_malloc(sizeof *cursor);
-    if (cursor == NULL) {
-        SDL_OutOfMemory();
-        return (NULL);
-    }
-    savelen = (w * 4) * h;
-    cursor->area.x = 0;
-    cursor->area.y = 0;
-    cursor->area.w = w;
-    cursor->area.h = h;
-    cursor->hot_x = hot_x;
-    cursor->hot_y = hot_y;
-    cursor->data = (Uint8 *) SDL_malloc((w / 8) * h * 2);
-    cursor->mask = cursor->data + ((w / 8) * h);
-    cursor->save[0] = (Uint8 *) SDL_malloc(savelen * 2);
-    cursor->save[1] = cursor->save[0] + savelen;
-    cursor->wm_cursor = NULL;
-    if (!cursor->data || !cursor->save[0]) {
-        SDL_FreeCursor(cursor);
-        SDL_OutOfMemory();
-        return (NULL);
-    }
-    for (i = ((w / 8) * h) - 1; i >= 0; --i) {
-        cursor->data[i] = data[i];
-        cursor->mask[i] = mask[i] | data[i];
-    }
-    SDL_memset(cursor->save[0], 0, savelen * 2);
-
-    /* If the window manager gives us a good cursor, we're done! */
     if (_this->CreateWMCursor) {
-        cursor->wm_cursor = _this->CreateWMCursor(_this, data, mask,
-                                                  w, h, hot_x, hot_y);
+        cursor = _this->CreateWMCursor(_this, data, mask, w, h, hot_x, hot_y);
     } else {
-        cursor->wm_cursor = NULL;
+        cursor = NULL;
     }
     return (cursor);
 }
@@ -180,56 +113,22 @@
         return;
     }
 
-    /* Prevent the event thread from moving the mouse */
-    SDL_LockCursor();
-
     /* Set the new cursor */
     if (cursor && (cursor != SDL_cursor)) {
-        /* Erase the current mouse position */
-        if (SHOULD_DRAWCURSOR(SDL_cursorstate)) {
-            SDL_EraseCursor(SDL_VideoSurface);
-        } else if (_this->MoveWMCursor) {
-            /* If the video driver is moving the cursor directly,
-               it needs to hide the old cursor before (possibly)
-               showing the new one.  (But don't erase NULL cursor)
-             */
-            if (SDL_cursor) {
-                _this->ShowWMCursor(_this, NULL);
-            }
-        }
         SDL_cursor = cursor;
     }
 
     /* Draw the new mouse cursor */
     if (SDL_cursor && (SDL_cursorstate & CURSOR_VISIBLE)) {
-        /* Use window manager cursor if possible */
-        if (SDL_cursor->wm_cursor &&
-            _this->ShowWMCursor(_this, SDL_cursor->wm_cursor)) {
-            SDL_cursorstate &= ~CURSOR_USINGSW;
-        } else {
-            SDL_cursorstate |= CURSOR_USINGSW;
-            if (_this->ShowWMCursor) {
-                _this->ShowWMCursor(_this, NULL);
-            }
-            {
-                int x, y;
-                SDL_GetMouseState(&x, &y);
-                SDL_cursor->area.x = (x - SDL_cursor->hot_x);
-                SDL_cursor->area.y = (y - SDL_cursor->hot_y);
-            }
-            SDL_DrawCursor(SDL_VideoSurface);
+        if (_this->ShowWMCursor) {
+            _this->ShowWMCursor(_this, SDL_cursor);
         }
     } else {
         /* Erase window manager mouse (cursor not visible) */
-        if (SDL_cursor && (SDL_cursorstate & CURSOR_USINGSW)) {
-            SDL_EraseCursor(SDL_VideoSurface);
-        } else {
-            if (_this) {
-                _this->ShowWMCursor(_this, NULL);
-            }
+        if (_this->ShowWMCursor) {
+            _this->ShowWMCursor(_this, NULL);
         }
     }
-    SDL_UnlockCursor();
 }
 
 SDL_Cursor *
@@ -248,16 +147,9 @@
         if (cursor != SDL_defcursor) {
             SDL_VideoDevice *_this = SDL_GetVideoDevice();
 
-            if (cursor->data) {
-                SDL_free(cursor->data);
+            if (_this && _this->FreeWMCursor) {
+                _this->FreeWMCursor(_this, cursor);
             }
-            if (cursor->save[0]) {
-                SDL_free(cursor->save[0]);
-            }
-            if (_this && cursor->wm_cursor) {
-                _this->FreeWMCursor(_this, cursor->wm_cursor);
-            }
-            SDL_free(cursor);
         }
     }
 }
@@ -269,13 +161,11 @@
 
     showing = (SDL_cursorstate & CURSOR_VISIBLE);
     if (toggle >= 0) {
-        SDL_LockCursor();
         if (toggle) {
             SDL_cursorstate |= CURSOR_VISIBLE;
         } else {
             SDL_cursorstate &= ~CURSOR_VISIBLE;
         }
-        SDL_UnlockCursor();
         if ((SDL_cursorstate & CURSOR_VISIBLE) != showing) {
             SDL_VideoDevice *_this = SDL_GetVideoDevice();
 
@@ -291,509 +181,23 @@
 }
 
 void
-SDL_WarpMouse(Uint16 x, Uint16 y)
+SDL_WarpMouseInWindow(SDL_WindowID windowID, int x, int y)
 {
     SDL_VideoDevice *_this = SDL_GetVideoDevice();
 
-    if (!_this || !SDL_PublicSurface) {
-        SDL_SetError("A video mode must be set before warping mouse");
+    /* FIXME: This should specify the target window */
+    if (!_this || !SDL_CurrentDisplay.num_windows) {
+        SDL_SetError("A window must be created before warping mouse");
         return;
     }
 
-    /* If we have an offset video mode, offset the mouse coordinates */
-    if (SDL_VideoSurface->pitch == 0) {
-        x += SDL_VideoSurface->offset /
-            SDL_VideoSurface->format->BytesPerPixel;
-        y += SDL_VideoSurface->offset;
-    } else {
-        x += (SDL_VideoSurface->offset % SDL_VideoSurface->pitch) /
-            SDL_VideoSurface->format->BytesPerPixel;
-        y += (SDL_VideoSurface->offset / SDL_VideoSurface->pitch);
+    if (!windowID) {
+        windowID = SDL_CurrentWindow;
     }
 
     /* This generates a mouse motion event */
     if (_this->WarpWMCursor) {
-        _this->WarpWMCursor(_this, x, y);
-    } else {
-        SDL_PrivateMouseMotion(0, 0, x, y);
-    }
-}
-
-void
-SDL_MoveCursor(int x, int y)
-{
-    SDL_VideoDevice *_this = SDL_GetVideoDevice();
-
-    /* Erase and update the current mouse position */
-    if (SHOULD_DRAWCURSOR(SDL_cursorstate)) {
-        /* Erase and redraw mouse cursor in new position */
-        SDL_LockCursor();
-        SDL_EraseCursor(SDL_VideoSurface);
-        SDL_cursor->area.x = (x - SDL_cursor->hot_x);
-        SDL_cursor->area.y = (y - SDL_cursor->hot_y);
-        SDL_DrawCursor(SDL_VideoSurface);
-        SDL_UnlockCursor();
-    } else if (_this->MoveWMCursor) {
-        _this->MoveWMCursor(_this, x, y);
-    }
-}
-
-/* Keep track of the current cursor colors */
-static int palette_changed = 1;
-static Uint8 pixels8[2];
-
-void
-SDL_CursorPaletteChanged(void)
-{
-    palette_changed = 1;
-}
-
-void
-SDL_MouseRect(SDL_Rect * area)
-{
-    SDL_VideoDevice *_this = SDL_GetVideoDevice();
-    int clip_diff;
-
-    *area = SDL_cursor->area;
-    if (area->x < 0) {
-        area->w += area->x;
-        area->x = 0;
-    }
-    if (area->y < 0) {
-        area->h += area->y;
-        area->y = 0;
-    }
-    clip_diff = (area->x + area->w) - SDL_VideoSurface->w;
-    if (clip_diff > 0) {
-        area->w = area->w < clip_diff ? 0 : area->w - clip_diff;
-    }
-    clip_diff = (area->y + area->h) - SDL_VideoSurface->h;
-    if (clip_diff > 0) {
-        area->h = area->h < clip_diff ? 0 : area->h - clip_diff;
-    }
-}
-
-static void
-SDL_DrawCursorFast(SDL_Surface * screen, SDL_Rect * area)
-{
-    const Uint32 pixels[2] = { 0xFFFFFFFF, 0x00000000 };
-    int i, w, h;
-    Uint8 *data, datab;
-    Uint8 *mask, maskb;
-
-    data = SDL_cursor->data + area->y * SDL_cursor->area.w / 8;
-    mask = SDL_cursor->mask + area->y * SDL_cursor->area.w / 8;
-    switch (screen->format->BytesPerPixel) {
-
-    case 1:
-        {
-            Uint8 *dst;
-            int dstskip;
-
-            if (palette_changed) {
-                pixels8[0] =
-                    (Uint8) SDL_MapRGB(screen->format, 255, 255, 255);
-                pixels8[1] = (Uint8) SDL_MapRGB(screen->format, 0, 0, 0);
-                palette_changed = 0;
-            }
-            dst = (Uint8 *) screen->pixels +
-                (SDL_cursor->area.y + area->y) * screen->pitch +
-                SDL_cursor->area.x;
-            dstskip = screen->pitch - area->w;
-
-            for (h = area->h; h; h--) {
-                for (w = area->w / 8; w; w--) {
-                    maskb = *mask++;
-                    datab = *data++;
-                    for (i = 0; i < 8; ++i) {
-                        if (maskb & 0x80) {
-                            *dst = pixels8[datab >> 7];
-                        }
-                        maskb <<= 1;
-                        datab <<= 1;
-                        dst++;
-                    }
-                }
-                dst += dstskip;
-            }
-        }
-        break;
-
-    case 2:
-        {
-            Uint16 *dst;
-            int dstskip;
-
-            dst = (Uint16 *) screen->pixels +
-                (SDL_cursor->area.y + area->y) * screen->pitch / 2 +
-                SDL_cursor->area.x;
-            dstskip = (screen->pitch / 2) - area->w;
-
-            for (h = area->h; h; h--) {
-                for (w = area->w / 8; w; w--) {
-                    maskb = *mask++;
-                    datab = *data++;
-                    for (i = 0; i < 8; ++i) {
-                        if (maskb & 0x80) {
-                            *dst = (Uint16) pixels[datab >> 7];
-                        }
-                        maskb <<= 1;
-                        datab <<= 1;
-                        dst++;
-                    }
-                }
-                dst += dstskip;
-            }
-        }
-        break;
-
-    case 3:
-        {
-            Uint8 *dst;
-            int dstskip;
-
-            dst = (Uint8 *) screen->pixels +
-                (SDL_cursor->area.y + area->y) * screen->pitch +
-                SDL_cursor->area.x * 3;
-            dstskip = screen->pitch - area->w * 3;
-
-            for (h = area->h; h; h--) {
-                for (w = area->w / 8; w; w--) {
-                    maskb = *mask++;
-                    datab = *data++;
-                    for (i = 0; i < 8; ++i) {
-                        if (maskb & 0x80) {
-                            SDL_memset(dst, pixels[datab >> 7], 3);
-                        }
-                        maskb <<= 1;
-                        datab <<= 1;
-                        dst += 3;
-                    }
-                }
-                dst += dstskip;
-            }
-        }
-        break;
-
-    case 4:
-        {
-            Uint32 *dst;
-            int dstskip;
-
-            dst = (Uint32 *) screen->pixels +
-                (SDL_cursor->area.y + area->y) * screen->pitch / 4 +
-                SDL_cursor->area.x;
-            dstskip = (screen->pitch / 4) - area->w;
-
-            for (h = area->h; h; h--) {
-                for (w = area->w / 8; w; w--) {
-                    maskb = *mask++;
-                    datab = *data++;
-                    for (i = 0; i < 8; ++i) {
-                        if (maskb & 0x80) {
-                            *dst = pixels[datab >> 7];
-                        }
-                        maskb <<= 1;
-                        datab <<= 1;
-                        dst++;
-                    }
-                }
-                dst += dstskip;
-            }
-        }
-        break;
-    }
-}
-
-static void
-SDL_DrawCursorSlow(SDL_Surface * screen, SDL_Rect * area)
-{
-    const Uint32 pixels[2] = { 0xFFFFFF, 0x000000 };
-    int h;
-    int x, minx, maxx;
-    Uint8 *data, datab = 0;
-    Uint8 *mask, maskb = 0;
-    Uint8 *dst;
-    int dstbpp, dstskip;
-
-    data = SDL_cursor->data + area->y * SDL_cursor->area.w / 8;
-    mask = SDL_cursor->mask + area->y * SDL_cursor->area.w / 8;
-    dstbpp = screen->format->BytesPerPixel;
-    dst = (Uint8 *) screen->pixels +
-        (SDL_cursor->area.y + area->y) * screen->pitch +
-        SDL_cursor->area.x * dstbpp;
-    dstskip = screen->pitch - SDL_cursor->area.w * dstbpp;
-
-    minx = area->x;
-    maxx = area->x + area->w;
-    if (screen->format->BytesPerPixel == 1) {
-        if (palette_changed) {
-            pixels8[0] = (Uint8) SDL_MapRGB(screen->format, 255, 255, 255);
-            pixels8[1] = (Uint8) SDL_MapRGB(screen->format, 0, 0, 0);
-            palette_changed = 0;
-        }
-        for (h = area->h; h; h--) {
-            for (x = 0; x < SDL_cursor->area.w; ++x) {
-                if ((x % 8) == 0) {
-                    maskb = *mask++;
-                    datab = *data++;
-                }
-                if ((x >= minx) && (x < maxx)) {
-                    if (maskb & 0x80) {
-                        SDL_memset(dst, pixels8[datab >> 7], dstbpp);
-                    }
-                }
-                maskb <<= 1;
-                datab <<= 1;
-                dst += dstbpp;
-            }
-            dst += dstskip;
-        }
-    } else {
-        for (h = area->h; h; h--) {
-            for (x = 0; x < SDL_cursor->area.w; ++x) {
-                if ((x % 8) == 0) {
-                    maskb = *mask++;
-                    datab = *data++;
-                }
-                if ((x >= minx) && (x < maxx)) {
-                    if (maskb & 0x80) {
-                        SDL_memset(dst, pixels[datab >> 7], dstbpp);
-                    }
-                }
-                maskb <<= 1;
-                datab <<= 1;
-                dst += dstbpp;
-            }
-            dst += dstskip;
-        }
-    }
-}
-
-/* This handles the ugly work of converting the saved cursor background from
-   the pixel format of the shadow surface to that of the video surface.
-   This is only necessary when blitting from a shadow surface of a different
-   pixel format than the video surface, and using a software rendered cursor.
-*/
-static void
-SDL_ConvertCursorSave(SDL_Surface * screen, int w, int h)
-{
-    SDL_VideoDevice *_this = SDL_GetVideoDevice();
-    SDL_BlitInfo info;
-    SDL_loblit RunBlit;
-
-    /* Make sure we can steal the blit mapping */
-    if (screen->map->dst != SDL_VideoSurface) {
-        return;
-    }
-
-    /* Set up the blit information */
-    info.s_pixels = SDL_cursor->save[1];
-    info.s_width = w;
-    info.s_height = h;
-    info.s_skip = 0;
-    info.d_pixels = SDL_cursor->save[0];
-    info.d_width = w;
-    info.d_height = h;
-    info.d_skip = 0;
-    info.aux_data = screen->map->sw_data->aux_data;
-    info.src = screen->format;
-    info.table = screen->map->table;
-    info.dst = SDL_VideoSurface->format;
-    RunBlit = screen->map->sw_data->blit;
-
-    /* Run the actual software blit */
-    RunBlit(&info);
-}
-
-void
-SDL_DrawCursorNoLock(SDL_Surface * screen)
-{
-    SDL_VideoDevice *_this = SDL_GetVideoDevice();
-    SDL_Rect area;
-
-    /* Get the mouse rectangle, clipped to the screen */
-    SDL_MouseRect(&area);
-    if ((area.w == 0) || (area.h == 0)) {
-        return;
-    }
-
-    /* Copy mouse background */
-    {
-        int w, h, screenbpp;
-        Uint8 *src, *dst;
-
-        /* Set up the copy pointers */
-        screenbpp = screen->format->BytesPerPixel;
-        if ((screen == SDL_VideoSurface) ||
-            FORMAT_EQUAL(screen->format, SDL_VideoSurface->format)) {
-            dst = SDL_cursor->save[0];
-        } else {
-            dst = SDL_cursor->save[1];
-        }
-        src = (Uint8 *) screen->pixels + area.y * screen->pitch +
-            area.x * screenbpp;
-
-        /* Perform the copy */
-        w = area.w * screenbpp;
-        h = area.h;
-        while (h--) {
-            SDL_memcpy(dst, src, w);
-            dst += w;
-            src += screen->pitch;
-        }
-    }
-
-    /* Draw the mouse cursor */
-    area.x -= SDL_cursor->area.x;
-    area.y -= SDL_cursor->area.y;
-    if ((area.x == 0) && (area.w == SDL_cursor->area.w)) {
-        SDL_DrawCursorFast(screen, &area);
-    } else {
-        SDL_DrawCursorSlow(screen, &area);
-    }
-}
-
-void
-SDL_DrawCursor(SDL_Surface * screen)
-{
-    /* Lock the screen if necessary */
-    if (screen == NULL) {
-        return;
-    }
-    if (SDL_MUSTLOCK(screen)) {
-        if (SDL_LockSurface(screen) < 0) {
-            return;
-        }
-    }
-
-    SDL_DrawCursorNoLock(screen);
-
-    /* Unlock the screen and update if necessary */
-    if (SDL_MUSTLOCK(screen)) {
-        SDL_UnlockSurface(screen);
-    }
-    if ((screen->flags & SDL_SCREEN_SURFACE) &&
-        !(screen->flags & SDL_HWSURFACE)) {
-        SDL_VideoDevice *_this = SDL_GetVideoDevice();
-        SDL_Window *window;
-        SDL_Rect area;
-
-        window = SDL_GetWindowFromSurface(screen);
-        if (!window) {
-            return;
-        }
-
-        SDL_MouseRect(&area);
-
-        if (_this->UpdateWindowSurface) {
-            _this->UpdateWindowSurface(_this, window, 1, &area);
-        }
-    }
-}
-
-void
-SDL_EraseCursorNoLock(SDL_Surface * screen)
-{
-    SDL_VideoDevice *_this = SDL_GetVideoDevice();
-    SDL_Window *window;
-    SDL_Rect area;
-
-    /* Get the window associated with the surface */
-    window = SDL_GetWindowFromSurface(screen);
-    if (!window || !window->surface) {
-        return;
-    }
-
-    /* Get the mouse rectangle, clipped to the screen */
-    SDL_MouseRect(&area);
-    if ((area.w == 0) || (area.h == 0)) {
-        return;
-    }
-
-    /* Copy mouse background */
-    {
-        int w, h, screenbpp;
-        Uint8 *src, *dst;
-
-        /* Set up the copy pointers */
-        screenbpp = screen->format->BytesPerPixel;
-        if ((screen->flags & SDL_SCREEN_SURFACE) ||
-            FORMAT_EQUAL(screen->format, window->surface->format)) {
-            src = SDL_cursor->save[0];
-        } else {
-            src = SDL_cursor->save[1];
-        }
-        dst = (Uint8 *) screen->pixels + area.y * screen->pitch +
-            area.x * screenbpp;
-
-        /* Perform the copy */
-        w = area.w * screenbpp;
-        h = area.h;
-        while (h--) {
-            SDL_memcpy(dst, src, w);
-            src += w;
-            dst += screen->pitch;
-        }
-
-        /* Perform pixel conversion on cursor background */
-        if (src > SDL_cursor->save[1]) {
-            SDL_ConvertCursorSave(screen, area.w, area.h);
-        }
-    }
-}
-
-void
-SDL_EraseCursor(SDL_Surface * screen)
-{
-    /* Lock the screen if necessary */
-    if (screen == NULL) {
-        return;
-    }
-    if (SDL_MUSTLOCK(screen)) {
-        if (SDL_LockSurface(screen) < 0) {
-            return;
-        }
-    }
-
-    SDL_EraseCursorNoLock(screen);
-
-    /* Unlock the screen and update if necessary */
-    if (SDL_MUSTLOCK(screen)) {
-        SDL_UnlockSurface(screen);
-    }
-    if ((screen->flags & SDL_SCREEN_SURFACE) &&
-        !(screen->flags & SDL_HWSURFACE)) {
-        SDL_VideoDevice *_this = SDL_GetVideoDevice();
-        SDL_Window *window;
-        SDL_Rect area;
-
-        window = SDL_GetWindowFromSurface(screen);
-        if (!window) {
-            return;
-        }
-
-        SDL_MouseRect(&area);
-
-        if (_this->UpdateWindowSurface) {
-            _this->UpdateWindowSurface(_this, window, 1, &area);
-        }
-    }
-}
-
-/* Reset the cursor on video mode change
-   FIXME:  Keep track of all cursors, and reset them all.
- */
-void
-SDL_ResetCursor(void)
-{
-    int savelen;
-
-    if (SDL_cursor) {
-        savelen = SDL_cursor->area.w * 4 * SDL_cursor->area.h;
-        SDL_cursor->area.x = 0;
-        SDL_cursor->area.y = 0;
-        SDL_memset(SDL_cursor->save[0], 0, savelen);
+        _this->WarpWMCursor(_this, windowID, x, y);
     }
 }
 
--- a/src/video/SDL_cursor_c.h	Mon May 29 05:08:33 2006 +0000
+++ b/src/video/SDL_cursor_c.h	Wed Jun 07 16:10:28 2006 +0000
@@ -24,51 +24,12 @@
 /* Useful variables and functions from SDL_cursor.c */
 #include "SDL_mouse.h"
 
-extern int SDL_CursorInit(Uint32 flags);
-extern void SDL_CursorPaletteChanged(void);
-extern void SDL_DrawCursor(SDL_Surface * screen);
-extern void SDL_DrawCursorNoLock(SDL_Surface * screen);
-extern void SDL_EraseCursor(SDL_Surface * screen);
-extern void SDL_EraseCursorNoLock(SDL_Surface * screen);
-extern void SDL_UpdateCursor(SDL_Surface * screen);
-extern void SDL_ResetCursor(void);
-extern void SDL_MoveCursor(int x, int y);
+extern int SDL_CursorInit(void);
 extern void SDL_CursorQuit(void);
 
-#define INLINE_MOUSELOCK
-#ifdef INLINE_MOUSELOCK
-/* Inline (macro) versions of the mouse lock functions */
-#include "SDL_mutex.h"
-
-extern SDL_mutex *SDL_cursorlock;
-
-#define SDL_LockCursor()						\
-	do {								\
-		if ( SDL_cursorlock ) {					\
-			SDL_mutexP(SDL_cursorlock);			\
-		}							\
-	} while ( 0 )
-#define SDL_UnlockCursor()						\
-	do {								\
-		if ( SDL_cursorlock ) {					\
-			SDL_mutexV(SDL_cursorlock);			\
-		}							\
-	} while ( 0 )
-#else
-extern void SDL_LockCursor(void);
-extern void SDL_UnlockCursor(void);
-#endif /* INLINE_MOUSELOCK */
-
-/* Only for low-level mouse cursor drawing */
-extern SDL_Cursor *SDL_cursor;
-extern void SDL_MouseRect(SDL_Rect * area);
-
 /* State definitions for the SDL cursor */
 #define CURSOR_VISIBLE	0x01
-#define CURSOR_USINGSW	0x10
-#define SHOULD_DRAWCURSOR(X) 						\
-			(((X)&(CURSOR_VISIBLE|CURSOR_USINGSW)) ==  	\
-					(CURSOR_VISIBLE|CURSOR_USINGSW))
 
 extern volatile int SDL_cursorstate;
+
 /* vi: set ts=4 sw=4 expandtab: */
--- a/src/video/SDL_pixels.c	Mon May 29 05:08:33 2006 +0000
+++ b/src/video/SDL_pixels.c	Wed Jun 07 16:10:28 2006 +0000
@@ -480,10 +480,10 @@
 /* 
  * Calculate the pad-aligned scanline width of a surface
  */
-Uint16
+int
 SDL_CalculatePitch(SDL_Surface * surface)
 {
-    Uint16 pitch;
+    int pitch;
 
     /* Surface should be 4-byte aligned for speed */
     pitch = surface->w * surface->format->BytesPerPixel;
--- a/src/video/SDL_pixels_c.h	Mon May 29 05:08:33 2006 +0000
+++ b/src/video/SDL_pixels_c.h	Wed Jun 07 16:10:28 2006 +0000
@@ -42,7 +42,7 @@
 extern void SDL_FreeBlitMap(SDL_BlitMap * map);
 
 /* Miscellaneous functions */
-extern Uint16 SDL_CalculatePitch(SDL_Surface * surface);
+extern int SDL_CalculatePitch(SDL_Surface * surface);
 extern void SDL_DitherColors(SDL_Color * colors, int bpp);
 extern Uint8 SDL_FindColor(SDL_Palette * pal, Uint8 r, Uint8 g, Uint8 b);
 extern void SDL_ApplyGamma(Uint16 * gamma, SDL_Color * colors,
--- a/src/video/SDL_surface.c	Mon May 29 05:08:33 2006 +0000
+++ b/src/video/SDL_surface.c	Wed Jun 07 16:10:28 2006 +0000
@@ -43,6 +43,7 @@
     SDL_Surface *screen;
     SDL_Surface *surface;
 
+    /* FIXME!! */
     /* Make sure the size requested doesn't overflow our datatypes */
     /* Next time I write a library like SDL, I'll use int for size. :) */
     if (width >= 16384 || height >= 65536) {
@@ -50,52 +51,13 @@
         return (NULL);
     }
 
-    /* Check to see if we desire the surface in video memory */
-    if (_this) {
-        screen = SDL_PublicSurface;
-    } else {
-        screen = NULL;
-    }
-    if (screen && ((screen->flags & SDL_HWSURFACE) == SDL_HWSURFACE)) {
-        if ((flags & (SDL_SRCCOLORKEY | SDL_SRCALPHA)) != 0) {
-            flags |= SDL_HWSURFACE;
-        }
-        if ((flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) {
-            if (!_this->info.blit_hw_CC) {
-                flags &= ~SDL_HWSURFACE;
-            }
-        }
-        if ((flags & SDL_SRCALPHA) == SDL_SRCALPHA) {
-            if (!_this->info.blit_hw_A) {
-                flags &= ~SDL_HWSURFACE;
-            }
-        }
-    } else {
-        flags &= ~SDL_HWSURFACE;
-    }
-
     /* Allocate the surface */
     surface = (SDL_Surface *) SDL_malloc(sizeof(*surface));
     if (surface == NULL) {
         SDL_OutOfMemory();
         return (NULL);
     }
-    surface->flags = SDL_SWSURFACE;
-    if ((flags & SDL_HWSURFACE) == SDL_HWSURFACE) {
-        if ((Amask) && (_this->displayformatalphapixel)) {
-            depth = _this->displayformatalphapixel->BitsPerPixel;
-            Rmask = _this->displayformatalphapixel->Rmask;
-            Gmask = _this->displayformatalphapixel->Gmask;
-            Bmask = _this->displayformatalphapixel->Bmask;
-            Amask = _this->displayformatalphapixel->Amask;
-        } else {
-            depth = screen->format->BitsPerPixel;
-            Rmask = screen->format->Rmask;
-            Gmask = screen->format->Gmask;
-            Bmask = screen->format->Bmask;
-            Amask = screen->format->Amask;
-        }
-    }
+    surface->flags = 0;
     surface->format = SDL_AllocFormat(depth, Rmask, Gmask, Bmask, Amask);
     if (surface->format == NULL) {
         SDL_free(surface);
@@ -108,27 +70,22 @@
     surface->h = height;
     surface->pitch = SDL_CalculatePitch(surface);
     surface->pixels = NULL;
-    surface->offset = 0;
     surface->hwdata = NULL;
     surface->locked = 0;
     surface->map = NULL;
-    surface->unused1 = 0;
     SDL_SetClipRect(surface, NULL);
     SDL_FormatChanged(surface);
 
     /* Get the pixels */
-    if (((flags & SDL_HWSURFACE) == SDL_SWSURFACE) ||
-        (_this->AllocHWSurface(_this, surface) < 0)) {
-        if (surface->w && surface->h) {
-            surface->pixels = SDL_malloc(surface->h * surface->pitch);
-            if (surface->pixels == NULL) {
-                SDL_FreeSurface(surface);
-                SDL_OutOfMemory();
-                return (NULL);
-            }
-            /* This is important for bitmaps */
-            SDL_memset(surface->pixels, 0, surface->h * surface->pitch);
+    if (surface->w && surface->h) {
+        surface->pixels = SDL_malloc(surface->h * surface->pitch);
+        if (surface->pixels == NULL) {
+            SDL_FreeSurface(surface);
+            SDL_OutOfMemory();
+            return NULL;
         }
+        /* This is important for bitmaps */
+        SDL_memset(surface->pixels, 0, surface->h * surface->pitch);
     }
 
     /* Allocate an empty mapping */
@@ -167,7 +124,72 @@
         surface->pitch = pitch;
         SDL_SetClipRect(surface, NULL);
     }
-    return (surface);
+    return surface;
+}
+
+SDL_Surface *
+SDL_CreateRGBSurfaceFromTexture(SDL_TextureID textureID)
+{
+    SDL_Surface *surface;
+    Uint32 format;
+    int w, h;
+    int bpp;
+    Uint32 Rmask, Gmask, Bmask, Amask;
+
+    if (SDL_QueryTexture(textureID, &format, NULL, &w, &h) < 0) {
+        return NULL;
+    }
+
+    if (!SDL_PixelFormatEnumToMasks
+        (format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) {
+        SDL_SetError("Unknown texture format");
+        return NULL;
+    }
+
+    surface = SDL_CreateRGBSurface(SDL_SWSURFACE, 0, 0, bpp,
+                                   Rmask, Gmask, Bmask, Amask);
+    if (surface != NULL) {
+        surface->flags |= (SDL_HWSURFACE | SDL_PREALLOC);
+        surface->w = width;
+        surface->h = height;
+        SDL_SetClipRect(surface, NULL);
+    }
+    return surface;
+}
+
+/*
+ * Set the palette in a blittable surface
+ */
+int
+SDL_SetColors(SDL_Surface * surface, SDL_Color * colors, int firstcolor,
+              int ncolors)
+{
+    SDL_Palette *pal;
+    int gotall;
+    int palsize;
+
+    /* Verify the parameters */
+    pal = surface->format->palette;
+    if (!pal) {
+        return 0;               /* not a palettized surface */
+    }
+    gotall = 1;
+    palsize = 1 << surface->format->BitsPerPixel;
+    if (ncolors > (palsize - firstcolor)) {
+        ncolors = (palsize - firstcolor);
+        gotall = 0;
+    }
+
+    if (colors != (pal->colors + firstcolor)) {
+        SDL_memcpy(pal->colors + firstcolor, colors,
+                   ncolors * sizeof(*colors));
+    }
+    SDL_FormatChanged(surface);
+
+    if (surface->flags & (SDL_SHADOW_SURFACE | SDL_SCREEN_SURFACE)) {
+        gotall &= SDL_SetScreenColors(surface, colors, firstcolor, ncolors);
+    }
+    return gotall;
 }
 
 /*
--- a/src/video/SDL_sysvideo.h	Mon May 29 05:08:33 2006 +0000
+++ b/src/video/SDL_sysvideo.h	Wed Jun 07 16:10:28 2006 +0000
@@ -39,9 +39,71 @@
 
 /* The SDL video driver */
 
+typedef struct SDL_Window SDL_Window;
+typedef struct SDL_Texture SDL_Texture;
+typedef struct SDL_Renderer SDL_Renderer;
+typedef struct SDL_RenderDriver SDL_RenderDriver;
+typedef struct SDL_VideoDisplay SDL_VideoDisplay;
+typedef struct SDL_VideoDevice SDL_VideoDevice;
+
+/* Define the SDL texture structure */
+struct SDL_Texture
+{
+    Uint32 id;
+
+    Uint32 format;      /**< The pixel format of the texture */
+    int access;         /**< SDL_TextureAccess */
+    int w;              /**< The width of the texture */
+    int h;              /**< The height of the texture */
+
+    SDL_Renderer *renderer;
+
+    void *driverdata;   /**< Driver specific texture representation */
+
+    SDL_Texture *next;
+};
+
+/* Define the SDL renderer structure */
+struct SDL_Renderer
+{
+    int (*CreateTexture) (SDL_Texture * texture);
+    int (*UpdateTexture) (SDL_Texture * texture, SDL_Rect * rect,
+                          const void *pixels, int pitch);
+    int (*LockTexture) (SDL_Texture * texture, SDL_Rect * rect, int markDirty,
+                        void **pixels, int *pitch);
+    void (*UnlockTexture) (SDL_Texture * texture);
+    void (*DirtyTexture) (SDL_Texture * texture, int numrects,
+                          SDL_Rect * rects);
+    void (*SelectRenderTexture) (SDL_Texture * texture);
+    void (*RenderFill) (SDL_Rect * rect, Uint32 color);
+    int (*RenderCopy) (SDL_Texture * texture, SDL_Rect * srcrect,
+                       SDL_Rect * dstrect, int blendMode, int scaleMode);
+    int (*RenderReadPixels) (SDL_Rect * rect, void *pixels, int pitch);
+    int (*RenderWritePixels) (SDL_Rect * rect, const void *pixels, int pitch);
+    void (*RenderPresent) (void);
+    void (*DestroyTexture) (SDL_Texture * texture);
+
+    void (*DestroyRenderer) (SDL_Renderer * renderer);
+
+    /* The current renderer info */
+    SDL_RendererInfo info;
+
+    /* The window associated with the renderer */
+    SDL_Window *window;
+
+    void *driverdata;
+};
+
+/* Define the SDL render driver structure */
+struct SDL_RenderDriver
+{
+    SDL_Renderer *(*CreateRenderer) (SDL_Window * window, Uint32 flags);
+
+    /* Info about the renderer capabilities */
+    SDL_RendererInfo info;
+};
+
 /* Define the SDL window structure, corresponding to toplevel windows */
-typedef struct SDL_Window SDL_Window;
-
 struct SDL_Window
 {
     Uint32 id;
@@ -51,10 +113,10 @@
     int w, h;
     Uint32 flags;
 
-    SDL_Surface *surface;
-    SDL_Surface *shadow;
     Uint16 *gamma;
 
+    SDL_Renderer *renderer;
+
     void *userdata;
     void *driverdata;
 };
@@ -62,21 +124,26 @@
 /* Define the SDL display structure
    This corresponds to physical monitors attached to the system.
  */
-typedef struct SDL_VideoDisplay
+struct SDL_VideoDisplay
 {
     int num_display_modes;
     SDL_DisplayMode *display_modes;
     SDL_DisplayMode desktop_mode;
     SDL_DisplayMode current_mode;
 
-    int max_windows;
+    int num_render_drivers;
+    SDL_RenderDriver *render_drivers;
+
     int num_windows;
     SDL_Window *windows;
 
+    SDL_Renderer *current_renderer;
+
+    /* The hash list of textures */
+    SDL_Texture *textures[64];
+
     void *driverdata;
-} SDL_VideoDisplay;
-
-typedef struct SDL_VideoDevice SDL_VideoDevice;
+};
 
 /* Define the SDL video driver structure */
 #define _THIS	SDL_VideoDevice *_this
@@ -105,6 +172,13 @@
      */
     int (*SetDisplayMode) (_THIS, const SDL_DisplayMode * mode);
 
+    /* Sets the color entries { firstcolor .. (firstcolor+ncolors-1) }
+       of the physical palette to those in 'colors'.  The return value
+       is 0 if all entries could be set properly or -1 otherwise.
+     */
+    int (*SetDisplayColors) (_THIS, int firstcolor, int ncolors,
+                             SDL_Color * colors);
+
     /* * * */
     /* Window functions
      */
@@ -122,22 +196,6 @@
     void (*SetWindowGrab) (_THIS, SDL_Window * window);
     void (*DestroyWindow) (_THIS, SDL_Window * window);
 
-    void (*CreateWindowSurface) (_THIS, SDL_Window * window, Uint32 flags);
-    void (*UpdateWindowSurface) (_THIS, SDL_Window * window, int numrects,
-                                 SDL_Rect * rects);
-    void (*FlipWindowSurface) (_THIS, SDL_Window * window);
-
-    /* Sets the color entries { firstcolor .. (firstcolor+ncolors-1) }
-       of the physical palette to those in 'colors'. If the device is
-       using a software palette (SDL_HWPALETTE not set), then the
-       changes are reflected in the logical palette of the screen
-       as well.
-       The return value is 1 if all entries could be set properly
-       or 0 otherwise.
-     */
-    int (*SetWindowColors) (_THIS, SDL_Window * window,
-                            int firstcolor, int ncolors, SDL_Color * colors);
-
     /* Get some platform dependent window information */
       SDL_bool(*GetWindowWMInfo) (_THIS, SDL_Window * window,
                                   SDL_SysWMinfo * info);
@@ -157,9 +215,6 @@
     /* * * */
     /* Hardware acceleration functions */
 
-    /* Information about the video hardware */
-    SDL_VideoInfo info;
-
     /* The pixel format used when SDL_CreateRGBSurface creates SDL_HWSURFACEs with alpha */
     SDL_PixelFormat *displayformatalphapixel;
 
@@ -242,23 +297,23 @@
     /* Free a window manager cursor
        This function can be NULL if CreateWMCursor is also NULL.
      */
-    void (*FreeWMCursor) (_THIS, WMcursor * cursor);
+    void (*FreeCursor) (_THIS, SDL_Cursor * cursor);
 
     /* If not NULL, create a black/white window manager cursor */
-    WMcursor *(*CreateWMCursor) (_THIS,
+    SDL_Cursor *(*CreateCursor) (_THIS,
                                  Uint8 * data, Uint8 * mask, int w, int h,
                                  int hot_x, int hot_y);
 
     /* Show the specified cursor, or hide if cursor is NULL */
-    int (*ShowWMCursor) (_THIS, WMcursor * cursor);
+    int (*ShowCursor) (_THIS, SDL_Cursor * cursor);
 
     /* Warp the window manager cursor to (x,y)
        If NULL, a mouse motion event is posted internally.
      */
-    void (*WarpWMCursor) (_THIS, Uint16 x, Uint16 y);
+    void (*WarpCursor) (_THIS, SDL_WindowID windowID, int x, int y);
 
     /* If not NULL, this is called when a mouse motion event occurs */
-    void (*MoveWMCursor) (_THIS, int x, int y);
+    void (*MoveCursor) (_THIS, int x, int y);
 
     /* Determine whether the mouse should be in relative mode or not.
        This function is called when the input grab state or cursor
@@ -283,7 +338,7 @@
     int num_displays;
     SDL_VideoDisplay *displays;
     int current_display;
-    Uint32 next_window_id;
+    Uint32 next_object_id;
 
     /* Driver information flags */
 
@@ -428,15 +483,14 @@
 
 #define SDL_CurrentDisplay	(_this->displays[_this->current_display])
 #define SDL_CurrentWindow	(SDL_CurrentDisplay.windows[0])
-#define SDL_VideoSurface	((_this && SDL_CurrentDisplay.num_windows > 0) ? SDL_CurrentWindow.surface : NULL)
-#define SDL_ShadowSurface	((_this && SDL_CurrentDisplay.num_windows > 0) ? SDL_CurrentWindow.shadow : NULL)
-#define SDL_PublicSurface	(SDL_ShadowSurface ? SDL_ShadowSurface : SDL_VideoSurface)
 
 extern SDL_VideoDevice *SDL_GetVideoDevice();
 extern void SDL_AddBasicVideoDisplay(const SDL_DisplayMode * desktop_mode);
 extern void SDL_AddVideoDisplay(const SDL_VideoDisplay * display);
-extern void SDL_AddDisplayMode(int display, const SDL_DisplayMode * mode);
-extern SDL_Window *SDL_GetWindowFromSurface(SDL_Surface * surface);
+extern void SDL_AddDisplayMode(int displayIndex,
+                               const SDL_DisplayMode * mode);
+extern void SDL_AddRenderDriver(int displayIndex,
+                                const SDL_RenderDriver * driver);
 
 #endif /* _SDL_sysvideo_h */
 
--- a/src/video/SDL_video.c	Mon May 29 05:08:33 2006 +0000
+++ b/src/video/SDL_video.c	Wed Jun 07 16:10:28 2006 +0000
@@ -231,7 +231,7 @@
     }
     _this = video;
     _this->name = bootstrap[i]->name;
-    _this->next_window_id = 1;
+    _this->next_object_id = 1;
 
 
     /* Set some very sane GL defaults */
@@ -268,16 +268,6 @@
         return (-1);
     }
 
-    /* Temporarily here for backwards compatibility */
-    {
-        int bpp;
-        Uint32 Rmask, Gmask, Bmask, Amask;
-
-        SDL_PixelFormatEnumToMasks(SDL_GetDesktopDisplayMode()->format, &bpp,
-                                   &Rmask, &Gmask, &Bmask, &Amask);
-        _this->info.vfmt = SDL_AllocFormat(bpp, Rmask, Gmask, Bmask, Amask);
-    }
-
     /* Sort the video modes */
     for (i = 0; i < _this->num_displays; ++i) {
         SDL_qsort(_this->displays[i].display_modes,
@@ -311,15 +301,6 @@
     return _this;
 }
 
-const SDL_VideoInfo *
-SDL_GetVideoInfo(void)
-{
-    if (!_this) {
-        return NULL;
-    }
-    return &_this->info;
-}
-
 void
 SDL_AddBasicVideoDisplay(const SDL_DisplayMode * desktop_mode)
 {
@@ -330,7 +311,6 @@
         display.desktop_mode = *desktop_mode;
     }
     display.current_mode = display.desktop_mode;
-    display.max_windows = 1;
 
     SDL_AddVideoDisplay(&display);
 }
@@ -378,14 +358,15 @@
 }
 
 void
-SDL_AddDisplayMode(int display, const SDL_DisplayMode * mode)
+SDL_AddDisplayMode(int displayIndex, const SDL_DisplayMode * mode)
 {
+    SDL_VideoDisplay *display = &_this->displays[displayIndex];
     SDL_DisplayMode *modes;
     int i, nmodes;
 
     /* Make sure we don't already have the mode in the list */
-    modes = SDL_CurrentDisplay.display_modes;
-    nmodes = SDL_CurrentDisplay.num_display_modes;
+    modes = display->display_modes;
+    nmodes = display->num_display_modes;
     for (i = 0; i < nmodes; ++i) {
         if (SDL_memcmp(mode, &modes[i], sizeof(*mode)) == 0) {
             return;
@@ -395,9 +376,9 @@
     /* Go ahead and add the new mode */
     modes = SDL_realloc(modes, (nmodes + 1) * sizeof(*mode));
     if (modes) {
-        SDL_CurrentDisplay.display_modes = modes;
+        display->display_modes = modes;
         modes[nmodes] = *mode;
-        SDL_CurrentDisplay.num_display_modes++;
+        display->num_display_modes++;
     }
 }
 
@@ -415,7 +396,7 @@
 {
     if (index < 0 || index >= SDL_GetNumDisplayModes()) {
         SDL_SetError("index must be in the range of 0 - %d",
-                     SDL_GetNumDisplayModes());
+                     SDL_GetNumDisplayModes() - 1);
         return NULL;
     }
     return &SDL_CurrentDisplay.display_modes[index];
@@ -568,19 +549,6 @@
         return 0;
     }
 
-    /* Free any previous window surfaces */
-    for (i = 0; i < display->num_windows; ++i) {
-        SDL_Window *window = &display->windows[i];
-        if (window->shadow) {
-            SDL_FreeSurface(window->shadow);
-            window->shadow = NULL;
-        }
-        if (window->surface) {
-            SDL_FreeSurface(window->surface);
-            window->surface = NULL;
-        }
-    }
-
     return _this->SetDisplayMode(_this, &display_mode);
 }
 
@@ -605,7 +573,7 @@
     }
 
     SDL_zero(window);
-    window.id = _this->next_window_id++;
+    window.id = _this->next_object_id++;
     window.title = title ? SDL_strdup(title) : NULL;
     window.x = x;
     window.y = y;
@@ -653,7 +621,7 @@
     }
 
     SDL_zero(window);
-    window.id = _this->next_window_id++;
+    window.id = _this->next_object_id++;
 
     if (!_this->CreateWindowFrom ||
         _this->CreateWindowFrom(_this, &window, data) < 0) {
@@ -701,28 +669,6 @@
     return NULL;
 }
 
-SDL_Window *
-SDL_GetWindowFromSurface(SDL_Surface * surface)
-{
-    int i, j;
-
-    if (!_this || !surface) {
-        return NULL;
-    }
-
-    for (i = 0; i < _this->num_displays; ++i) {
-        SDL_VideoDisplay *display = &_this->displays[i];
-        for (j = 0; j < display->num_windows; ++j) {
-            SDL_Window *window = &display->windows[j];
-            if (surface == window->surface || surface == window->shadow) {
-                return window;
-            }
-        }
-    }
-    return NULL;
-}
-
-
 Uint32
 SDL_GetWindowFlags(SDL_WindowID windowID)
 {
@@ -998,11 +944,8 @@
                 window->flags &= ~SDL_WINDOW_INPUT_GRABBED;
                 _this->SetWindowGrab(_this, window);
             }
-            if (window->shadow) {
-                SDL_FreeSurface(window->shadow);
-            }
-            if (window->surface) {
-                SDL_FreeSurface(window->surface);
+            if (window->renderer) {
+                SDL_DestroyRenderer(window->id);
             }
             if (_this->DestroyWindow) {
                 _this->DestroyWindow(_this, window);
@@ -1024,371 +967,569 @@
     }
 }
 
-SDL_Surface *
-SDL_CreateWindowSurface(SDL_WindowID windowID, Uint32 format, Uint32 flags)
+void
+SDL_AddRenderDriver(int displayIndex, const SDL_RenderDriver * driver)
+{
+    SDL_VideoDisplay *display = &_this->displays[displayIndex];
+    SDL_RenderDriver *render_drivers;
+
+    render_drivers =
+        SDL_realloc(display->render_drivers,
+                    (display->num_render_drivers +
+                     1) * sizeof(*render_drivers));
+    if (render_drivers) {
+        render_drivers[display->num_render_drivers] = *driver;
+        display->render_drivers = render_drivers;
+        display->num_render_drivers++;
+    }
+}
+
+int
+SDL_GetNumRenderers(void)
+{
+    if (_this) {
+        return SDL_CurrentDisplay.num_render_drivers;
+    }
+    return 0;
+}
+
+int
+SDL_GetRendererInfo(int index, SDL_RendererInfo * info)
+{
+    if (index < 0 || index >= SDL_GetNumRenderers()) {
+        SDL_SetError("index must be in the range of 0 - %d",
+                     SDL_GetNumRenderers() - 1);
+        return -1;
+    }
+    *info = SDL_CurrentDisplay.render_drivers[index].info;
+    return 0;
+}
+
+int
+SDL_CreateRenderer(SDL_WindowID windowID, int index, Uint32 flags)
+{
+    SDL_Window *window = SDL_GetWindowFromID(windowID);
+
+    if (!window) {
+        return 0;
+    }
+
+    if (index < 0) {
+        int n = SDL_GetNumRenderers();
+        for (index = 0; index < n; ++index) {
+            if ((SDL_CurrentDisplay.render_drivers[index].info.
+                 flags & flags) == flags) {
+                break;
+            }
+        }
+        if (index == n) {
+            SDL_SetError("Couldn't find matching render driver");
+            return -1;
+        }
+    }
+
+    if (index >= SDL_GetNumRenderers()) {
+        SDL_SetError("index must be -1 or in the range of 0 - %d",
+                     SDL_GetNumRenderers() - 1);
+        return -1;
+    }
+
+    /* Free any existing renderer */
+    SDL_DestroyRenderer(windowID);
+
+    /* Create a new renderer instance */
+    window->renderer =
+        SDL_CurrentDisplay.render_drivers[index].CreateRenderer(window,
+                                                                flags);
+    if (!window->renderer) {
+        return -1;
+    }
+    SDL_CurrentDisplay.current_renderer = window->renderer;
+
+    return 0;
+}
+
+int
+SDL_SelectRenderer(SDL_WindowID windowID)
 {
     SDL_Window *window = SDL_GetWindowFromID(windowID);
-    Uint32 black;
-    SDL_Surface *surface;
+
+    if (!window || !window->renderer) {
+        return -1;
+    }
+    SDL_CurrentDisplay.current_renderer = window->renderer;
+    return 0;
+}
+
+SDL_TextureID
+SDL_CreateTexture(Uint32 format, int access, int w, int h)
+{
+    SDL_Renderer *renderer;
+    SDL_Texture *texture;
+
+    if (!_this) {
+        return 0;
+    }
+
+    renderer = SDL_CurrentDisplay.current_renderer;
+    if (!renderer || !renderer->CreateTexture) {
+        return 0;
+    }
+
+    texture = (SDL_Texture *) SDL_malloc(sizeof(*texture));
+    if (!texture) {
+        SDL_OutOfMemory();
+        return 0;
+    }
+
+    SDL_zerop(texture);
+    texture->id = _this->next_object_id++;
+    texture->format = format;
+    texture->access = access;
+    texture->w = w;
+    texture->h = h;
+    texture->renderer = renderer;
 
-    if (!window) {
-        return NULL;
+    if (renderer->CreateTexture(texture) < 0) {
+        SDL_free(texture);
+        return 0;
+    }
+}
+
+SDL_TextureID
+SDL_CreateTextureFromSurface(Uint32 format, int access, SDL_Surface * surface)
+{
+    SDL_TextureID textureID;
+    Uint32 surface_flags = surface->flags;
+    SDL_PixelFormat *fmt = surface->format;
+    Uint32 colorkey;
+    Uint8 alpha;
+    SDL_Rect bounds;
+    SDL_Surface dst;
+    int bpp;
+    Uint32 Rmask, Gmask, Bmask, Amask;
+
+    if (!surface) {
+        SDL_SetError("SDL_CreateTextureFromSurface() passed NULL surface");
+        return 0;
+    }
+
+    if (format) {
+        if (!SDL_PixelFormatEnumToMasks
+            (format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) {
+            SDL_SetError("Unknown pixel format");
+            return 0;
+        }
+    } else {
+        bpp = fmt->BitsPerPixel;
+        Rmask = fmt->Rmask;
+        Gmask = fmt->Gmask;
+        Bmask = fmt->Bmask;
+        Amask = fmt->Amask;
+        format = SDL_MasksToPixelFormatEnum(bpp, Rmask, Gmask, Bmask, Amask);
+        if (!format) {
+            SDL_SetError("Unknown pixel format");
+            return 0;
+        }
+    }
+
+    textureID = SDL_CreateTexture(format, access, surface->w, surface->h);
+    if (!textureID) {
+        return 0;
     }
 
-    if (!_this->CreateWindowSurface) {
+    /* Set up a destination surface for the texture update */
+    SDL_zero(dst);
+    dst.format = SDL_AllocFormat(bpp, Rmask, Gmask, Bmask, Amask);
+    if (!dst.format) {
+        SDL_DestroyTexture(textureID);
+        return 0;
+    }
+    dst.w = surface->w;
+    dst.h = surface->h;
+    if (SDL_LockTexture(textureID, NULL, 1, &dst.pixels, &dst.pitch) == 0) {
+        dst.flags |= SDL_PREALLOC;
+    } else {
+        dst.pitch = SDL_CalculatePitch(&dst);
+        dst.pixels = SDL_malloc(dst.h * dst.pitch);
+        if (!dst.pixels) {
+            SDL_DestroyTexture(textureID);
+            SDL_FreeFormat(dst.format);
+            SDL_OutOfMemory();
+            return 0;
+        }
+    }
+
+    /* Copy the palette if any */
+    if (fmt->palette && dst.format->palette) {
+        SDL_SetTexturePalette(textureID, fmt->palette->colors, 0,
+                              fmt->palette->ncolors);
+
+        SDL_memcpy(dst.format->palette->colors,
+                   fmt->palette->colors,
+                   fmt->palette->ncolors * sizeof(SDL_Color));
+        dst.format->palette->ncolors = fmt->palette->ncolors;
+    }
+
+    /* Make the texture transparent if the surface has colorkey */
+    if (surface_flags & SDL_SRCCOLORKEY) {
+        int row;
+        int length = dst.w * dst.format->BytesPerPixel;
+        Uint8 *p = (Uint8 *) dst.pixels;
+        for (row = 0; row < dst.h; ++row) {
+            SDL_memset(p, 0, length);
+            p += dst.pitch;
+        }
+    }
+
+    /* Copy over the alpha channel */
+    if (surface_flags & SDL_SRCALPHA) {
+        if (fmt->Amask) {
+            surface->flags &= ~SDL_SRCALPHA;
+        } else {
+            /* FIXME: Need to make sure the texture has an alpha channel
+             *        and copy 'alpha' into the texture alpha channel.
+             */
+            alpha = surface->format->alpha;
+            SDL_SetAlpha(surface, 0, 0);
+        }
+    }
+
+    /* Copy over the image data */
+    bounds.x = 0;
+    bounds.y = 0;
+    bounds.w = surface->w;
+    bounds.h = surface->h;
+    SDL_LowerBlit(surface, &bounds, &dst, &bounds);
+
+    /* Clean up the original surface */
+    if ((surface_flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) {
+        Uint32 cflags = surface_flags & (SDL_SRCCOLORKEY | SDL_RLEACCELOK);
+        SDL_SetColorKey(surface, cflags, colorkey);
+    }
+    if ((surface_flags & SDL_SRCALPHA) == SDL_SRCALPHA) {
+        Uint32 aflags = surface_flags & (SDL_SRCALPHA | SDL_RLEACCELOK);
+        if (fmt->Amask) {
+            surface->flags |= SDL_SRCALPHA;
+        } else {
+            SDL_SetAlpha(surface, aflags, alpha);
+        }
+    }
+
+    /* Update the texture */
+    if (dst.flags & SDL_PREALLOC) {
+        SDL_UnlockTexture(textureID);
+    } else {
+        SDL_UpdateTexture(textureID, NULL, dst.pixels, dst.pitch);
+        SDL_free(dst.pixels);
+    }
+    SDL_FreeFormat(dst.format);
+
+    return textureID;
+}
+
+static __inline__ SDL_Texture *
+SDL_GetTextureFromID(SDL_TextureID textureID)
+{
+    int hash;
+    SDL_Texture *texture;
+
+    if (!_this) {
         return NULL;
     }
 
-    if (!window->surface) {
-        _this->CreateWindowSurface(_this, window, flags);
-        if (!window->surface) {
-            return NULL;
-        }
-        window->surface->flags |= SDL_SCREEN_SURFACE;
-
-        /* If we have a palettized surface, create a default palette */
-        if (window->surface->format->palette) {
-            SDL_Color colors[256];
-            SDL_PixelFormat *vf = window->surface->format;
-            SDL_DitherColors(colors, vf->BitsPerPixel);
-            SDL_SetColors(window->surface, colors, 0, vf->palette->ncolors);
+    hash = (textureID % SDL_arraysize(SDL_CurrentDisplay.textures));
+    for (texture = SDL_CurrentDisplay.textures[hash]; texture;
+         texture = texture->next) {
+        if (texture->id == textureID) {
+            return texture;
         }
     }
-    surface = window->surface;
+    return NULL;
+}
+
+int
+SDL_QueryTexture(SDL_TextureID textureID, Uint32 * format, int *access,
+                 int *w, int *h)
+{
+    SDL_Texture *texture = SDL_GetTextureFromID(textureID);
+
+    if (!texture) {
+        return -1;
+    }
+
+    if (format) {
+        *format = texture->format;
+    }
+    if (access) {
+        *access = texture->access;
+    }
+    if (w) {
+        *w = texture->w;
+    }
+    if (h) {
+        *h = texture->h;
+    }
+    return 0;
+}
+
+int
+SDL_UpdateTexture(SDL_TextureID textureID, SDL_Rect * rect,
+                  const void *pixels, int pitch)
+{
+    SDL_Texture *texture = SDL_GetTextureFromID(textureID);
+    SDL_Renderer *renderer;
+
+    if (!texture) {
+        return -1;
+    }
+
+    renderer = texture->renderer;
+    if (!renderer->UpdateTexture) {
+        return -1;
+    }
+    return renderer->UpdateTexture(texture, rect, pixels, pitch);
+}
+
+int
+SDL_LockTexture(SDL_TextureID textureID, SDL_Rect * rect, int markDirty,
+                void **pixels, int *pitch)
+{
+    SDL_Texture *texture = SDL_GetTextureFromID(textureID);
+    SDL_Renderer *renderer;
+
+    if (!texture) {
+        return -1;
+    }
 
-    if (window->shadow) {
-        SDL_FreeSurface(window->shadow);
-        window->shadow = NULL;
+    renderer = texture->renderer;
+    if (!renderer->LockTexture) {
+        return -1;
+    }
+    return renderer->LockTexture(texture, rect, markDirty, pixels, pitch);
+}
+
+void
+SDL_UnlockTexture(SDL_TextureID textureID)
+{
+    SDL_Texture *texture = SDL_GetTextureFromID(textureID);
+    SDL_Renderer *renderer;
+
+    if (!texture) {
+        return;
+    }
+
+    renderer = texture->renderer;
+    if (!renderer->UnlockTexture) {
+        return;
+    }
+    return renderer->UnlockTexture(texture);
+}
+
+void
+SDL_DirtyTexture(SDL_TextureID textureID, int numrects, SDL_Rect * rects)
+{
+    SDL_Texture *texture = SDL_GetTextureFromID(textureID);
+    SDL_Renderer *renderer;
+
+    if (!texture) {
+        return;
+    }
+
+    renderer = texture->renderer;
+    if (!renderer->DirtyTexture) {
+        return;
+    }
+    renderer->DirtyTexture(texture, numrects, rects);
+}
+
+void
+SDL_SelectRenderTexture(SDL_TextureID textureID)
+{
+    SDL_Texture *texture = SDL_GetTextureFromID(textureID);
+    SDL_Renderer *renderer;
+
+    if (!texture || texture->access != SDL_TextureAccess_Render) {
+        return;
+    }
+    renderer = texture->renderer;
+    if (!renderer->SelectRenderTexture) {
+        return;
+    }
+    renderer->SelectRenderTexture(texture);
+}
+
+int
+SDL_RenderFill(SDL_Rect * rect, Uint32 color)
+{
+    SDL_Renderer *renderer;
+
+    if (!_this) {
+        return -1;
+    }
+
+    renderer = SDL_CurrentDisplay.current_renderer;
+    if (!renderer || !renderer->RenderFill) {
+        return -1;
     }
 
-    /* Create a shadow surface if necessary */
-    if ((!(flags & SDL_ANYFORMAT)
-         && (format != SDL_GetCurrentDisplayMode()->format))
-        || ((flags & SDL_HWPALETTE)
-            && !(window->surface->flags & SDL_HWPALETTE))) {
-        int bpp;
-        Uint32 Rmask, Gmask, Bmask, Amask;
+    renderer->RenderFill(rect, color);
+}
+
+int
+SDL_RenderCopy(SDL_TextureID textureID, SDL_Rect * srcrect,
+               SDL_Rect * dstrect, int blendMode, int scaleMode)
+{
+    SDL_Texture *texture = SDL_GetTextureFromID(textureID);
+    SDL_Renderer *renderer;
+
+    if (!texture || texture->renderer != SDL_CurrentDisplay.current_renderer) {
+        return;
+    }
+
+    renderer = SDL_CurrentDisplay.current_renderer;
+    if (!renderer || !renderer->RenderCopy) {
+        return -1;
+    }
+
+    return renderer->RenderCopy(texture, srcrect, dstrect, blendMode,
+                                scaleMode);
+}
+
+int
+SDL_RenderReadPixels(SDL_Rect * rect, void *pixels, int pitch)
+{
+    SDL_Renderer *renderer;
+
+    if (!_this) {
+        return -1;
+    }
+
+    renderer = SDL_CurrentDisplay.current_renderer;
+    if (!renderer || !renderer->RenderReadPixels) {
+        return -1;
+    }
+
+    return renderer->RenderReadPixels(rect, pixels, pitch);
+}
+
+int
+SDL_RenderWritePixels(SDL_Rect * rect, const void *pixels, int pitch)
+{
+    SDL_Renderer *renderer;
+
+    if (!_this) {
+        return -1;
+    }
+
+    renderer = SDL_CurrentDisplay.current_renderer;
+    if (!renderer || !renderer->RenderWritePixels) {
+        return -1;
+    }
+
+    return renderer->RenderWritePixels(rect, pixels, pitch);
+}
+
+void
+SDL_RenderPresent(void)
+{
+    SDL_Renderer *renderer;
+
+    if (!_this) {
+        return;
+    }
+
+    renderer = SDL_CurrentDisplay.current_renderer;
+    if (!renderer || !renderer->RenderPresent) {
+        return;
+    }
 
-        SDL_PixelFormatEnumToMasks(format, &bpp, &Amask, &Gmask, &Bmask,
-                                   &Amask);
-        window->shadow =
-            SDL_CreateRGBSurface(SDL_SWSURFACE, surface->w, surface->h, bpp,
-                                 Rmask, Gmask, Bmask, Amask);
-        if (window->shadow == NULL) {
-            return NULL;
+    renderer->RenderPresent();
+}
+
+void
+SDL_DestroyTexture(SDL_TextureID textureID)
+{
+    int hash;
+    SDL_Texture *prev, *texture;
+    SDL_Renderer *renderer;
+
+    if (!_this) {
+        return;
+    }
+
+    /* Look up the texture in the hash table */
+    hash = (textureID % SDL_arraysize(SDL_CurrentDisplay.textures));
+    prev = NULL;
+    for (texture = SDL_CurrentDisplay.textures[hash]; texture;
+         prev = texture, texture = texture->next) {
+        if (texture->id == textureID) {
+            break;
         }
-        window->shadow->flags |= SDL_SHADOW_SURFACE;
+    }
+    if (!texture) {
+        return;
+    }
+
+    /* Unlink the texture from the list */
+    if (prev) {
+        prev->next = texture->next;
+    } else {
+        SDL_CurrentDisplay.textures[hash] = texture->next;
+    }
 
-        surface = window->shadow;
+    /* Free the texture */
+    renderer = texture->renderer;
+    renderer->DestroyTexture(texture);
+    SDL_free(texture);
+}
+
+void
+SDL_DestroyRenderer(SDL_WindowID windowID)
+{
+    SDL_Window *window = SDL_GetWindowFromID(windowID);
+    SDL_Renderer *renderer;
+    int i;
+
+    if (!window) {
+        return;
+    }
 
-        /* 8-bit shadow surfaces report that they have exclusive palette */
-        if (surface->format->palette) {
-            surface->flags |= SDL_HWPALETTE;
-            if (format == SDL_GetCurrentDisplayMode()->format) {
-                SDL_memcpy(surface->format->palette->colors,
-                           window->surface->format->palette->colors,
-                           window->surface->format->palette->ncolors *
-                           sizeof(SDL_Color));
+    renderer = window->renderer;
+    if (!renderer) {
+        return;
+    }
+
+    /* Free existing textures for this renderer */
+    for (i = 0; i < SDL_arraysize(SDL_CurrentDisplay.textures); ++i) {
+        SDL_Texture *texture;
+        SDL_Texture *prev = NULL;
+        SDL_Texture *next;
+        for (texture = SDL_CurrentDisplay.textures[i]; texture;
+             texture = next) {
+            next = texture->next;
+            if (texture->renderer == renderer) {
+                if (prev) {
+                    prev->next = next;
+                } else {
+                    SDL_CurrentDisplay.textures[i] = next;
+                }
+                renderer->DestroyTexture(texture);
+                SDL_free(texture);
             } else {
-                SDL_DitherColors(surface->format->palette->colors, bpp);
+                prev = texture;
             }
         }
     }
 
-    /* Clear the surface for display */
-    {
-        Uint32 black = SDL_MapRGB(surface->format, 0, 0, 0);
-        SDL_FillRect(surface, NULL, black);
-        if (surface->flags & SDL_DOUBLEBUF) {
-            SDL_Flip(surface);
-            SDL_FillRect(surface, NULL, black);
-        }
-        SDL_Flip(surface);
-    }
-
-    return surface;
-}
-
-/* 
- * Convert a surface into the video pixel format.
- */
-SDL_Surface *
-SDL_DisplayFormat(SDL_Surface * surface)
-{
-    Uint32 flags;
-
-    if (!SDL_PublicSurface) {
-        SDL_SetError("No video mode has been set");
-        return (NULL);
-    }
-    /* Set the flags appropriate for copying to display surface */
-    if (((SDL_PublicSurface->flags & SDL_HWSURFACE) == SDL_HWSURFACE)
-        && _this->info.blit_hw)
-        flags = SDL_HWSURFACE;
-    else
-        flags = SDL_SWSURFACE;
-#ifdef AUTORLE_DISPLAYFORMAT
-    flags |= (surface->flags & (SDL_SRCCOLORKEY | SDL_SRCALPHA));
-    flags |= SDL_RLEACCELOK;
-#else
-    flags |=
-        surface->flags & (SDL_SRCCOLORKEY | SDL_SRCALPHA | SDL_RLEACCELOK);
-#endif
-    return (SDL_ConvertSurface(surface, SDL_PublicSurface->format, flags));
-}
-
-/*
- * Convert a surface into a format that's suitable for blitting to
- * the screen, but including an alpha channel.
- */
-SDL_Surface *
-SDL_DisplayFormatAlpha(SDL_Surface * surface)
-{
-    SDL_PixelFormat *vf;
-    SDL_PixelFormat *format;
-    SDL_Surface *converted;
-    Uint32 flags;
-    /* default to ARGB8888 */
-    Uint32 amask = 0xff000000;
-    Uint32 rmask = 0x00ff0000;
-    Uint32 gmask = 0x0000ff00;
-    Uint32 bmask = 0x000000ff;
-
-    if (!SDL_PublicSurface) {
-        SDL_SetError("No video mode has been set");
-        return (NULL);
-    }
-    vf = SDL_PublicSurface->format;
-
-    switch (vf->BytesPerPixel) {
-    case 2:
-        /* For XGY5[56]5, use, AXGY8888, where {X, Y} = {R, B}.
-           For anything else (like ARGB4444) it doesn't matter
-           since we have no special code for it anyway */
-        if ((vf->Rmask == 0x1f) &&
-            (vf->Bmask == 0xf800 || vf->Bmask == 0x7c00)) {
-            rmask = 0xff;
-            bmask = 0xff0000;
-        }
-        break;
-
-    case 3:
-    case 4:
-        /* Keep the video format, as long as the high 8 bits are
-           unused or alpha */
-        if ((vf->Rmask == 0xff) && (vf->Bmask == 0xff0000)) {
-            rmask = 0xff;
-            bmask = 0xff0000;
-        }
-        break;
-
-    default:
-        /* We have no other optimised formats right now. When/if a new
-           optimised alpha format is written, add the converter here */
-        break;
-    }
-    format = SDL_AllocFormat(32, rmask, gmask, bmask, amask);
-    flags = SDL_PublicSurface->flags & SDL_HWSURFACE;
-    flags |= surface->flags & (SDL_SRCALPHA | SDL_RLEACCELOK);
-    converted = SDL_ConvertSurface(surface, format, flags);
-    SDL_FreeFormat(format);
-    return (converted);
-}
-
-/*
- * Update a specific portion of the physical screen
- */
-void
-SDL_UpdateRect(SDL_Surface * screen, Sint32 x, Sint32 y, Uint32 w, Uint32 h)
-{
-    if (screen) {
-        SDL_Rect rect;
-
-        /* Perform some checking */
-        if (w == 0)
-            w = screen->w;
-        if (h == 0)
-            h = screen->h;
-        if ((int) (x + w) > screen->w)
-            return;
-        if ((int) (y + h) > screen->h)
-            return;
-
-        /* Fill the rectangle */
-        rect.x = (Sint16) x;
-        rect.y = (Sint16) y;
-        rect.w = (Uint16) w;
-        rect.h = (Uint16) h;
-        SDL_UpdateRects(screen, 1, &rect);
-    }
-}
-void
-SDL_UpdateRects(SDL_Surface * screen, int numrects, SDL_Rect * rects)
-{
-    int i;
-    SDL_Window *window;
-
-    /* Find the window corresponding to this surface */
-    window = SDL_GetWindowFromSurface(screen);
-    if (!window) {
-        SDL_SetError("Couldn't find window associated with surface");
-        return;
-    }
+    /* Free the renderer instance */
+    renderer->DestroyRenderer(renderer);
 
-    if (screen->flags & SDL_SHADOW_SURFACE) {
-        if (SHOULD_DRAWCURSOR(SDL_cursorstate)) {
-            SDL_LockCursor();
-            SDL_DrawCursor(screen);
-            for (i = 0; i < numrects; ++i) {
-                SDL_LowerBlit(screen, &rects[i], window->surface, &rects[i]);
-            }
-            SDL_EraseCursor(screen);
-            SDL_UnlockCursor();
-        } else {
-            for (i = 0; i < numrects; ++i) {
-                SDL_LowerBlit(screen, &rects[i], window->surface, &rects[i]);
-            }
-        }
-
-        /* Fall through to video surface update */
-        screen = window->surface;
-    }
-    if ((screen->flags & SDL_SCREEN_SURFACE) && _this->UpdateWindowSurface) {
-        /* Update the video surface */
-        if (screen->offset) {
-            int offset_y = screen->offset / screen->pitch;
-            int offset_x = screen->offset % screen->pitch;
-            for (i = 0; i < numrects; ++i) {
-                rects[i].x += offset_x;
-                rects[i].y += offset_y;
-            }
-            _this->UpdateWindowSurface(_this, window, numrects, rects);
-            for (i = 0; i < numrects; ++i) {
-                rects[i].x -= offset_x;
-                rects[i].y -= offset_y;
-            }
-        } else {
-            _this->UpdateWindowSurface(_this, window, numrects, rects);
-        }
-    }
-}
-
-/*
- * Performs hardware double buffering, if possible, or a full update if not.
- */
-int
-SDL_Flip(SDL_Surface * screen)
-{
-    SDL_Window *window;
-
-    /* Find the window corresponding to this surface */
-    window = SDL_GetWindowFromSurface(screen);
-    if (!window) {
-        SDL_SetError("Couldn't find window associated with surface");
-        return;
-    }
-
-    /* Copy the shadow surface to the video surface */
-    if (screen->flags & SDL_SHADOW_SURFACE) {
-        SDL_Rect rect;
-
-        rect.x = 0;
-        rect.y = 0;
-        rect.w = screen->w;
-        rect.h = screen->h;
-        if (SHOULD_DRAWCURSOR(SDL_cursorstate)) {
-            SDL_LockCursor();
-            SDL_DrawCursor(screen);
-            SDL_LowerBlit(screen, &rect, window->surface, &rect);
-            SDL_EraseCursor(screen);
-            SDL_UnlockCursor();
-        } else {
-            SDL_LowerBlit(screen, &rect, window->surface, &rect);
-        }
-
-        /* Fall through to video surface update */
-        screen = window->surface;
+    /* Clear references */
+    window->renderer = NULL;
+    if (SDL_CurrentDisplay.current_renderer == renderer) {
+        SDL_CurrentDisplay.current_renderer = NULL;
     }
-    if (screen->flags & SDL_DOUBLEBUF) {
-        _this->FlipWindowSurface(_this, window);
-    } else {
-        SDL_UpdateRect(screen, 0, 0, 0, 0);
-    }
-    return (0);
-}
-
-int
-SDL_SetColors(SDL_Surface * screen, SDL_Color * colors, int firstcolor,
-              int ncolors)
-{
-    SDL_Window *window = NULL;
-    SDL_Palette *pal;
-    int gotall;
-    int palsize;
-
-    /* Verify the parameters */
-    pal = screen->format->palette;
-    if (!pal) {
-        return 0;               /* not a palettized surface */
-    }
-    gotall = 1;
-    palsize = 1 << screen->format->BitsPerPixel;
-    if (ncolors > (palsize - firstcolor)) {
-        ncolors = (palsize - firstcolor);
-        gotall = 0;
-    }
-
-    if (colors != (pal->colors + firstcolor)) {
-        SDL_memcpy(pal->colors + firstcolor, colors,
-                   ncolors * sizeof(*colors));
-    }
-    SDL_FormatChanged(screen);
-
-    if (screen->flags & (SDL_SHADOW_SURFACE | SDL_SCREEN_SURFACE)) {
-        window = SDL_GetWindowFromSurface(screen);
-        if (!window) {
-            return 0;
-        }
-    }
-
-    if (screen->flags & SDL_SHADOW_SURFACE) {
-        SDL_Palette *vidpal;
-
-        vidpal = window->surface->format->palette;
-        if (vidpal && vidpal->ncolors == pal->ncolors) {
-            /* This is a shadow surface, and the physical
-             * framebuffer is also indexed. Propagate the
-             * changes to its logical palette so that
-             * updates are always identity blits
-             */
-            SDL_memcpy(vidpal->colors + firstcolor, colors,
-                       ncolors * sizeof(*colors));
-        }
-        if (window->surface->flags & SDL_HWPALETTE) {
-            /* Set the physical palette */
-            screen = window->surface;
-        } else {
-            SDL_UpdateRect(screen, 0, 0, 0, 0);
-        }
-    }
-
-    if (screen->flags & SDL_SCREEN_SURFACE) {
-        if (_this->SetWindowColors) {
-            gotall =
-                _this->SetWindowColors(_this, window, firstcolor, ncolors,
-                                       colors);
-            if (!gotall) {
-                /* The video flags shouldn't have SDL_HWPALETTE, and
-                   the video driver is responsible for copying back the
-                   correct colors into the video surface palette.
-                 */
-                ;
-            }
-        }
-        SDL_CursorPaletteChanged();
-    }
-
-    return gotall;
 }
 
 void
@@ -1416,12 +1557,12 @@
             SDL_free(display->windows);
             display->windows = NULL;
         }
+        SDL_free(display->info.vfmt);
     }
     _this->VideoQuit(_this);
     if (_this->displays) {
         SDL_free(_this->displays);
     }
-    SDL_free(_this->info.vfmt);
     _this->free(_this);
     _this = NULL;
 }
@@ -1549,11 +1690,8 @@
 void
 SDL_GL_SwapBuffers(void)
 {
-    if (SDL_VideoSurface->flags & SDL_INTERNALOPENGL) {
-        _this->GL_SwapBuffers(_this);
-    } else {
-        SDL_SetError("OpenGL video mode has not been set");
-    }
+    // FIXME: Track the current window context - do we provide N contexts, and match them to M windows, or is there a one-to-one mapping?
+    _this->GL_SwapBuffers(_this);
 }
 
 #if 0                           // FIXME