changeset 4569:e1664f94f026

Andrey A. I made a video driver GAPI/RAW for WinCE (SDL-1.3). RAW mode has a priority, and also, GAPI mode works with environment "SDL_VIDEO_RENDERER=gapi" and for RAW mode "SDL_VIDEO_RENDERER=raw". I checked the work on the screens of VGA, WVGA, QVGA, WQVGA, HVGA, + tested all modes with WindowsMobile Emulator. Also, correctly draws the pointer position and the scale of the pointer for VGA/WVGA modes, correctly draws top left position for DM orientation screen, and portrait/landscape/square geometry the screen also correct. Also, I added a small fix for GDI fullscreen mode. Patch for latest revision SDL-1.3 in an attachment. Also added small path for mingw32ce build.
author Sam Lantinga <slouken@libsdl.org>
date Tue, 27 Jul 2010 21:31:28 -0700
parents 25b9cd8bdc30
children 844b5ef4b149
files configure.in src/video/SDL_sysvideo.h src/video/SDL_video.c src/video/win32/SDL_ceddrawrender.c src/video/win32/SDL_d3drender.c src/video/win32/SDL_gapirender.c src/video/win32/SDL_gapirender.h src/video/win32/SDL_gapirender_c.h src/video/win32/SDL_gdirender.c src/video/win32/SDL_win32clipboard.c src/video/win32/SDL_win32events.c src/video/win32/SDL_win32modes.c src/video/win32/SDL_win32video.c src/video/win32/SDL_win32video.h src/video/win32/SDL_win32window.c src/video/win32/SDL_win32window.h
diffstat 16 files changed, 1317 insertions(+), 731 deletions(-) [+]
line wrap: on
line diff
--- a/configure.in	Fri Jul 23 21:33:00 2010 -0700
+++ b/configure.in	Tue Jul 27 21:31:28 2010 -0700
@@ -1917,7 +1917,7 @@
     AC_MSG_CHECKING(Windows CE)
     have_wince=no
     AC_TRY_COMPILE([
-#ifndef _WIN32_WCE
+#if !defined(_WIN32_WCE) && !defined(__MINGW32CE__)
 #error This is not Windows CE
 #endif
     ],[
@@ -2388,6 +2388,12 @@
             SOURCES="$SOURCES $srcdir/src/atomic/win32/*.c"
             have_atomic=yes
         fi
+        # Set up dummy files for the joystick for now
+        if test x$enable_joystick = xyes; then
+            AC_DEFINE(SDL_JOYSTICK_DUMMY)
+            SOURCES="$SOURCES $srcdir/src/joystick/dummy/*.c"
+            have_joystick=yes
+        fi
         # Set up files for the thread library
         if test x$enable_threads = xyes; then
             AC_DEFINE(SDL_THREAD_WIN32)
@@ -2411,10 +2417,20 @@
         fi
         # Set up the system libraries we need
         EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lcoredll -lcommctrl -lmmtimer"
+
+	# mingw32ce library
+	case "$host" in
+    	    *-mingw32ce)
+    		EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lmingwex"
+    		;;
+    	    *)
+        	;;
+	esac
+
         # The Win32 platform requires special setup
         SDLMAIN_SOURCES="$srcdir/src/main/win32/*.c"
-        SDL_CFLAGS="$SDL_CFLAGS -Dmain=SDL_main -D_WIN32_WCE=0x420"
-        SDL_LIBS="-lSDLmain $SDL_LIBS"
+        EXTRA_CFLAGS="$EXTRA_CFLAGS -Dmain=SDL_main -D_WIN32_WCE=0x420"
+        EXTRA_LDFLAGS="-lSDLmain $EXTRA_LDFLAGS"
         ;;
     *-*-cygwin* | *-*-mingw32*)
         ARCH=win32
--- a/src/video/SDL_sysvideo.h	Fri Jul 23 21:33:00 2010 -0700
+++ b/src/video/SDL_sysvideo.h	Tue Jul 27 21:31:28 2010 -0700
@@ -387,9 +387,6 @@
 #if SDL_VIDEO_DRIVER_SVGALIB
 extern VideoBootStrap SVGALIB_bootstrap;
 #endif
-#if SDL_VIDEO_DRIVER_GAPI
-extern VideoBootStrap GAPI_bootstrap;
-#endif
 #if SDL_VIDEO_DRIVER_WIN32
 extern VideoBootStrap WIN32_bootstrap;
 #endif
--- a/src/video/SDL_video.c	Fri Jul 23 21:33:00 2010 -0700
+++ b/src/video/SDL_video.c	Tue Jul 27 21:31:28 2010 -0700
@@ -67,9 +67,6 @@
 #if SDL_VIDEO_DRIVER_SVGALIB
     &SVGALIB_bootstrap,
 #endif
-#if SDL_VIDEO_DRIVER_GAPI
-    &GAPI_bootstrap,
-#endif
 #if SDL_VIDEO_DRIVER_WIN32
     &WIN32_bootstrap,
 #endif
--- a/src/video/win32/SDL_ceddrawrender.c	Fri Jul 23 21:33:00 2010 -0700
+++ b/src/video/win32/SDL_ceddrawrender.c	Tue Jul 27 21:31:28 2010 -0700
@@ -459,6 +459,8 @@
     }
     data->ddraw = videodata->ddraw;
 
+    videodata->render = RENDER_DDRAW;
+
     renderer->DisplayModeChanged = DDRAW_DisplayModeChanged;
     renderer->CreateTexture = DDRAW_CreateTexture;
     renderer->QueryTexturePixels = DDRAW_QueryTexturePixels;
--- a/src/video/win32/SDL_d3drender.c	Fri Jul 23 21:33:00 2010 -0700
+++ b/src/video/win32/SDL_d3drender.c	Tue Jul 27 21:31:28 2010 -0700
@@ -451,6 +451,8 @@
     }
     data->d3d = videodata->d3d;
 
+    videodata->render = RENDER_D3D;
+
     renderer->DisplayModeChanged = D3D_DisplayModeChanged;
     renderer->CreateTexture = D3D_CreateTexture;
     renderer->QueryTexturePixels = D3D_QueryTexturePixels;
--- a/src/video/win32/SDL_gapirender.c	Fri Jul 23 21:33:00 2010 -0700
+++ b/src/video/win32/SDL_gapirender.c	Tue Jul 27 21:31:28 2010 -0700
@@ -1,670 +1,1281 @@
-/*
-    SDL - Simple DirectMedia Layer
-    Copyright (C) 1997-2010 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.
+/***************************************************************************
+ *   Copyright (C) 2010 by Andrey Afletdinov <afletdinov@gmail.com>        *
+ *                                                                         *
+ *   WinCE RAW/GAPI video driver                                           *
+ *                                                                         *
+ *   Part of the SDL - (Simple DirectMedia Layer)                          *
+ *   http://www.libsdl.org                                                 *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program 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 General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
 
-    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
-    
-    Stefan Klug
-    klug.stefan@gmx.de
-*/
 #include "SDL_config.h"
 
 #if SDL_VIDEO_RENDER_GAPI
 
 #include "SDL_win32video.h"
-//#include "../SDL_sysvideo.h"
+#include "SDL_win32window.h"
 #include "../SDL_yuv_sw_c.h"
-#include "../SDL_renderer_sw.h"
 
-#include "SDL_gapirender_c.h"
-
-#define GAPI_RENDERER_DEBUG 1
-
-/* GAPI renderer implementation */
+// RawFrameBufferInfo
+typedef struct
+{
+   WORD wFormat;
+   WORD wBPP;
+   VOID *pFramePointer;
+   int  cxStride;
+   int  cyStride;
+   int  cxPixels;
+   int  cyPixels;
+} RawFrameBufferInfo;
 
-static SDL_Renderer *GAPI_CreateRenderer(SDL_Window * window, Uint32 flags);
-static int GAPI_RenderDrawPoints(SDL_Renderer * renderer,
-                                 const SDL_Point * points, int count);
-static int GAPI_RenderDrawLines(SDL_Renderer * renderer,
-                                const SDL_Point * points, int count);
-static int GAPI_RenderDrawRects(SDL_Renderer * renderer,
-                                const SDL_Rect ** rects, int count);
-static int GAPI_RenderFillRects(SDL_Renderer * renderer,
-                                const SDL_Rect ** rects, int count);
-static int GAPI_RenderCopy(SDL_Renderer * renderer,
-                           SDL_Texture * texture,
-                           const SDL_Rect * srcrect,
-                           const SDL_Rect * dstrect);
-static void GAPI_RenderPresent(SDL_Renderer * renderer);
-static void GAPI_DestroyRenderer(SDL_Renderer * renderer);
+// GXDeviceInfo
+typedef struct
+{
+    long Version;
+    void* pvFrameBuffer;
+    unsigned long cbStride;
+    unsigned long cxWidth;
+    unsigned long cyHeight;
+    unsigned long cBPP;
+    unsigned long ffFormat;
+    char unknown[0x84 - 7 * 4];
+} GXDeviceInfo;
 
-
-SDL_RenderDriver GAPI_RenderDriver = {
-    GAPI_CreateRenderer,
-    {
-     "gapi",
-     (SDL_RENDERER_SINGLEBUFFER),
-     }
+// wince: GXDisplayProperties
+struct GXDisplayProperties
+{
+    DWORD cxWidth;
+    DWORD cyHeight;
+    long cbxPitch;
+    long cbyPitch;
+    long cBPP;
+    DWORD ffFormat;
 };
 
-static HMODULE g_hGapiLib = 0;
+// gx.dll
+typedef int   (*PFNGXOpenDisplay)(HWND hWnd, DWORD dwFlags);
+typedef int   (*PFNGXCloseDisplay)();
+typedef void* (*PFNGXBeginDraw)();
+typedef int   (*PFNGXEndDraw)();
+typedef struct GXDisplayProperties (*PFNGXGetDisplayProperties)();
+typedef int   (*PFNGXSuspend)();
+typedef int   (*PFNGXResume)();
 
-// for testing with GapiEmu
-#define USE_GAPI_EMU 0
-#define EMULATE_AXIM_X30 0
+typedef struct
+{
+    // gx.dll
+    HMODULE                   hGapiLib;
+    PFNGXOpenDisplay          GXOpenDisplay;
+    PFNGXCloseDisplay         GXCloseDisplay;
+    PFNGXBeginDraw            GXBeginDraw;
+    PFNGXEndDraw              GXEndDraw;
+    PFNGXGetDisplayProperties GXGetDisplayProperties;
+    PFNGXSuspend              GXSuspend;
+    PFNGXResume               GXResume;
+} GapiInfo;
+
+//#ifndef DM_DISPLAYORIENTATION
+//#define DM_DISPLAYORIENTATION 0x00800000L
+//#endif
+
+#define FORMAT_565		1
+#define FORMAT_555		2
+#define FORMAT_OTHER		3
+
+#define GETRAWFRAMEBUFFER	0x00020001
+#define GETGXINFO		0x00020000
+
+#define kfPalette		0x10
+#define kfDirect		0x20
+#define kfDirect555		0x40
+#define kfDirect565		0x80
 
-#if 0
-#define GAPI_LOG(...) printf(__VA_ARGS__)
-#else
-#define GAPI_LOG(...)
-#endif
+#define GX_FULLSCREEN		0x01
+
+enum ScreenOrientation { ORIENTATION_UNKNOWN = -1, ORIENTATION_UP = DMDO_0, ORIENTATION_DOWN = DMDO_180, ORIENTATION_LEFT = DMDO_270, ORIENTATION_RIGHT = DMDO_90 };
+enum ScreenGeometry { GEOMETRY_UNKNOWN, GEOMETRY_PORTRAIT, GEOMETRY_LANDSCAPE, GEOMETRY_SQUARE };
+enum FrameBufferFlags { FB_SKIP_OFFSET = 0x0001, FB_RAW_MODE = 0x0002, FB_SUSPENDED = 0x0004 };
+
+// private framebuffer info
+typedef struct
+{
+    int width;
+    int height;
+    int xpitch;
+    int ypitch;
+    int offset;
+} FrameBufferInfo;
 
+// private display data
+typedef struct
+{
+    unsigned char* pixels;	// video memory
+    int format;			// video format
+    FrameBufferInfo fb;		// framebuffer geometry
+    GapiInfo* gapi;		// GAPI module
+    int userOrientation;
+    int systemOrientation;
+    int hardwareGeometry;
+    int flags;			// fb flags
+    float scale;		// scale pointer position
+    int debug;
 
-#if USE_GAPI_EMU && !REPORT_VIDEO_INFO
-#pragma message("Warning: Using GapiEmu in release build. I assume you'd like to set USE_GAPI_EMU to zero.")
-#endif
+} WINCE_RenderData;
+
+typedef struct
+{
+    SDL_SW_YUVTexture *yuv;
+    Uint32 format;
+    void *pixels;
+    int pitch;
+
+} WINCE_TextureData;
 
 
-static void
-GAPI_SetError(const char *prefix, HRESULT result)
-{
-    const char *error;
+// system func
+SDL_Renderer*	WINCE_CreateRenderer(SDL_Window* window, Uint32 flags);
+void		WINCE_DestroyRenderer(SDL_Renderer* renderer);
+
+int		WINCE_CreateTexture(SDL_Renderer* renderer, SDL_Texture* texture);
+void		WINCE_DestroyTexture(SDL_Renderer* renderer, SDL_Texture* texture);
+int		WINCE_QueryTexturePixels(SDL_Renderer* renderer, SDL_Texture* texture, void** pixels, int* pitch);
+int		WINCE_UpdateTexture(SDL_Renderer* renderer, SDL_Texture* texture, const SDL_Rect* rect, const void* pixels, int pitch);
+int		WINCE_LockTexture(SDL_Renderer* renderer, SDL_Texture* texture, const SDL_Rect* rect, int dirty, void** pixels, int* pitch);
+void		WINCE_UnlockTexture(SDL_Renderer* renderer, SDL_Texture* texture);
+
+int		WINCE_Available(void);
+void		WINCE_SetupOrientation(WINCE_RenderData* data, int width, int height);
+
+int		WINCE_RenderCopy(SDL_Renderer* renderer, SDL_Texture* texture, const SDL_Rect* srect, const SDL_Rect* drect);
+void		WINCE_ShowWindow(_THIS, SDL_Window* window, int visible);
+
+void		WINCE_RenderPresent(SDL_Renderer* renderer);
+int		WINCE_RenderDrawPoints(SDL_Renderer* renderer, const SDL_Point* points, int count);
+int		WINCE_RenderDrawLines(SDL_Renderer* renderer, const SDL_Point* points, int count);
+int		WINCE_RenderDrawRects(SDL_Renderer* renderer, const SDL_Rect ** rects, int count);
+int		WINCE_RenderFillRects(SDL_Renderer* renderer, const SDL_Rect** rects, int count);
+
+void		WINCE_PointerCoordinateTransform(SDL_Window* window, POINT* pt);
+void		WINCE_DumpVideoInfo(WINCE_RenderData* data);
+void		WINCE_PortraitTransform(WINCE_RenderData* data, int width, int height);
+void		WINCE_LandscapeTransform(WINCE_RenderData* data, int width, int height);
+void		WINCE_SquareTransform(WINCE_RenderData* data, int width, int height);
+int		WINCE_FixedGeometry(FrameBufferInfo* fb, int bpp, int debug);
+int		WINCE_GetDMOrientation(void);
+int		WINCE_SetDMOrientation(int orientation);
+void		WINCE_UpdateYUVTextureData(SDL_Texture* texture);
+
+// gapi engine specific
+int		GAPI_Init(WINCE_RenderData* data, HWND hwnd);
+void		GAPI_Quit(WINCE_RenderData* data);
+
+// raw engine specific
+int		RAW_Init(WINCE_RenderData* data);
+void		RAW_Quit(WINCE_RenderData* data);
+
+// tools
+void		FrameBufferRotate(FrameBufferInfo* src, int orientation);
+int		GetFrameBufferOrientation(const FrameBufferInfo* src);
+void		PointerRotate(POINT* pt, const FrameBufferInfo* fb, int orientation);
+void		FrameBufferInitialize(FrameBufferInfo* fb);
+void		FrameBufferDumpInfo(const FrameBufferInfo* fb, const char*);
+const		char* GetOrientationName(int orientation);
+void		UpdateLine16to16(const FrameBufferInfo* fb, const Uint16* src, Uint16* dst, Uint16 width);
+
+// stdlib
+inline int	__abs(int x){ return x < 0 ? -x : x; };
+inline void	__swap(int* a, int* b){ int t = *a; *a = *b; *b = t; };
 
-    switch (result) {
-    default:
-        error = "UNKNOWN";
-        break;
+#define GAPI_RENDER_NAME	"gapi"
+#define RAW_RENDER_NAME		"raw"
+//
+SDL_RenderDriver GAPI_RenderDriver = {
+    WINCE_CreateRenderer,
+    {
+	GAPI_RENDER_NAME,
+	(SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTDISCARD),
+	(SDL_TEXTUREMODULATE_NONE),
+	(SDL_BLENDMODE_NONE),
+	(SDL_TEXTURESCALEMODE_NONE),
+	7,
+	{
+	    SDL_PIXELFORMAT_RGB555,
+	    SDL_PIXELFORMAT_RGB565,
+	    SDL_PIXELFORMAT_YV12,
+	    SDL_PIXELFORMAT_IYUV,
+	    SDL_PIXELFORMAT_YUY2,
+	    SDL_PIXELFORMAT_UYVY,
+	    SDL_PIXELFORMAT_YVYU
+	},
+	0,
+	0
     }
-    SDL_SetError("%s: %s", prefix, error);
+};
+
+SDL_RenderDriver RAW_RenderDriver = {
+    WINCE_CreateRenderer,
+    {
+	RAW_RENDER_NAME,
+	(SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTDISCARD),
+	(SDL_TEXTUREMODULATE_NONE),
+	(SDL_BLENDMODE_NONE),
+	(SDL_TEXTURESCALEMODE_NONE),
+	7,
+	{
+	    SDL_PIXELFORMAT_RGB555,
+	    SDL_PIXELFORMAT_RGB565,
+	    SDL_PIXELFORMAT_YV12,
+	    SDL_PIXELFORMAT_IYUV,
+	    SDL_PIXELFORMAT_YUY2,
+	    SDL_PIXELFORMAT_UYVY,
+	    SDL_PIXELFORMAT_YVYU
+	},
+	0,
+	0
+    }
+};
+
+int WINCE_Available(void)
+{
+    const char* preferably = SDL_getenv("SDL_VIDEO_RENDERER");
+
+    // raw check
+    RawFrameBufferInfo rfbi = { 0 };
+    HDC hdc = GetDC(NULL);
+    int render_raw = ExtEscape(hdc, GETRAWFRAMEBUFFER, 0, NULL, sizeof(RawFrameBufferInfo), (char *) &rfbi);
+    ReleaseDC(NULL, hdc);
+
+    if(render_raw != 0 && rfbi.cxPixels != 0 && rfbi.cyPixels != 0 &&
+        rfbi.pFramePointer != 0 && rfbi.cxStride != 0 && rfbi.cyStride != 0)
+	    render_raw = 1;
+
+    if(preferably && 0 == SDL_strcasecmp(preferably, RAW_RENDER_NAME)) return 0 != render_raw;
+
+    // gapi check
+    HMODULE render_gapi = LoadLibrary(TEXT("\\Windows\\gx.dll"));
+    if(0 == render_gapi)
+        render_gapi = LoadLibrary(TEXT("gx.dll"));
+    FreeLibrary(render_gapi);
+
+    if(preferably && 0 == SDL_strcasecmp(preferably, GAPI_RENDER_NAME)) return 0 != render_gapi;
+
+    return 0 != render_raw || 0 != render_gapi;
 }
 
-void
-GAPI_AddRenderDriver(_THIS)
+void WINCE_AddRenderDriver(_THIS)
 {
-    int i;
+    HDC hdc;
+    HMODULE render_gapi;
+    int render_raw, ii;
+    const char* preferably = SDL_getenv("SDL_VIDEO_RENDERER");
 
-    /* TODO: should we check for support of GetRawFramebuffer here?
-     */
-#if USE_GAPI_EMU
-    g_hGapiLib = LoadLibrary(L"GAPI_Emu.dll");
-#else
-    g_hGapiLib = LoadLibrary(L"\\Windows\\gx.dll");
-#endif
+   // raw check
+    RawFrameBufferInfo rfbi = { 0 };
+    hdc = GetDC(NULL);
+    render_raw = ExtEscape(hdc, GETRAWFRAMEBUFFER, 0, NULL, sizeof(RawFrameBufferInfo), (char *) &rfbi);
+    ReleaseDC(NULL, hdc);
 
-    if (g_hGapiLib) {
-#define LINK(name,import) gx.name = (PFN##name)GetProcAddress( g_hGapiLib, L##import );
+    if(render_raw != 0 && rfbi.cxPixels != 0 && rfbi.cyPixels != 0 &&
+    	rfbi.pFramePointer != 0 && rfbi.cxStride != 0 && rfbi.cyStride != 0)
+	    render_raw = 1;
 
-        LINK(GXOpenDisplay, "?GXOpenDisplay@@YAHPAUHWND__@@K@Z")
-            LINK(GXCloseDisplay, "?GXCloseDisplay@@YAHXZ")
-            LINK(GXBeginDraw, "?GXBeginDraw@@YAPAXXZ")
-            LINK(GXEndDraw, "?GXEndDraw@@YAHXZ")
-            LINK(GXOpenInput, "?GXOpenInput@@YAHXZ")
-            LINK(GXCloseInput, "?GXCloseInput@@YAHXZ")
-            LINK(GXGetDisplayProperties,
-                 "?GXGetDisplayProperties@@YA?AUGXDisplayProperties@@XZ")
-            LINK(GXGetDefaultKeys, "?GXGetDefaultKeys@@YA?AUGXKeyList@@H@Z")
-            LINK(GXSuspend, "?GXSuspend@@YAHXZ")
-            LINK(GXResume, "?GXResume@@YAHXZ")
-            LINK(GXSetViewport, "?GXSetViewport@@YAHKKKK@Z")
-            LINK(GXIsDisplayDRAMBuffer, "?GXIsDisplayDRAMBuffer@@YAHXZ")
+    // gapi check
+    render_gapi = LoadLibrary(TEXT("\\Windows\\gx.dll"));
+    if(0 == render_gapi)
+        render_gapi = LoadLibrary(TEXT("gx.dll"));
+
+    if(render_gapi)
+	FreeLibrary(render_gapi);
 
-            /* wrong gapi.dll */
-            if (!gx.GXOpenDisplay) {
-            FreeLibrary(g_hGapiLib);
-            g_hGapiLib = 0;
-        }
-#undef LINK
-    }
-
-    for (i = 0; i < _this->num_displays; ++i) {
-        SDL_AddRenderDriver(&_this->displays[i], &GAPI_RenderDriver);
+    for(ii = 0; ii < _this->num_displays; ++ii)
+    {
+	if(preferably)
+	{
+	    if(0 == SDL_strcasecmp(preferably, RAW_RENDER_NAME) && render_raw)
+    		SDL_AddRenderDriver(&_this->displays[ii], &RAW_RenderDriver);
+	    else
+	    if(0 == SDL_strcasecmp(preferably, GAPI_RENDER_NAME) && render_gapi)
+    		SDL_AddRenderDriver(&_this->displays[ii], &GAPI_RenderDriver);
+	}
+	else
+	{
+	    if(render_raw)
+    		SDL_AddRenderDriver(&_this->displays[ii], &RAW_RenderDriver);
+	    if(render_gapi)
+    		SDL_AddRenderDriver(&_this->displays[ii], &GAPI_RenderDriver);
+	}
     }
 }
 
-typedef enum
-{
-    USAGE_GX_FUNCS = 0x0001,    /* enable to use GXOpen/GXClose/GXBeginDraw... */
-    USAGE_DATA_PTR_CONSTANT = 0x0002    /* the framebuffer is at a constant location, don't use values from GXBeginDraw() */
-} GAPI_UsageFlags;
-
-
-
-typedef struct
-{
-    int w;
-    int h;
-    int xPitch;                 /* bytes to move to go to the next pixel */
-    int yPitch;                 /* bytes to move to go to the next line */
-    int offset;                 /* data offset, to add to the data returned from GetFramebuffer, before processing */
-
-    void *data;
-    Uint32 usageFlags;          /* these flags contain options to define screen handling and to reliably workarounds */
-
-    Uint32 format;              /* pixel format as defined in SDL_pixels.h */
-
-} GAPI_RenderData;
-
-
-static Uint32
-GuessPixelFormatFromBpp(int bpp)
+SDL_Renderer* WINCE_CreateRenderer(SDL_Window* window, Uint32 flags)
 {
-    switch (bpp) {
-    case 15:
-        return SDL_PIXELFORMAT_RGB555;
-    case 16:
-        return SDL_PIXELFORMAT_RGB565;
-    default:
-        return SDL_PIXELFORMAT_UNKNOWN;
-        break;
-    }
-}
+    SDL_VideoDisplay* display = window->display;
+    SDL_DisplayMode* displayMode = &display->current_mode;
+    SDL_WindowData* windowdata = (SDL_WindowData *) window->driverdata;
+    SDL_Renderer* renderer;
+    WINCE_RenderData* data;
+    int bpp;
+    Uint32 Rmask, Gmask, Bmask, Amask;
 
-static GAPI_RenderData *
-FillRenderDataRawFramebuffer(SDL_Window * window)
-{
-    RawFrameBufferInfo rbi;
-    GAPI_RenderData *renderdata;
-    HDC hdc;
+    if(!(window->flags & SDL_WINDOW_FULLSCREEN))
+	window->flags |= SDL_WINDOW_FULLSCREEN;
 
-    //TODO should we use the hdc of the window?
-    hdc = GetDC(NULL);
-    int result = ExtEscape(hdc, GETRAWFRAMEBUFFER, 0, NULL,
-                           sizeof(RawFrameBufferInfo),
-                           (char *) &rbi);
-    ReleaseDC(NULL, hdc);
-
-    if (!(result > 0)) {
+    if(!SDL_PixelFormatEnumToMasks(displayMode->format, &bpp, &Rmask, &Gmask, &Bmask, &Amask))
+    {
+        SDL_SetError("Unknown display format");
         return NULL;
     }
 
-    /* Asus A696 returns wrong results so we do a sanity check
-       See:
-       http://groups.google.com/group/microsoft.public.smartphone.developer/browse_thread/thread/4fde5bddd477de81
-     */
-    if (rbi.cxPixels <= 0 ||
-        rbi.cyPixels <= 0 ||
-        rbi.cxStride == 0 || rbi.cyStride == 0 || rbi.pFramePointer == 0) {
-        return NULL;
+    switch(window->fullscreen_mode.format)
+    {
+	case SDL_PIXELFORMAT_RGB555:
+	case SDL_PIXELFORMAT_RGB565:
+	    break;
+
+	default:
+    	    SDL_SetError("Support only 16 or 15 bpp");
+	    return NULL;
     }
 
-
-    renderdata = (GAPI_RenderData *) SDL_calloc(1, sizeof(*renderdata));
-    if (!renderdata) {
+    renderer = (SDL_Renderer*) SDL_calloc(1, sizeof(SDL_Renderer));
+    if(!renderer)
+    {
         SDL_OutOfMemory();
         return NULL;
     }
-    //Try to match the window size
-    //TODO add rotation support
-    if (rbi.cxPixels != window->w || rbi.cyPixels != window->h) {
-        SDL_free(renderdata);
-        return NULL;
-    }
-    //Check that the display uses a known display format
-    switch (rbi.wFormat) {
-    case FORMAT_565:
-        renderdata->format = SDL_PIXELFORMAT_RGB565;
-        break;
-    case FORMAT_555:
-        renderdata->format = SDL_PIXELFORMAT_RGB555;
-        break;
-    default:
-        //TODO we should add support for other formats
-        SDL_free(renderdata);
-        return NULL;
-    }
 
-    renderdata->usageFlags = USAGE_DATA_PTR_CONSTANT;
-    renderdata->data = rbi.pFramePointer;
-    renderdata->w = rbi.cxPixels;
-    renderdata->h = rbi.cyPixels;
-    renderdata->xPitch = rbi.cxStride;
-    renderdata->yPitch = rbi.cyStride;
-
-    return renderdata;
-
-}
-
-
-static GAPI_RenderData *
-FillRenderDataGAPI(SDL_Window * window)
-{
-    GAPI_RenderData *renderdata;
-    struct GXDisplayProperties gxdp;
-    int tmp;
-
-#ifdef _ARM_
-    WCHAR oemstr[100];
-#endif
-
-    if (!g_hGapiLib) {
-        return NULL;
-    }
-
-    renderdata = (GAPI_RenderData *) SDL_calloc(1, sizeof(GAPI_RenderData));
-    if (!renderdata) {
+    data = (WINCE_RenderData*) SDL_calloc(1, sizeof(WINCE_RenderData));
+    if(!data)
+    {
+        WINCE_DestroyRenderer(renderer);
         SDL_OutOfMemory();
         return NULL;
     }
 
-    gxdp = gx.GXGetDisplayProperties();
-    renderdata->usageFlags = USAGE_GX_FUNCS;
-    renderdata->w = gxdp.cxWidth;
-    renderdata->h = gxdp.cyHeight;
-    renderdata->xPitch = gxdp.cbxPitch;
-    renderdata->yPitch = gxdp.cbyPitch;
-
-    //Check that the display uses a known display format
-    if (gxdp.ffFormat & kfDirect565) {
-        renderdata->format = SDL_PIXELFORMAT_RGB565;
-    } else if (gxdp.ffFormat & kfDirect555) {
-        renderdata->format = SDL_PIXELFORMAT_RGB555;
-    } else {
-        renderdata->format = SDL_PIXELFORMAT_UNKNOWN;
-    }
-
-    /* apply some device specific corrections */
-#ifdef _ARM_
-    SystemParametersInfo(SPI_GETOEMINFO, sizeof(oemstr), oemstr, 0);
-
-    // buggy iPaq38xx
-    if ((oemstr[12] == 'H') && (oemstr[13] == '3')
-        && (oemstr[14] == '8')
-        && (gxdp.cbxPitch > 0)) {
-        renderdata->data = (void *) 0xac0755a0;
-        renderdata->xPitch = -640;
-        renderdata->yPitch = 2;
-    }
-#if (EMULATE_AXIM_X30 == 0)
-    // buggy Dell Axim X30
-    if (_tcsncmp(oemstr, L"Dell Axim X30", 13) == 0)
-#endif
+    // initialize internal engine
+    if(!RAW_Init(data) && !GAPI_Init(data, windowdata->hwnd))
     {
-        GXDeviceInfo gxInfo = { 0 };
-        HDC hdc = GetDC(NULL);
-        int result;
-
-        gxInfo.Version = 100;
-        result =
-            ExtEscape(hdc, GETGXINFO, 0, NULL, sizeof(gxInfo),
-                      (char *) &gxInfo);
-        if (result > 0) {
-            renderdata->usageFlags = USAGE_DATA_PTR_CONSTANT;   /* no more GAPI usage from now */
-            renderdata->data = gxInfo.pvFrameBuffer;
-            this->hidden->needUpdate = 0;
-            renderdata->xPitch = 2;
-            renderdata->yPitch = 480;
-            renderdata->w = gxInfo.cxWidth;
-            renderdata->h = gxInfo.cyHeight;
-
-            //Check that the display uses a known display format
-            switch (rbi->wFormat) {
-            case FORMAT_565:
-                renderdata->format = SDL_PIXELFORMAT_RGB565;
-                break;
-            case FORMAT_555:
-                renderdata->format = SDL_PIXELFORMAT_RGB555;
-                break;
-            default:
-                //TODO we should add support for other formats
-                SDL_free(renderdata);
-                return NULL;
-            }
-        }
-    }
-#endif
-
-
-    if (renderdata->format == SDL_PIXELFORMAT_UNKNOWN) {
-        SDL_SetError("Gapi Pixelformat is unknown");
-        SDL_free(renderdata);
+        WINCE_DestroyRenderer(renderer);
         return NULL;
     }
 
-    /* Gapi always returns values in standard orientation, so we manually apply
-       the current orientation 
-     */
 
-    DEVMODE settings;
-    SDL_memset(&settings, 0, sizeof(DEVMODE));
-    settings.dmSize = sizeof(DEVMODE);
-
-    settings.dmFields = DM_DISPLAYORIENTATION;
-    ChangeDisplaySettingsEx(NULL, &settings, NULL, CDS_TEST, NULL);
-
-    if (settings.dmDisplayOrientation == DMDO_90) {
-
-        tmp = renderdata->w;
-        renderdata->w = renderdata->h;
-        renderdata->h = tmp;
-
-        tmp = renderdata->xPitch;
-        renderdata->xPitch = -renderdata->yPitch;
-        renderdata->yPitch = tmp;
-
-        renderdata->offset = -renderdata->w * renderdata->xPitch;
-
-    } else if (settings.dmDisplayOrientation == DMDO_180) {
-
-        renderdata->xPitch = -renderdata->xPitch;
-        renderdata->yPitch = -renderdata->yPitch;
+    // set debug
+    data->debug	= SDL_getenv("DEBUG_VIDEO_GAPI") || SDL_getenv("GAPI_RENDERER_DEBUG") ? 1 : 0;
+#if defined(DEBUG_VIDEO_GAPI) || defined(GAPI_RENDERER_DEBUG)
+    data->debug	= 1;
+#endif
 
-        renderdata->offset = -renderdata->h * renderdata->yPitch
-            - renderdata->w * renderdata->xPitch;
-
-    } else if (settings.dmDisplayOrientation == DMDO_270) {
-
-        tmp = renderdata->w;
-        renderdata->w = renderdata->h;
-        renderdata->h = tmp;
-
-        tmp = renderdata->xPitch;
-        renderdata->xPitch = renderdata->yPitch;
-        renderdata->yPitch = -tmp;
+    windowdata->videodata->render = data->gapi ? RENDER_GAPI : RENDER_RAW;
+    windowdata->videodata->CoordTransform = WINCE_PointerCoordinateTransform;
 
-        renderdata->offset = -renderdata->h * renderdata->yPitch;
-
-    }
+    window->display->device->MaximizeWindow = NULL;
+    window->display->device->MinimizeWindow = NULL;
 
-    if (renderdata->w != window->w || renderdata->h != window->h) {
-        GAPI_LOG("GAPI open failed, wrong size %i %i %i %i\n", renderdata->w,
-                 renderdata->h, renderdata->xPitch, renderdata->yPitch);
-        SDL_free(renderdata);
-        return NULL;
-    }
-
-    return renderdata;
-
-}
-
+    WINCE_SetupOrientation(data, window->w, window->h);
 
-/* This function does the whole encapsulation of Gapi/RAWFRAMEBUFFER
-   it should handle all the device dependent details and fill the device INDEPENDENT
-   RenderData structure.
- */
-GAPI_RenderData *
-FillRenderData(SDL_Window * window)
-{
-    /* We try to match the requested window to the modes available by GAPI and RAWFRAMEBUFFER.
-       First RAWFRAMEBUFFER is tried, as it is the most reliable one 
-       Look here for detailed discussions:
-       http://pdaphonehome.com/forums/samsung-i700/28087-just-saw.html
-       http://blogs.msdn.com/windowsmobile/archive/2007/08/13/have-you-migrated-to-directdraw-yet.aspx
-     */
-
-    GAPI_RenderData *res;
-
-    res = FillRenderDataRawFramebuffer(window);
-    GAPI_LOG("FillRenderDataRawFramebuffer: %p\n", res);
-    if (res) {
-        return res;
-    }
-    //Now we try gapi
-    res = FillRenderDataGAPI(window);
-    GAPI_LOG("FillRenderDataGAPI: %p\n", res);
-
-    return res;
-}
-
-void *
-GetFramebuffer()
-{
-
-}
-
+    renderer->CreateTexture = WINCE_CreateTexture;
+    renderer->DestroyTexture = WINCE_DestroyTexture;
+    renderer->QueryTexturePixels = WINCE_QueryTexturePixels;
+    renderer->UpdateTexture = WINCE_UpdateTexture;
+    renderer->LockTexture = WINCE_LockTexture;
+    renderer->UnlockTexture = WINCE_UnlockTexture;
 
-SDL_Renderer *
-GAPI_CreateRenderer(SDL_Window * window, Uint32 flags)
-{
-    SDL_VideoDisplay *display = window->display;
-    SDL_WindowData *windowdata = (SDL_WindowData *) window->driverdata;
-    SDL_DisplayMode *displayMode = &display->current_mode;
-    SDL_Renderer *renderer;
-    GAPI_RenderData *data;
-    int i, n;
-    int bpp;
-    Uint32 Rmask, Gmask, Bmask, Amask;
-
-    if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
-        SDL_SetError("Gapi supports only fullscreen windows");
-        return NULL;
-    }
-
-    if (!SDL_PixelFormatEnumToMasks
-        (displayMode->format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) {
-        SDL_SetError("Unknown display format");
-        return NULL;
-    }
+    renderer->RenderCopy = WINCE_RenderCopy;
+    renderer->DestroyRenderer = WINCE_DestroyRenderer;
 
-    renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
-    if (!renderer) {
-        SDL_OutOfMemory();
-        return NULL;
-    }
+    renderer->RenderPresent = WINCE_RenderPresent;
+    renderer->RenderDrawPoints = WINCE_RenderDrawPoints;
+    renderer->RenderDrawLines = WINCE_RenderDrawLines;
+    renderer->RenderDrawRects = WINCE_RenderDrawRects;
+    renderer->RenderFillRects = WINCE_RenderFillRects;
 
-    data = FillRenderData(window);
-    if (!data) {
-        GAPI_DestroyRenderer(renderer);
-        SDL_OutOfMemory();
-        return NULL;
-    }
+    renderer->info = data->gapi ? GAPI_RenderDriver.info : RAW_RenderDriver.info;
 
-    renderer->RenderDrawPoints = GAPI_RenderDrawPoints;
-    renderer->RenderDrawLines = GAPI_RenderDrawLines;
-    renderer->RenderDrawRects = GAPI_RenderDrawRects;
-    renderer->RenderFillRects = GAPI_RenderFillRects;
-    renderer->RenderCopy = GAPI_RenderCopy;
-    renderer->RenderPresent = GAPI_RenderPresent;
-    renderer->DestroyRenderer = GAPI_DestroyRenderer;
-    renderer->info.name = GAPI_RenderDriver.info.name;
-    renderer->info.flags = 0;
     renderer->window = window;
     renderer->driverdata = data;
 
-    /* Gapi provides only a framebuffer so lets use software implementation */
-    Setup_SoftwareRenderer(renderer);
-
-#ifdef GAPI_RENDERER_DEBUG
-    printf("Created gapi renderer\n");
-    printf("use GX functions: %i\n", data->usageFlags & USAGE_GX_FUNCS);
-    printf("framebuffer is constant: %i\n",
-           data->usageFlags & USAGE_DATA_PTR_CONSTANT);
-    printf("w: %i h: %i\n", data->w, data->h);
-    printf("data ptr: %p\n", data->data);       /* this can be 0 in case of GAPI usage */
-    printf("xPitch: %i\n", data->xPitch);
-    printf("yPitch: %i\n", data->yPitch);
-    printf("offset: %i\n", data->offset);
-    printf("format: %x\n", data->format);
-#endif
-
-    if (data->usageFlags & USAGE_GX_FUNCS) {
-        if (gx.GXOpenDisplay(windowdata->hwnd, GX_FULLSCREEN) == 0) {
-            GAPI_DestroyRenderer(renderer);
-            return NULL;
-        }
-    }
-
     return renderer;
 }
 
-static int
-GAPI_RenderDrawPoints(SDL_Renderer * renderer,
-                      const SDL_Point * points, int count)
+void WINCE_DestroyRenderer(SDL_Renderer* renderer)
+{
+    WINCE_RenderData *renderdata = (WINCE_RenderData*) renderer->driverdata;
+
+    if(renderdata)
+    {
+	if(renderdata->gapi)
+    	    GAPI_Quit(renderdata);
+	else
+	    RAW_Quit(renderdata);
+
+        SDL_free(renderdata);
+    }
+
+    SDL_free(renderer);
+}
+
+int WINCE_CreateTexture(SDL_Renderer* renderer, SDL_Texture* texture)
+{
+    WINCE_TextureData* texturedata = (WINCE_TextureData*) SDL_calloc(1, sizeof(WINCE_TextureData));
+    if(NULL == texturedata)
+    {
+        SDL_OutOfMemory();
+        return -1;
+    }
+
+    texturedata->pitch = texture->w * SDL_BYTESPERPIXEL(texture->format);
+    texturedata->pixels = SDL_malloc(texture->h * texturedata->pitch);
+    if(NULL == texturedata->pixels)
+    {
+        SDL_OutOfMemory();
+        return -1;
+    }
+
+    if(SDL_ISPIXELFORMAT_FOURCC(texture->format))
+    {
+	texturedata->yuv = SDL_SW_CreateYUVTexture(texture->format, texture->w, texture->h);
+        if(NULL == texturedata->yuv)
+	{
+    	    SDL_OutOfMemory();
+            return -1;
+        }
+	SDL_Window* window = renderer->window;
+	SDL_VideoDisplay* display = window->display;
+	texturedata->format = display->current_mode.format;
+    }
+    else
+    {
+	texturedata->yuv = NULL;
+	texturedata->format = texture->format;
+    }
+
+    texture->driverdata = texturedata;
+
+    return 0;
+}
+
+void WINCE_DestroyTexture(SDL_Renderer* renderer, SDL_Texture* texture)
+{
+    WINCE_TextureData *texturedata = (WINCE_TextureData*) texture->driverdata;
+
+    if(texturedata)
+    {
+	if(texturedata->yuv) SDL_SW_DestroyYUVTexture(texturedata->yuv);
+	if(texturedata->pixels) SDL_free(texturedata->pixels);
+	SDL_free(texturedata);
+	texture->driverdata = NULL;
+    }
+}
+
+int WINCE_QueryTexturePixels(SDL_Renderer* renderer, SDL_Texture* texture, void** pixels, int* pitch)
+{
+    WINCE_TextureData* texturedata = (WINCE_TextureData*) texture->driverdata;
+
+    if(texturedata->yuv)
+        return SDL_SW_QueryYUVTexturePixels(texturedata->yuv, pixels, pitch);
+
+    *pixels = texturedata->pixels;
+    *pitch = texturedata->pitch;
+
+    return 0;
+}
+
+int WINCE_UpdateTexture(SDL_Renderer* renderer, SDL_Texture* texture, const SDL_Rect* rect, const void* pixels, int pitch)
 {
-    // TODO implement
+    WINCE_TextureData* texturedata = (WINCE_TextureData*) texture->driverdata;
+
+    if(texturedata->yuv)
+    {
+        if(SDL_SW_UpdateYUVTexture(texturedata->yuv, rect, pixels, pitch) < 0)
+            return -1;
+        WINCE_UpdateYUVTextureData(texture);
+        return 0;
+    }
+
+    if(0 < rect->w && 0 < rect->h)
+    {
+	const unsigned char *src = ((const unsigned char*) pixels);
+	unsigned char *dst = ((unsigned char*) texturedata->pixels) +
+				rect->y * texturedata->pitch +
+				rect->x * SDL_BYTESPERPIXEL(texture->format);
+        int length = rect->w * SDL_BYTESPERPIXEL(texture->format);
+	int height = rect->h;
+
+	while(height--)
+	{
+	    SDL_memcpy(dst, src, length);
+	    dst += texturedata->pitch;
+	    src += pitch;
+	}
+    }
+
+    return 0;
+}
+
+int WINCE_LockTexture(SDL_Renderer* renderer, SDL_Texture* texture, const SDL_Rect* rect, int dirty, void** pixels, int* pitch)
+{
+    WINCE_TextureData *texturedata = (WINCE_TextureData*) texture->driverdata;
+
+    if(texturedata->yuv)
+        return SDL_SW_LockYUVTexture(texturedata->yuv, rect, dirty, pixels, pitch);
+
+    *pixels = (void *) ((unsigned char*) texturedata->pixels +
+		    rect->y * texturedata->pitch +
+		    rect->x * SDL_BYTESPERPIXEL(texture->format));
+    *pitch = texturedata->pitch;
+}
+
+void WINCE_UnlockTexture(SDL_Renderer* renderer, SDL_Texture* texture)
+{
+    WINCE_TextureData *texturedata = (WINCE_TextureData*) texture->driverdata;
+
+    if(texturedata->yuv)
+    {
+        SDL_SW_UnlockYUVTexture(texturedata->yuv);
+	WINCE_UpdateYUVTextureData(texture);
+    }
+}
+
+int WINCE_RenderCopy(SDL_Renderer* renderer, SDL_Texture* texture, const SDL_Rect* srect, const SDL_Rect* drect)
+{
+    WINCE_RenderData* dstdata = (WINCE_RenderData*) renderer->driverdata;
+    WINCE_TextureData* srcdata = (WINCE_TextureData*) texture->driverdata;
+
+    if((dstdata->flags & FB_SUSPENDED) ||
+       0 >= srect->w || 0 >= srect->h) return;
+
+    // lock gapi
+    if(dstdata->gapi) dstdata->gapi->GXBeginDraw();
+
+    const unsigned char *src = ((const unsigned char*) srcdata->pixels);
+    unsigned char *dst = dstdata->pixels + (dstdata->flags & FB_SKIP_OFFSET ? 0 : dstdata->fb.offset) +
+				drect->y * dstdata->fb.ypitch +
+				drect->x * dstdata->fb.xpitch;
+    if(srcdata->yuv)
+    {
+	return SDL_SW_CopyYUVToRGB(srcdata->yuv,
+                                   srect, srcdata->format,
+                                   drect->w, drect->h, dst,
+                                   dstdata->fb.ypitch);
+    }
+    else
+    {
+	int height = drect->h;
+	int length = drect->w * SDL_BYTESPERPIXEL(texture->format); // in bytes
+
+	while(height--)
+	{
+	    switch(SDL_BYTESPERPIXEL(texture->format))
+	    {
+		case 2: UpdateLine16to16(&dstdata->fb, (Uint16*) src, (Uint16*) dst, length >> 1); break;
+
+		default: break;
+	    }
+
+	    dst += dstdata->fb.ypitch;
+	    src += srcdata->pitch;
+	}
+    }
+
+    // unlock gapi
+    if(dstdata->gapi) dstdata->gapi->GXEndDraw();
+
+    return 0;
+}
+
+void WINCE_RenderPresent(SDL_Renderer* renderer)
+{
+}
+
+int WINCE_RenderDrawPoints(SDL_Renderer* renderer, const SDL_Point* points, int count)
+{
     SDL_Unsupported();
     return -1;
 }
 
-static int
-GAPI_RenderDrawLines(SDL_Renderer * renderer,
-                     const SDL_Point * points, int count)
+int WINCE_RenderDrawLines(SDL_Renderer* renderer, const SDL_Point* points, int count)
 {
-    // TODO implement
     SDL_Unsupported();
     return -1;
 }
 
-static int
-GAPI_RenderDrawRects(SDL_Renderer * renderer,
-                     const SDL_Rect ** rects, int count)
+int WINCE_RenderDrawRects(SDL_Renderer* renderer, const SDL_Rect ** rects, int count)
 {
-    // TODO implement
     SDL_Unsupported();
     return -1;
 }
 
-static int
-GAPI_RenderFillRects(SDL_Renderer * renderer,
-                     const SDL_Rect ** rects, int count)
+int WINCE_RenderFillRects(SDL_Renderer* renderer, const SDL_Rect** rects, int count)
 {
-    // TODO implement
     SDL_Unsupported();
     return -1;
 }
 
-/* Video memory is very slow so lets optimize as much as possible */
-static void
-updateLine16to16(char *src, int srcXPitch, int srcYPitch,
-                 char *dst, int dstXPitch, int dstYPitch, int width,
-                 int height)
+
+
+void WINCE_SetupOrientation(WINCE_RenderData* data, int width, int height)
 {
-    char *srcLine, *dstLine;
-    char *srcPix, *dstPix;
+    const float maxW1 = GetSystemMetrics(SM_CXSCREEN) > GetSystemMetrics(SM_CYSCREEN) ? GetSystemMetrics(SM_CXSCREEN) : GetSystemMetrics(SM_CYSCREEN);
+    const float maxW2 = data->fb.width > data->fb.height ? data->fb.width : data->fb.height;
+
+    // scale define
+    data->scale = maxW2 / maxW1;
+
+    // init fb values
+    FrameBufferInitialize(&data->fb);
+
+    // orientation values
+    data->userOrientation = ORIENTATION_UP;
+    data->systemOrientation = WINCE_GetDMOrientation();
+    data->hardwareGeometry = data->fb.width == data->fb.height ? GEOMETRY_SQUARE :
+				(data->fb.width < data->fb.height ? GEOMETRY_PORTRAIT : GEOMETRY_LANDSCAPE);
+
+    if(data->debug)
+	WINCE_DumpVideoInfo(data);
+
+    if(data->systemOrientation == ORIENTATION_UNKNOWN)
+	data->systemOrientation == ORIENTATION_UP;
+
+    data->userOrientation = ORIENTATION_UP;
 
-    int x, y;
+    switch(data->hardwareGeometry)
+    {
+	case GEOMETRY_PORTRAIT:  WINCE_PortraitTransform(data, width, height); break;
+	case GEOMETRY_LANDSCAPE: WINCE_LandscapeTransform(data, width, height); break;
+	case GEOMETRY_SQUARE:    WINCE_SquareTransform(data, width, height); break;
+	default: break;
+    }
+
+    // debug
+    if(data->debug)
+    {
+	printf("\n");
+	printf("user video width:          %d\n", width);
+	printf("user video height:         %d\n", height);
+	FrameBufferDumpInfo(&data->fb, "user");
+    }
+}
+
+void WINCE_DumpVideoInfo(WINCE_RenderData* data)
+{
+    // get oem info
+    WCHAR oemInfo[48];
+    SDL_memset(oemInfo, 0, sizeof(oemInfo));
+    SystemParametersInfo(SPI_GETOEMINFO, sizeof(oemInfo) - sizeof(WCHAR), oemInfo, 0);
+
+    printf("hardware oem: ");
+    wprintf(oemInfo);
+    printf("\n");
 
-    //First dumb solution
-    if (srcXPitch == 2 && dstXPitch == 2) {
-        srcLine = src;
-        dstLine = dst;
-        y = height;
-        while (y--) {
-            SDL_memcpy(dstLine, srcLine, width * sizeof(Uint16));
-            srcLine += srcYPitch;
-            dstLine += dstYPitch;
-        }
-    } else {
-        //printf("GAPI uses slow blit path %i, %i\n", dstXPitch, dstYPitch);
-        srcLine = src;
-        dstLine = dst;
-        y = height;
-        while (y--) {
-            srcPix = srcLine;
-            dstPix = dstLine;
-            x = width;
-            while (x--) {
-                *((Uint16 *) dstPix) = *((Uint16 *) srcPix);
-                dstPix += dstXPitch;
-                srcPix += srcXPitch;
-            }
-            srcLine += srcYPitch;
-            dstLine += dstYPitch;
-        }
+    printf("video driver mode:             %s\n", (data->flags & FB_RAW_MODE ? RAW_RENDER_NAME : GAPI_RENDER_NAME));
+    printf("GetSystemMetrics(SM_CXSCREEN): %d\n", GetSystemMetrics(SM_CXSCREEN));
+    printf("GetSystemMetrics(SM_CYSCREEN): %d\n", GetSystemMetrics(SM_CYSCREEN));
+    printf("scale coord:                   %f\n", data->scale);
+
+    FrameBufferDumpInfo(&data->fb, "hardware");
+
+    printf("display format:                %p\n", data->format);
+    printf("display bits per pixel:        %d\n", SDL_BITSPERPIXEL(data->format));
+    printf("display bytes per pixel:       %d\n", SDL_BYTESPERPIXEL(data->format));
+    printf("display memory:                %p\n", data->pixels);
+    printf("system orientation:            %d, %s\n", data->systemOrientation, GetOrientationName(data->systemOrientation));
+    printf("hardware geometry:             %d\n", data->hardwareGeometry);
+}
+
+void WINCE_ShowWindow(_THIS, SDL_Window* window, int visible)
+{
+    SDL_WindowData* windowdata = (SDL_WindowData*) window->driverdata;
+    SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
+    SDL_Renderer* renderer = (SDL_Renderer*) window->renderer;
+
+    if(visible)
+    {
+	if(window->flags & SDL_WINDOW_FULLSCREEN)
+	{
+	    if(videodata->SHFullScreen)
+		videodata->SHFullScreen(windowdata->hwnd, SHFS_HIDETASKBAR | SHFS_HIDESTARTICON | SHFS_HIDESIPBUTTON);
+	    ShowWindow(FindWindow(TEXT("HHTaskBar"), NULL), SW_HIDE);
+	}
+
+	ShowWindow(windowdata->hwnd, SW_SHOW);
+        SetForegroundWindow(windowdata->hwnd);
+
+	if(renderer &&
+	    (videodata->render == RENDER_GAPI || videodata->render == RENDER_RAW))
+	{
+	    WINCE_RenderData* renderdata = (WINCE_RenderData*) renderer->driverdata;
+	    renderdata->flags &= ~FB_SUSPENDED;
+	    if(renderdata->gapi) renderdata->gapi->GXResume();
+	}
+    }
+    else
+    {
+	if(renderer &&
+	    (videodata->render == RENDER_GAPI || videodata->render == RENDER_RAW))
+	{
+	    WINCE_RenderData* renderdata = (WINCE_RenderData*) renderer->driverdata;
+	    if(renderdata->gapi) renderdata->gapi->GXSuspend();
+	    renderdata->flags |= FB_SUSPENDED;
+	}
+
+	ShowWindow(windowdata->hwnd, SW_HIDE);
+
+	if(window->flags & SDL_WINDOW_FULLSCREEN)
+	{
+	    if(videodata->SHFullScreen)
+		videodata->SHFullScreen(windowdata->hwnd, SHFS_SHOWTASKBAR | SHFS_SHOWSTARTICON | SHFS_SHOWSIPBUTTON);
+	    ShowWindow(FindWindow(TEXT("HHTaskBar"), NULL), SW_SHOW);
+	}
     }
 }
 
-static int
-GAPI_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
-                const SDL_Rect * srcrect, const SDL_Rect * dstrect)
+
+void WINCE_PointerCoordinateTransform(SDL_Window* window, POINT* pt)
+{
+    WINCE_RenderData* data = (WINCE_RenderData*) window->renderer->driverdata;
+
+    pt->x *= data->scale;
+    pt->y *= data->scale;
+
+    PointerRotate(pt, &data->fb, data->userOrientation);
+}
+
+void WINCE_PortraitTransform(WINCE_RenderData* data, int width, int height)
+{
+    if(data->systemOrientation != ORIENTATION_UP)
+	FrameBufferRotate(&data->fb, data->systemOrientation);
+
+    if(data->fb.width != width || data->fb.height != height)
+    switch(data->systemOrientation)
+    {
+	case ORIENTATION_UP:
+	case ORIENTATION_LEFT: data->userOrientation = ORIENTATION_RIGHT; break;
+	case ORIENTATION_RIGHT:
+	case ORIENTATION_DOWN: data->userOrientation = ORIENTATION_LEFT; break;
+	default: break;
+    }
+
+    if(data->userOrientation != ORIENTATION_UP)
+	FrameBufferRotate(&data->fb, data->userOrientation);
+}
+
+void WINCE_LandscapeTransform(WINCE_RenderData* data, int width, int height)
 {
-    GAPI_RenderData *data = (GAPI_RenderData *) renderer->driverdata;
-    int bpp;
-    int bytespp;
-    int status;
-    Uint32 Rmask, Gmask, Bmask, Amask;
+    switch(data->systemOrientation)
+    {
+	case ORIENTATION_UP:  FrameBufferRotate(&data->fb, ORIENTATION_LEFT); break;
+	case ORIENTATION_LEFT:FrameBufferRotate(&data->fb, ORIENTATION_DOWN); break;
+	case ORIENTATION_DOWN:FrameBufferRotate(&data->fb, ORIENTATION_RIGHT); break;
+	default: break;
+    }
+
+    if(data->fb.width != width || data->fb.height != height)
+    switch(data->systemOrientation)
+    {
+	case ORIENTATION_UP:
+	case ORIENTATION_LEFT: data->userOrientation = ORIENTATION_RIGHT; break;
+	case ORIENTATION_RIGHT:
+	case ORIENTATION_DOWN: data->userOrientation = ORIENTATION_LEFT; break;
+	default: break;
+    }
+
+    if(data->userOrientation != ORIENTATION_UP)
+	FrameBufferRotate(&data->fb, data->userOrientation);
+}
+
+void WINCE_SquareTransform(WINCE_RenderData* data, int width, int height)
+{
+    WINCE_PortraitTransform(data, width, height);
+}
 
-    if (texture->format != data->format) {
-        SDL_SetError("Gapi got wrong texture");
-        return -1;
+int WINCE_FixedGeometry(FrameBufferInfo* fb, int bpp, int debug)
+{
+    // check square
+    if(GetSystemMetrics(SM_CXSCREEN) == GetSystemMetrics(SM_CYSCREEN) &&
+	fb->width != fb->height)
+    {
+	if(fb->width < fb->height)
+	    fb->height = fb->width;
+	else
+	if(fb->height < fb->width)
+	    fb->width = fb->height;
+    }
+
+    // check width
+    if(__abs(fb->xpitch) == bpp &&
+	fb->width  != __abs(fb->ypitch) / bpp)
+    {
+	if(fb->height == __abs(fb->ypitch) / bpp)
+    	{
+	    __swap(&fb->width, &fb->height);
+
+	    if(debug)
+		printf("WINCE_FixedGeometry: width: %d, height: %d\n", fb->width, fb->height);
+	}
+	else
+	    return -1;
+    }
+    else
+    // check height
+    if(__abs(fb->ypitch) == bpp &&
+	fb->height != __abs(fb->xpitch) / bpp)
+    {
+	if(fb->width  == __abs(fb->xpitch) / bpp)
+    	{
+	    __swap(&fb->width, &fb->height);
+
+	    if(debug)
+		printf("WINCE_FixedGeometry: width: %d, height: %d\n", fb->width, fb->height);
+	}
+	else
+	    return -1;
     }
 
-    GAPI_LOG("GAPI_RenderCopy\n");
+    return 0;
+}
+
+void WINCE_UpdateYUVTextureData(SDL_Texture* texture)
+{
+    WINCE_TextureData* texturedata = (WINCE_TextureData*) texture->driverdata;
+    SDL_Rect rect;
+
+    rect.x = 0;
+    rect.y = 0;
+    rect.w = texture->w;
+    rect.h = texture->h;
+    SDL_SW_CopyYUVToRGB(texturedata->yuv, &rect, texturedata->format, texture->w, texture->h, texturedata->pixels, texturedata->pitch);
+}
+
+int GAPI_Init(WINCE_RenderData* data, HWND hwnd)
+{
+    if(NULL == data->gapi)
+    {
+	const char* preferably = SDL_getenv("SDL_VIDEO_RENDERER");
+	if(preferably && 0 != SDL_strcasecmp(preferably, GAPI_RENDER_NAME)) return 0;
+
+        data->gapi = (GapiInfo *) SDL_calloc(1, sizeof(GapiInfo));
+        if(NULL == data->gapi)
+        {
+            SDL_OutOfMemory();
+            return 0;
+        }
+
+	data->gapi->hGapiLib = LoadLibrary(TEXT("\\Windows\\gx.dll"));
+	if(0 == data->gapi->hGapiLib)
+	{
+	    data->gapi->hGapiLib = LoadLibrary(TEXT("gx.dll"));
+	    if(0 == data->gapi->hGapiLib) return 0;
+	}
+
+	// load gapi library
+#define LINK(type,name,import) name=(PFN##type)GetProcAddress(data->gapi->hGapiLib,TEXT(import))
+	LINK(GXOpenDisplay,         data->gapi->GXOpenDisplay,         "?GXOpenDisplay@@YAHPAUHWND__@@K@Z");
+	LINK(GXCloseDisplay,        data->gapi->GXCloseDisplay,        "?GXCloseDisplay@@YAHXZ");
+	LINK(GXBeginDraw,           data->gapi->GXBeginDraw,           "?GXBeginDraw@@YAPAXXZ");
+	LINK(GXEndDraw,             data->gapi->GXEndDraw,             "?GXEndDraw@@YAHXZ");
+	LINK(GXGetDisplayProperties,data->gapi->GXGetDisplayProperties,"?GXGetDisplayProperties@@YA?AUGXDisplayProperties@@XZ");
+	LINK(GXSuspend,             data->gapi->GXSuspend,             "?GXSuspend@@YAHXZ");
+	LINK(GXResume,              data->gapi->GXResume,              "?GXResume@@YAHXZ");
+#undef LINK
+
+	int enable = data->gapi->GXGetDisplayProperties && data->gapi->GXCloseDisplay && data->gapi->GXOpenDisplay &&
+	    data->gapi->GXBeginDraw && data->gapi->GXEndDraw && data->gapi->GXSuspend && data->gapi->GXResume;
+
+	if(!enable)
+	{
+	    SDL_SetError("GAPI_Init: error gx.dll: internal error");
+	    GAPI_Quit(data);
+	    return 0;
+	}
+
+	if(0 == data->gapi->GXOpenDisplay(hwnd, GX_FULLSCREEN))
+	{
+	    SDL_SetError("GAPI_Init: couldn't initialize GAPI");
+	    GAPI_Quit(data);
+	    return 0;
+	}
+
+	struct GXDisplayProperties gxProperties = data->gapi->GXGetDisplayProperties();
 
-    if (data->usageFlags & USAGE_GX_FUNCS) {
-        char *buffer;
-        buffer = gx.GXBeginDraw();
-        if (!(data->usageFlags & USAGE_DATA_PTR_CONSTANT)) {
-            data->data = buffer;
+	// fill FrameBufferInfo
+	data->fb.xpitch = gxProperties.cbxPitch;
+	data->fb.ypitch = gxProperties.cbyPitch;
+	data->fb.width  = gxProperties.cxWidth;
+	data->fb.height = gxProperties.cyHeight;
+	data->fb.offset = 0;
+
+        if((gxProperties.ffFormat & kfDirect565) || 16 == gxProperties.cBPP)
+	    data->format = SDL_PIXELFORMAT_RGB565;
+	else
+	if((gxProperties.ffFormat & kfDirect555) || 15 == gxProperties.cBPP)
+	    data->format = SDL_PIXELFORMAT_RGB555;
+	else
+	    data->format = 0;
+
+	// get pixels
+	GXDeviceInfo gxInfo = { 0 };
+	HDC hdc = GetDC(NULL);
+
+	gxInfo.Version = 100;
+	int result = ExtEscape(hdc, GETGXINFO, 0, NULL, sizeof(gxInfo), (char *) &gxInfo);
+	ReleaseDC(NULL, hdc);
+
+	if(result > 0)
+	{
+	    // more debug
+	    if(data->debug)
+	    {
+		printf("GXDeviceInfo.pvFrameBuffer:    %p\n", gxInfo.pvFrameBuffer);
+    		printf("GXDeviceInfo.cxWidth:          %d\n", gxInfo.cxWidth);
+    		printf("GXDeviceInfo.cyHeight:         %d\n", gxInfo.cyHeight);
+    		printf("GXDeviceInfo.cbStride:         %d\n", gxInfo.cbStride);
+    		printf("GXDeviceInfo.cBPP:             %d\n", gxInfo.cBPP);
+    		printf("GXDeviceInfo.ffFormat:        0x%x\n", gxInfo.ffFormat);
+
+    		printf("GXDeviceInfo.unk:\n");
+		int ii; for(ii = 0; ii <  sizeof(gxInfo.unknown); ++ii)
+		printf("0x%02hhX,", gxInfo.unknown[ii]);
+		printf("\n");
+	    }
+
+    	    if(gxInfo.ffFormat && gxInfo.ffFormat != gxProperties.ffFormat)
+	    {
+		if((gxInfo.ffFormat & kfDirect565) || 16 == gxInfo.cBPP)
+		    data->format = SDL_PIXELFORMAT_RGB565;
+		else
+		if((gxInfo.ffFormat & kfDirect555) || 15 == gxInfo.cBPP)
+		    data->format = SDL_PIXELFORMAT_RGB555;
+	    }
+
+    	    data->pixels = gxInfo.pvFrameBuffer;
         }
+	else
+	{
+	    data->flags |= FB_SKIP_OFFSET;
+	    data->pixels = data->gapi->GXBeginDraw();
+	    data->gapi->GXEndDraw();
+
+	    if(data->debug)
+	    {
+		printf("GAPI_Init\n");
+		printf("use GXBeginDraw:               %p\n", data->pixels);
+		printf("use skip offset\n");
+	    }
+	}
+
+	if(0 == data->format ||
+	    0 > WINCE_FixedGeometry(&data->fb, SDL_BYTESPERPIXEL(data->format), data->debug))
+	{
+	    SDL_SetError("GAPI_Init: unknown hardware");
+	    GAPI_Quit(data);
+	    return 0;
+	}
     }
 
-    GAPI_LOG("GAPI_RenderCopy blit\n");
-    /* If our framebuffer has an xPitch which matches the pixelsize, we
-       can convert the framebuffer to a SDL_surface and blit there,
-       otherwise, we have to use our own blitting routine
-     */
-    SDL_PixelFormatEnumToMasks(data->format, &bpp, &Rmask, &Gmask, &Bmask,
-                               &Amask);
-    bytespp = bpp >> 3;
-    if (data->xPitch == bytespp && 0) {
-        SDL_Surface *screen =
-            SDL_CreateRGBSurfaceFrom(data->data, data->w, data->h,
-                                     bpp, data->yPitch, Rmask, Gmask, Bmask,
-                                     Amask);
-        status =
-            SDL_UpperBlit((SDL_Surface *) texture->driverdata, srcrect,
-                          screen, dstrect);
-        SDL_FreeSurface(screen);
-    } else {                    /* screen is rotated, we have to blit on our own */
-        SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
+    return data->gapi && data->pixels ? 1 : 0;
+}
+
+void GAPI_Quit(WINCE_RenderData* data)
+{
+    if(data->gapi)
+    {
+	if(data->gapi->GXCloseDisplay) data->gapi->GXCloseDisplay(); 
+	if(data->gapi->hGapiLib)  FreeLibrary(data->gapi->hGapiLib);
+
+	SDL_free(data->gapi);
+        data->gapi = NULL;
+    }
+}
+
+int RAW_Init(WINCE_RenderData* data)
+{
+    const char* preferably = SDL_getenv("SDL_VIDEO_RENDERER");
+    if(preferably && 0 != SDL_strcasecmp(preferably, RAW_RENDER_NAME)) return 0;
+
+    RawFrameBufferInfo rfbi = { 0 };
+    HDC hdc = GetDC(NULL);
+    int result = ExtEscape(hdc, GETRAWFRAMEBUFFER, 0, NULL, sizeof(RawFrameBufferInfo), (char *) &rfbi);
+    ReleaseDC(NULL, hdc);
+
+    //disable
+    if(result == 0 || rfbi.pFramePointer == 0 ||
+    	rfbi.cxPixels == 0 || rfbi.cyPixels == 0 ||
+	rfbi.cxStride == 0 || rfbi.cyStride == 0) return 0;
+
+    data->flags     = FB_RAW_MODE;
+
+    // fill FrameBufferInfo
+    SDL_memset(&data->fb, 0, sizeof(FrameBufferInfo));
+
+    data->fb.xpitch = rfbi.cxStride;
+    data->fb.ypitch = rfbi.cyStride;
+    data->fb.width  = rfbi.cxPixels;
+    data->fb.height = rfbi.cyPixels;
+    data->fb.offset = 0;
 
-        char *src, *dst;
-        src = surface->pixels;
-        src += srcrect->y * surface->pitch + srcrect->x * 2;
+    if((FORMAT_565 & rfbi.wFormat) || 16 == rfbi.wBPP)
+	data->format = SDL_PIXELFORMAT_RGB565;
+    else
+    if((FORMAT_555 & rfbi.wFormat) || 15 == rfbi.wBPP)
+	data->format = SDL_PIXELFORMAT_RGB555;
+    else
+	data->format = 0;
+
+    if(0 == data->format ||
+	0 > WINCE_FixedGeometry(&data->fb, SDL_BYTESPERPIXEL(data->format), data->debug))
+    {
+	SDL_SetError("RAW_Init: unknown hardware");
+	RAW_Quit(data);
+	return 0;
+    }
+
+    data->pixels = rfbi.pFramePointer;
+
+    return data->pixels ? 1 : 0;
+}
+
+void RAW_Quit(WINCE_RenderData* data)
+{
+}
 
-        dst = data->data + data->offset;
-        dst += dstrect->y * data->yPitch + dstrect->x * data->xPitch;
+void FrameBufferInitialize(FrameBufferInfo* fb)
+{
+    int orientation = GetFrameBufferOrientation(fb);
+
+    // set correct start offset
+    switch(orientation)
+    {
+	case ORIENTATION_UP:
+	    fb->offset = 0;
+	    break;
 
-        updateLine16to16(src, 2, surface->pitch,
-                         dst, data->xPitch, data->yPitch,
-                         srcrect->w, srcrect->h);
+	case ORIENTATION_LEFT:
+	    fb->offset = __abs(fb->ypitch * (fb->height - 1));
+	    break;
 
+	case ORIENTATION_RIGHT:
+	    fb->offset = __abs(fb->xpitch * (fb->width - 1));
+	    break;
+
+	case ORIENTATION_DOWN:
+	    fb->offset = __abs(fb->xpitch * (fb->width - 1) +
+				fb->ypitch * (fb->height - 1));
+	    break;
+
+	default: break;
     }
 
-    Uint32 ticks = SDL_GetTicks();
-    if (data->usageFlags & USAGE_GX_FUNCS) {
-        gx.GXEndDraw();
+    //if(orientation != ORIENTATION_UP)
+    switch(orientation)
+    {
+	case ORIENTATION_LEFT: FrameBufferRotate(fb, ORIENTATION_RIGHT); break;
+	case ORIENTATION_RIGHT:FrameBufferRotate(fb, ORIENTATION_LEFT); break;
+	case ORIENTATION_DOWN: FrameBufferRotate(fb, ORIENTATION_DOWN); break;
+
+	default: break;
     }
-    GAPI_LOG("GAPI_RenderCopy %i\n", SDL_GetTicks() - ticks);
-    return status;
+}
+
+int GetFrameBufferOrientation(const FrameBufferInfo* src)
+{
+    if(src->xpitch > 0 && src->ypitch > 0)
+	return ORIENTATION_UP;
+    else
+    if(src->xpitch > 0 && src->ypitch < 0)
+	return ORIENTATION_LEFT;
+    else
+    if(src->xpitch < 0 && src->ypitch > 0)
+	return ORIENTATION_RIGHT;
+    else
+    if(src->xpitch < 0 && src->ypitch < 0)
+	return ORIENTATION_DOWN;
+
+    return ORIENTATION_UNKNOWN;
 }
 
-static void
-GAPI_RenderPresent(SDL_Renderer * renderer)
+void FrameBufferRotate(FrameBufferInfo* dst, int orientation)
 {
-    /* Nothing todo as we rendered directly to the screen on RenderCopy */
+    FrameBufferInfo src;
+    // copy dst -> src
+    SDL_memcpy(&src, dst, sizeof(FrameBufferInfo));
+
+    switch(orientation)
+    {
+        case ORIENTATION_LEFT:
+	    dst->width  = src.height;
+	    dst->height = src.width;
+	    dst->xpitch = src.ypitch;
+	    dst->ypitch = -src.xpitch;
+	    dst->offset = src.offset + src.xpitch * (src.width - 1);
+	    break;
+
+        case ORIENTATION_RIGHT:
+	    dst->width  = src.height;
+	    dst->height = src.width;
+	    dst->xpitch = -src.ypitch;
+	    dst->ypitch = src.xpitch;
+	    dst->offset = src.offset + src.ypitch * (src.height - 1);
+	    break;
+
+        case ORIENTATION_DOWN:
+	    FrameBufferRotate(dst, ORIENTATION_LEFT);
+	    FrameBufferRotate(dst, ORIENTATION_LEFT);
+	    break;
+
+        default:
+	    break;
+    }
+}
+
+void PointerRotate(POINT* pt, const FrameBufferInfo* fb, int orientation)
+{
+    switch(orientation)
+    {
+	case ORIENTATION_UP:
+	    break;
+
+	case ORIENTATION_LEFT:
+	{
+	    int temp = pt->y;
+	    pt->y = fb->height - pt->x;
+	    pt->x = temp;
+	}
+	    break;
+
+	case ORIENTATION_RIGHT:
+	{
+	    int temp = pt->x;
+	    pt->x = fb->width - pt->y;
+	    pt->y = temp;
+	}
+	    break;
+
+	case ORIENTATION_DOWN:
+	    pt->x = fb->width  - pt->x;
+	    pt->y = fb->height - pt->y;
+	    break;
+
+	default: break;
+    }
 }
 
-static void
-GAPI_DestroyRenderer(SDL_Renderer * renderer)
+const char* GetOrientationName(int orientation)
+{
+    switch(orientation)
+    {
+        case ORIENTATION_UP:        return "UP";
+        case ORIENTATION_DOWN:      return "DOWN";
+        case ORIENTATION_LEFT:      return "LEFT";
+        case ORIENTATION_RIGHT:     return "RIGHT";
+        default: break;
+    }
+
+    return "UNKNOWN";
+}
+
+int WINCE_GetDMOrientation(void)
 {
-    GAPI_RenderData *data = (GAPI_RenderData *) renderer->driverdata;
+    DEVMODE sDevMode = {0};
+    sDevMode.dmSize = sizeof(DEVMODE);
+    sDevMode.dmFields = DM_DISPLAYORIENTATION;
+
+    // DMDO_0, DMDO_90, DMDO_180, DMDO_270
+    if(DISP_CHANGE_BADMODE != ChangeDisplaySettingsEx(NULL, &sDevMode, 0, CDS_TEST, NULL))
+	switch(sDevMode.dmDisplayOrientation)
+	{
+	    case DMDO_0:	return DMDO_0;
+	    case DMDO_90:	return DMDO_90;
+	    case DMDO_180:	return DMDO_180;
+	    case DMDO_270:	return DMDO_270;
+	    default: break;
+	}
 
-    if (data->usageFlags & USAGE_GX_FUNCS) {
-        gx.GXCloseDisplay();
+    SDL_SetError("WINCE_GetDMOrientation: ChangeDisplaySettingsEx return BADMODE");
+    return -1;
+}
+
+int WINCE_SetDMOrientation(int orientation)
+{
+    DEVMODE sDevMode = {0};
+    sDevMode.dmSize = sizeof(DEVMODE);
+    sDevMode.dmFields = DM_DISPLAYORIENTATION;
+
+    switch(orientation)
+    {
+	case DMDO_0:	sDevMode.dmDisplayOrientation = DMDO_0;   break;
+	case DMDO_90:	sDevMode.dmDisplayOrientation = DMDO_90;  break;
+	case DMDO_180:	sDevMode.dmDisplayOrientation = DMDO_180; break;
+	case DMDO_270:	sDevMode.dmDisplayOrientation = DMDO_270; break;
+	default: return 0;
     }
 
-    if (data) {
-        SDL_free(data);
-    }
-    SDL_free(renderer);
+    if(DISP_CHANGE_BADMODE != ChangeDisplaySettingsEx(NULL, &sDevMode, 0, CDS_RESET, NULL))
+	return 1;
+
+    SDL_SetError("WINCE_SetDMOrientation: ChangeDisplaySettingsEx return BADMODE");
+    return -1;
+}
+
+void FrameBufferDumpInfo(const FrameBufferInfo* fb, const char* name)
+{
+    printf("%s fb.width:       %d\n", name, fb->width);
+    printf("%s fb.height:      %d\n", name, fb->height);
+    printf("%s fb.xpitch:      %d\n", name, fb->xpitch);
+    printf("%s fb.ypitch:      %d\n", name, fb->ypitch);
+    printf("%s fb.offset:      %d\n", name, fb->offset);
+
+    int orientation = GetFrameBufferOrientation(fb);
+    printf("%s fb.orientation: %d, %s\n", name, orientation, GetOrientationName(orientation));
 }
 
-#endif /* SDL_VIDEO_RENDER_GAPI */
+void UpdateLine16to16(const FrameBufferInfo* fb, const Uint16* src, Uint16* dst, Uint16 width)
+{
+    if(2 == fb->xpitch)
+    {
+	switch(width)
+	{
+	    case 1:
+		*dst = *src;
+		break;
+
+	    case 2:
+		*((Uint32*) dst) = *((Uint32*) src);
+		break;
 
-/* vi: set ts=4 sw=4 expandtab: */
+	    default:
+		SDL_memcpy(dst, src, width * 2);
+		break;
+	}
+    }
+    else
+    if(-2 == fb->xpitch)
+    {
+	while(width--)
+	    *dst-- = *src++;
+    }
+    else
+    {
+	while(width--)
+	{
+	    *dst = *src++;
+	    dst += fb->xpitch / 2;
+	}
+    }
+}
+
+#endif // SDL_VIDEO_RENDER_GAPI
--- a/src/video/win32/SDL_gapirender.h	Fri Jul 23 21:33:00 2010 -0700
+++ b/src/video/win32/SDL_gapirender.h	Tue Jul 27 21:31:28 2010 -0700
@@ -27,7 +27,11 @@
 /* SDL surface based renderer implementation */
 
 #if SDL_VIDEO_RENDER_GAPI
-extern void GAPI_AddRenderDriver(_THIS);
+extern void WINCE_AddRenderDriver(_THIS);
+extern int  WINCE_Available(void);
+extern void WINCE_ShowWindow(_THIS, SDL_Window* window, int visible);
+extern int  WINCE_GetDMOrientation(void);
+extern int  WINCE_SetDMOrientation(int orientation);
 #endif
 
 /* vi: set ts=4 sw=4 expandtab: */
--- a/src/video/win32/SDL_gapirender_c.h	Fri Jul 23 21:33:00 2010 -0700
+++ b/src/video/win32/SDL_gapirender_c.h	Tue Jul 27 21:31:28 2010 -0700
@@ -22,100 +22,3 @@
     Stefan Klug
     klug.stefan@gmx.de
 */
-
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-
-/* hi res definitions */
-typedef struct _RawFrameBufferInfo
-{
-    WORD wFormat;
-    WORD wBPP;
-    VOID *pFramePointer;
-    int cxStride;
-    int cyStride;
-    int cxPixels;
-    int cyPixels;
-} RawFrameBufferInfo;
-
-#define GETRAWFRAMEBUFFER   0x00020001
-
-#define FORMAT_565 1
-#define FORMAT_555 2
-#define FORMAT_OTHER 3
-
-
-/* From gx.h, since it's not really C compliant */
-
-struct GXDisplayProperties
-{
-    DWORD cxWidth;
-    DWORD cyHeight;             // notice lack of 'th' in the word height.
-    long cbxPitch;              // number of bytes to move right one x pixel - can be negative.
-    long cbyPitch;              // number of bytes to move down one y pixel - can be negative.
-    long cBPP;                  // # of bits in each pixel
-    DWORD ffFormat;             // format flags.
-};
-
-struct GXKeyList
-{
-    short vkUp;                 // key for up
-    POINT ptUp;                 // x,y position of key/button.  Not on screen but in screen coordinates.
-    short vkDown;
-    POINT ptDown;
-    short vkLeft;
-    POINT ptLeft;
-    short vkRight;
-    POINT ptRight;
-    short vkA;
-    POINT ptA;
-    short vkB;
-    POINT ptB;
-    short vkC;
-    POINT ptC;
-    short vkStart;
-    POINT ptStart;
-};
-
-typedef int (*PFNGXOpenDisplay) (HWND hWnd, DWORD dwFlags);
-typedef int (*PFNGXCloseDisplay) ();
-typedef void *(*PFNGXBeginDraw) ();
-typedef int (*PFNGXEndDraw) ();
-typedef int (*PFNGXOpenInput) ();
-typedef int (*PFNGXCloseInput) ();
-typedef struct GXDisplayProperties (*PFNGXGetDisplayProperties) ();
-typedef struct GXKeyList (*PFNGXGetDefaultKeys) (int iOptions);
-typedef int (*PFNGXSuspend) ();
-typedef int (*PFNGXResume) ();
-typedef int (*PFNGXSetViewport) (DWORD dwTop, DWORD dwHeight,
-                                 DWORD dwReserved1, DWORD dwReserved2);
-typedef BOOL(*PFNGXIsDisplayDRAMBuffer) ();
-
-struct GapiFunc
-{
-    PFNGXOpenDisplay GXOpenDisplay;
-    PFNGXCloseDisplay GXCloseDisplay;
-    PFNGXBeginDraw GXBeginDraw;
-    PFNGXEndDraw GXEndDraw;
-    PFNGXOpenInput GXOpenInput;
-    PFNGXCloseInput GXCloseInput;
-    PFNGXGetDisplayProperties GXGetDisplayProperties;
-    PFNGXGetDefaultKeys GXGetDefaultKeys;
-    PFNGXSuspend GXSuspend;
-    PFNGXResume GXResume;
-    PFNGXSetViewport GXSetViewport;
-    PFNGXIsDisplayDRAMBuffer GXIsDisplayDRAMBuffer;
-} gx;
-
-#define kfLandscape      0x8    // Screen is rotated 270 degrees
-#define kfPalette        0x10   // Pixel values are indexes into a palette
-#define kfDirect         0x20   // Pixel values contain actual level information
-#define kfDirect555      0x40   // 5 bits each for red, green and blue values in a pixel.
-#define kfDirect565      0x80   // 5 red bits, 6 green bits and 5 blue bits per pixel
-#define kfDirect888      0x100  // 8 bits each for red, green and blue values in a pixel.
-#define kfDirect444      0x200  // 4 red, 4 green, 4 blue
-#define kfDirectInverted 0x400
-
-#define GX_FULLSCREEN    0x01   // for OpenDisplay()
-#define GX_NORMALKEYS    0x02
-#define GX_LANDSCAPEKEYS        0x03
--- a/src/video/win32/SDL_gdirender.c	Fri Jul 23 21:33:00 2010 -0700
+++ b/src/video/win32/SDL_gdirender.c	Tue Jul 27 21:31:28 2010 -0700
@@ -184,6 +184,8 @@
         return NULL;
     }
 
+    windowdata->videodata->render = RENDER_GDI;
+
     renderer->DisplayModeChanged = GDI_DisplayModeChanged;
     renderer->CreateTexture = GDI_CreateTexture;
     renderer->QueryTexturePixels = GDI_QueryTexturePixels;
@@ -267,6 +269,34 @@
     }
     data->current_hbm = 0;
 
+#ifdef _WIN32_WCE
+    // check size for GDI fullscreen and rotate
+    if((window->flags & SDL_WINDOW_FULLSCREEN) &&
+        GetSystemMetrics(SM_CXSCREEN) != GetSystemMetrics(SM_CYSCREEN) &&
+        ((GetSystemMetrics(SM_CXSCREEN) < GetSystemMetrics(SM_CYSCREEN) && window->w > window->h) ||
+         (GetSystemMetrics(SM_CXSCREEN) > GetSystemMetrics(SM_CYSCREEN) && window->w < window->h)))
+    {
+	int orientation = WINCE_GetDMOrientation();
+	switch(orientation)
+	{
+	    case DMDO_0:   orientation = DMDO_90; break;
+	    case DMDO_270: orientation = DMDO_180; break;
+	    case DMDO_90:  orientation = DMDO_0; break;
+	    case DMDO_180: orientation = DMDO_270; break;
+
+	    default:
+		GDI_DestroyRenderer(renderer);
+		return NULL;
+	}
+
+	if(0 > WINCE_SetDMOrientation(orientation))
+	{
+	    GDI_DestroyRenderer(renderer);
+	    return NULL;
+	}
+    }
+#endif
+
     return renderer;
 }
 
@@ -416,6 +446,7 @@
         WIN_SetError("Couldn't create bitmap");
         return -1;
     }
+
     return 0;
 }
 
--- a/src/video/win32/SDL_win32clipboard.c	Fri Jul 23 21:33:00 2010 -0700
+++ b/src/video/win32/SDL_win32clipboard.c	Tue Jul 27 21:31:28 2010 -0700
@@ -95,7 +95,11 @@
                 WIN_SetError("Couldn't set clipboard data");
                 result = -1;
             }
+#ifdef _WIN32_WCE
+            data->clipboard_count = 0;
+#else
             data->clipboard_count = GetClipboardSequenceNumber();
+#endif
         }
         SDL_free(tstr);
 
@@ -149,7 +153,11 @@
 {
     DWORD count;
 
+#ifdef _WIN32_WCE
+    count = 0;
+#else
     count = GetClipboardSequenceNumber();
+#endif
     if (count != data->clipboard_count) {
         if (data->clipboard_count) {
             SDL_SendClipboardUpdate();
--- a/src/video/win32/SDL_win32events.c	Fri Jul 23 21:33:00 2010 -0700
+++ b/src/video/win32/SDL_win32events.c	Tue Jul 27 21:31:28 2010 -0700
@@ -184,6 +184,22 @@
         break;
 
 	case WM_MOUSEMOVE:
+#ifdef _WIN32_WCE
+	/* transform coords for VGA, WVGA... */
+	{
+	    SDL_VideoData *videodata = data->videodata;
+	    if(videodata->CoordTransform &&
+		(videodata->render == RENDER_GAPI || videodata->render == RENDER_RAW))
+	    {
+		POINT pt;
+		pt.x = LOWORD(lParam);
+		pt.y = HIWORD(lParam);
+		videodata->CoordTransform(data->window, &pt);
+    		SDL_SendMouseMotion(data->window, 0, pt.x, pt.y);
+		break;
+	    }
+	}
+#endif
         SDL_SendMouseMotion(data->window, 0, LOWORD(lParam), HIWORD(lParam));
         break;
 
--- a/src/video/win32/SDL_win32modes.c	Fri Jul 23 21:33:00 2010 -0700
+++ b/src/video/win32/SDL_win32modes.c	Tue Jul 27 21:31:28 2010 -0700
@@ -203,10 +203,18 @@
 {
     SDL_DisplayModeData *data = (SDL_DisplayModeData *) display->desktop_mode.driverdata;
 
+#ifdef _WIN32_WCE
+    // WINCE: DEVMODE.dmPosition not found, or may be mingw32ce bug
+    rect->x = 0;
+    rect->y = 0;
+    rect->w = display->windows->w;
+    rect->h = display->windows->h;
+#else
     rect->x = (int)data->DeviceMode.dmPosition.x;
     rect->y = (int)data->DeviceMode.dmPosition.y;
     rect->w = data->DeviceMode.dmPelsWidth;
     rect->h = data->DeviceMode.dmPelsHeight;
+#endif
     return 0;
 }
 
--- a/src/video/win32/SDL_win32video.c	Fri Jul 23 21:33:00 2010 -0700
+++ b/src/video/win32/SDL_win32video.c	Tue Jul 27 21:31:28 2010 -0700
@@ -30,6 +30,7 @@
 #include "SDL_win32video.h"
 #include "SDL_d3drender.h"
 #include "SDL_gdirender.h"
+#include "SDL_gapirender.h"
 
 /* Initialization/Query functions */
 static int WIN_VideoInit(_THIS);
@@ -48,6 +49,7 @@
     SDL_free(message);
 }
 
+
 /* WIN32 driver bootstrap functions */
 
 static int
@@ -74,6 +76,11 @@
         FreeLibrary(data->ddrawDLL);
     }
 #endif
+#ifdef _WIN32_WCE
+    if(data->hAygShell) {
+       FreeLibrary(data->hAygShell);
+    }
+#endif
     SDL_free(device->driverdata);
     SDL_free(device);
 }
@@ -138,6 +145,15 @@
     }
 #endif /* SDL_VIDEO_RENDER_DDRAW */
 
+#ifdef _WIN32_WCE
+    data->hAygShell = LoadLibrary(TEXT("\\windows\\aygshell.dll"));
+    if(0 == data->hAygShell)
+        data->hAygShell = LoadLibrary(TEXT("aygshell.dll"));
+    data->SHFullScreen = (0 != data->hAygShell ?
+        (PFNSHFullScreen) GetProcAddress(data->hAygShell, TEXT("SHFullScreen")) : 0);
+    data->CoordTransform = NULL;
+#endif
+
     /* Set the function pointers */
     device->VideoInit = WIN_VideoInit;
     device->VideoQuit = WIN_VideoQuit;
@@ -186,10 +202,13 @@
 }
 
 VideoBootStrap WIN32_bootstrap = {
+#ifdef _WIN32_WCE
+    "wince", "SDL WinCE video driver", WINCE_Available, WIN_CreateDevice
+#else
     "win32", "SDL Win32/64 video driver", WIN_Available, WIN_CreateDevice
+#endif
 };
 
-
 int
 WIN_VideoInit(_THIS)
 {
@@ -207,7 +226,7 @@
     GDI_AddRenderDriver(_this);
 #endif
 #if SDL_VIDEO_RENDER_GAPI
-    GAPI_AddRenderDriver(_this);
+    WINCE_AddRenderDriver(_this);
 #endif
 
     WIN_InitKeyboard(_this);
--- a/src/video/win32/SDL_win32video.h	Fri Jul 23 21:33:00 2010 -0700
+++ b/src/video/win32/SDL_win32video.h	Tue Jul 27 21:31:28 2010 -0700
@@ -28,7 +28,9 @@
 
 #define WIN32_LEAN_AND_MEAN
 #define STRICT
+#ifndef UNICODE
 #define UNICODE
+#endif
 #undef WINVER
 #define WINVER  0x500           /* Need 0x410 for AlphaBlend() and 0x500 for EnumDisplayDevices() */
 #include <windows.h>
@@ -63,10 +65,17 @@
 #endif
 extern void WIN_SetError(const char *prefix);
 
+enum { RENDER_NONE, RENDER_D3D, RENDER_DDRAW, RENDER_GDI, RENDER_GAPI, RENDER_RAW };
+
+typedef BOOL  (*PFNSHFullScreen)(HWND, DWORD);
+typedef void  (*PFCoordTransform)(SDL_Window*, POINT*);
+
 /* Private display data */
 
 typedef struct SDL_VideoData
 {
+    int render;
+
 #if SDL_VIDEO_RENDER_D3D
     HANDLE d3dDLL;
     IDirect3D9 *d3d;
@@ -75,6 +84,11 @@
     HANDLE ddrawDLL;
     IDirectDraw *ddraw;
 #endif
+#ifdef _WIN32_WCE
+    HMODULE hAygShell;
+    PFNSHFullScreen SHFullScreen;
+    PFCoordTransform CoordTransform;
+#endif
 
     DWORD clipboard_count;
 
--- a/src/video/win32/SDL_win32window.c	Fri Jul 23 21:33:00 2010 -0700
+++ b/src/video/win32/SDL_win32window.c	Tue Jul 27 21:31:28 2010 -0700
@@ -34,44 +34,12 @@
 #include "../../events/SDL_keyboard_c.h"
 
 #include "SDL_win32video.h"
+#include "SDL_win32window.h"
 
 /* This is included after SDL_win32video.h, which includes windows.h */
 #include "SDL_syswm.h"
-
-
-#define SHFS_SHOWTASKBAR            0x0001
-#define SHFS_HIDETASKBAR            0x0002
-#define SHFS_SHOWSIPBUTTON          0x0004
-#define SHFS_HIDESIPBUTTON          0x0008
-#define SHFS_SHOWSTARTICON          0x0010
-#define SHFS_HIDESTARTICON          0x0020
-
-#ifdef _WIN32_WCE
-// dynamically load aygshell dll because we want SDL to work on HPC and be300
-int aygshell_loaded = 0;
-BOOL(WINAPI * SHFullScreen) (HWND hwndRequester, DWORD dwState) = 0;
-
+#include "SDL_gapirender.h"
 
-static BOOL
-CE_SHFullScreen(HWND hwndRequester, DWORD dwState)
-{
-    if (SHFullScreen == 0 && aygshell_loaded == 0) {
-        aygshell_loaded = 0;
-        void *lib = SDL_LoadObject("aygshell.dll");
-        if (lib) {
-            SHFullScreen =
-                (BOOL(WINAPI *) (HWND, DWORD)) SDL_LoadFunction(lib,
-                                                                "SHFullScreen");
-        }
-    }
-
-    if (SHFullScreen) {
-        SHFullScreen(hwndRequester, dwState);
-        //printf("SHFullscreen(%i)\n",dwState);
-    }
-}
-
-#endif
 
 /* Fake window to help with DirectInput events. */
 HWND SDL_HelperWindow = NULL;
@@ -472,32 +440,22 @@
 void
 WIN_ShowWindow(_THIS, SDL_Window * window)
 {
+#ifdef _WIN32_WCE
+    WINCE_ShowWindow(_this, window, 1);
+#else
     HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
-
     ShowWindow(hwnd, SW_SHOW);
-
-#ifdef _WIN32_WCE
-    if (window->flags & SDL_WINDOW_FULLSCREEN) {
-        CE_SHFullScreen(hwnd,
-                        SHFS_HIDESTARTICON | SHFS_HIDETASKBAR |
-                        SHFS_HIDESIPBUTTON);
-    }
 #endif
 }
 
 void
 WIN_HideWindow(_THIS, SDL_Window * window)
 {
+#ifdef _WIN32_WCE
+    WINCE_ShowWindow(_this, window, 0);
+#else
     HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
-
     ShowWindow(hwnd, SW_HIDE);
-
-#ifdef _WIN32_WCE
-    if (window->flags & SDL_WINDOW_FULLSCREEN) {
-        CE_SHFullScreen(hwnd,
-                        SHFS_SHOWSTARTICON | SHFS_SHOWTASKBAR |
-                        SHFS_SHOWSIPBUTTON);
-    }
 #endif
 }
 
@@ -513,45 +471,33 @@
         top = HWND_NOTOPMOST;
     }
     SetWindowPos(hwnd, top, 0, 0, 0, 0, (SWP_NOMOVE | SWP_NOSIZE));
-
-#ifdef _WIN32_WCE
-    if (window->flags & SDL_WINDOW_FULLSCREEN) {
-        CE_SHFullScreen(hwnd,
-                        SHFS_HIDESTARTICON | SHFS_HIDETASKBAR |
-                        SHFS_HIDESIPBUTTON);
-    }
-#endif
 }
 
 void
 WIN_MaximizeWindow(_THIS, SDL_Window * window)
 {
     HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
-
-    ShowWindow(hwnd, SW_MAXIMIZE);
+    SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
 
 #ifdef _WIN32_WCE
-    if (window->flags & SDL_WINDOW_FULLSCREEN) {
-        CE_SHFullScreen(hwnd,
-                        SHFS_HIDESTARTICON | SHFS_HIDETASKBAR |
-                        SHFS_HIDESIPBUTTON);
-    }
+    if((window->flags & SDL_WINDOW_FULLSCREEN) && videodata->SHFullScreen)
+        videodata->SHFullScreen(hwnd, SHFS_HIDETASKBAR | SHFS_HIDESTARTICON | SHFS_HIDESIPBUTTON);
 #endif
+
+    ShowWindow(hwnd, SW_MAXIMIZE);
 }
 
 void
 WIN_MinimizeWindow(_THIS, SDL_Window * window)
 {
     HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
+    SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
 
     ShowWindow(hwnd, SW_MINIMIZE);
 
 #ifdef _WIN32_WCE
-    if (window->flags & SDL_WINDOW_FULLSCREEN) {
-        CE_SHFullScreen(hwnd,
-                        SHFS_SHOWSTARTICON | SHFS_SHOWTASKBAR |
-                        SHFS_SHOWSIPBUTTON);
-    }
+    if((window->flags & SDL_WINDOW_FULLSCREEN) && videodata->SHFullScreen)
+	videodata->SHFullScreen(hwnd, SHFS_SHOWTASKBAR | SHFS_SHOWSTARTICON | SHFS_SHOWSIPBUTTON);
 #endif
 }
 
@@ -586,6 +532,9 @@
     SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
 
     if (data) {
+#ifdef _WIN32_WCE
+	WINCE_ShowWindow(_this, window, 0);
+#endif
         ReleaseDC(data->hwnd, data->hdc);
         if (data->created) {
             DestroyWindow(data->hwnd);
--- a/src/video/win32/SDL_win32window.h	Fri Jul 23 21:33:00 2010 -0700
+++ b/src/video/win32/SDL_win32window.h	Tue Jul 27 21:31:28 2010 -0700
@@ -24,6 +24,15 @@
 #ifndef _SDL_win32window_h
 #define _SDL_win32window_h
 
+#ifdef _WIN32_WCE
+#define SHFS_SHOWTASKBAR        0x0001
+#define SHFS_HIDETASKBAR        0x0002
+#define SHFS_SHOWSIPBUTTON      0x0004
+#define SHFS_HIDESIPBUTTON      0x0008
+#define SHFS_SHOWSTARTICON      0x0010
+#define SHFS_HIDESTARTICON      0x0020
+#endif
+
 typedef struct
 {
     SDL_Window *window;