diff -Nru /tmp/SDL-1.2.6/include/SDL_audio.h SDL-1.2.6/include/SDL_audio.h
--- /tmp/SDL-1.2.6/include/SDL_audio.h	2002-06-08 20:42:11.000000000 +0300
+++ SDL-1.2.6/include/SDL_audio.h	2006-05-14 20:34:40.000000000 +0300
@@ -53,6 +53,7 @@
 	Uint16 samples;		/* Audio buffer size in samples (power of 2) */
 	Uint16 padding;		/* Necessary for some compile environments */
 	Uint32 size;		/* Audio buffer size in bytes (calculated) */
+	Uint8  thread_priority; /* Thread priority */
 	/* This function is called when the audio device needs more data.
 	   'stream' is a pointer to the audio data buffer
 	   'len' is the length of that buffer in bytes.
diff -Nru /tmp/SDL-1.2.6/include/SDL_video.h SDL-1.2.6/include/SDL_video.h
--- /tmp/SDL-1.2.6/include/SDL_video.h	2003-08-30 22:13:00.000000000 +0300
+++ SDL-1.2.6/include/SDL_video.h	2006-05-22 22:52:30.000000000 +0300
@@ -145,7 +145,8 @@
 #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	0x01000000	/* Surface uses preallocated memory */
+#define SDL_PREALLOC	0x01000000	/* Surface uses preallocated memory */
+#define SDL_FLIPVIDEO	0x00100000	/* wince: flip landscape */
 
 /* Evaluates to true if the surface needs to be locked before access */
 #define SDL_MUSTLOCK(surface)	\
diff -Nru /tmp/SDL-1.2.6/Makefile SDL-1.2.6/Makefile
--- /tmp/SDL-1.2.6/Makefile	1970-01-01 02:00:00.000000000 +0200
+++ SDL-1.2.6/Makefile	2006-10-08 13:30:31.000000000 +0300
@@ -0,0 +1,27 @@
+#CC = arm-wince-pe-g++
+CC = arm-wince-pe-gcc
+CFLAGS = -Iinclude -Isrc/audio -Isrc/cdrom -Isrc/timer -Isrc/joystick -Isrc/events -Isrc/video -Isrc/thread -Isrc/thread/win32 -Isrc -Isrc/video/wincommon -Isrc/video/windib -D__cdecl= -UWM_GETMINMAXINFO -UWS_MAXIMIZE
+CFLAGS += -D_WIN32_WCE=300 -DARM -D_ARM_ -D__ARM__ -DUNICODE -D_UNICODE -DNO_SIGNAL_H -DENABLE_WINDIB -DENABLE_WINGAPI -D_FORCE_CE_SEMAPHORE -DWIN32 -DGCC_BUILD #-D_CRTBLD
+#CFLAGS += -DDEBUG -g
+CFLAGS += -O2
+
+OBJS = src/audio/SDL_audio.o src/audio/SDL_audiocvt.o src/audio/SDL_audiodev.o src/audio/SDL_audiomem.o src/audio/SDL_mixer.o src/audio/SDL_wave.o
+OBJS += src/audio/windib/SDL_dibaudio.o 
+OBJS += src/cdrom/SDL_cdrom.o src/cdrom/win32/SDL_syscdrom.o src/endian/SDL_endian.o src/events/SDL_active.o src/events/SDL_events.o src/events/SDL_expose.o
+OBJS += src/events/SDL_keyboard.o src/events/SDL_mouse.o src/events/SDL_quit.o src/events/SDL_resize.o src/file/SDL_rwops.o src/joystick/SDL_joystick.o
+OBJS += src/joystick/win32/SDL_mmjoystick.o src/thread/win32/SDL_sysmutex.o src/thread/win32/SDL_syssem.o src/thread/win32/SDL_systhread.o
+OBJS += src/thread/SDL_thread.o src/thread/win32/win_ce_semaphore.o src/timer/win32/SDL_systimer.o src/timer/SDL_timer.o src/video/windib/SDL_dibevents.o
+OBJS += src/video/windib/SDL_dibvideo.o src/video/wincommon/SDL_sysevents.o src/video/wincommon/SDL_sysmouse.o src/video/wincommon/SDL_syswm.o
+OBJS += src/video/wingapi/SDL_gapivideo.o src/video/SDL_blit.o src/video/SDL_blit_0.o src/video/SDL_blit_1.o src/video/SDL_blit_A.o
+OBJS += src/video/SDL_blit_N.o src/video/SDL_bmp.o src/video/SDL_cursor.o src/video/SDL_gamma.o src/video/SDL_pixels.o src/video/SDL_RLEaccel.o
+OBJS += src/video/SDL_stretch.o src/video/SDL_surface.o src/video/SDL_video.o src/video/SDL_yuv.o src/video/SDL_yuv_mmx.o src/video/SDL_yuv_sw.o
+OBJS += src/main/win32/SDL_main.o src/SDL.o src/SDL_error.o src/SDL_fatal.o src/SDL_getenv.o src/SDL_loadso.o 
+
+all : libSDL.lib
+
+libSDL.lib : $(OBJS)
+	arm-wince-pe-ar cru $@ $^
+	arm-wince-pe-ranlib $@
+
+clean : 
+	rm `find . -name *.o`
diff -Nru /tmp/SDL-1.2.6/src/audio/SDL_audio.c SDL-1.2.6/src/audio/SDL_audio.c
--- /tmp/SDL-1.2.6/src/audio/SDL_audio.c	2003-08-30 22:13:00.000000000 +0300
+++ SDL-1.2.6/src/audio/SDL_audio.c	2006-07-10 16:37:22.000000000 +0300
@@ -453,7 +453,7 @@
 	}
 
 	/* Allocate a fake audio memory buffer */
-	audio->fake_stream = SDL_AllocAudioMem(audio->spec.size);
+	audio->fake_stream = (Uint8 *) SDL_AllocAudioMem(audio->spec.size);
 	if ( audio->fake_stream == NULL ) {
 		SDL_CloseAudio();
 		SDL_OutOfMemory();
diff -Nru /tmp/SDL-1.2.6/src/audio/windib/SDL_dibaudio.c SDL-1.2.6/src/audio/windib/SDL_dibaudio.c
--- /tmp/SDL-1.2.6/src/audio/windib/SDL_dibaudio.c	2002-06-08 20:45:38.000000000 +0300
+++ SDL-1.2.6/src/audio/windib/SDL_dibaudio.c	2006-07-10 21:59:51.000000000 +0300
@@ -40,6 +40,7 @@
 #if defined(_WIN32_WCE) && (_WIN32_WCE < 300)
 #include "win_ce_semaphore.h"
 #endif
+#undef waveOutGetErrorText
 
 
 /* Audio driver functions */
@@ -147,7 +148,7 @@
 /* Set high priority for the audio thread */
 static void DIB_ThreadInit(_THIS)
 {
-	SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
+	SetThreadPriority(GetCurrentThread(), this->hidden->thread_priority);
 }
 
 void DIB_WaitAudio(_THIS)
@@ -229,6 +230,10 @@
 	int i;
 	WAVEFORMATEX waveformat;
 
+	this->hidden->thread_priority = spec->thread_priority;
+	if (this->hidden->thread_priority <= 0)
+		this->hidden->thread_priority = THREAD_PRIORITY_NORMAL;
+
 	/* Initialize the wavebuf structures for closing */
 	sound = NULL;
 	audio_sem = NULL;
diff -Nru /tmp/SDL-1.2.6/src/audio/windib/SDL_dibaudio.h SDL-1.2.6/src/audio/windib/SDL_dibaudio.h
--- /tmp/SDL-1.2.6/src/audio/windib/SDL_dibaudio.h	2002-06-08 20:45:38.000000000 +0300
+++ SDL-1.2.6/src/audio/windib/SDL_dibaudio.h	2006-05-14 20:34:40.000000000 +0300
@@ -41,6 +41,7 @@
 	Uint8 *mixbuf;		/* The raw allocated mixing buffer */
 	WAVEHDR wavebuf[NUM_BUFFERS];	/* Wave audio fragments */
 	int next_buffer;
+	Uint8 thread_priority; /* Thread priority */
 };
 
 /* Old variable names */
diff -Nru /tmp/SDL-1.2.6/src/cdrom/win32/SDL_syscdrom.c SDL-1.2.6/src/cdrom/win32/SDL_syscdrom.c
--- /tmp/SDL-1.2.6/src/cdrom/win32/SDL_syscdrom.c	2002-06-08 20:45:39.000000000 +0300
+++ SDL-1.2.6/src/cdrom/win32/SDL_syscdrom.c	2006-05-14 20:34:40.000000000 +0300
@@ -30,12 +30,30 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <windows.h>
+#ifndef _WIN32_WCE
 #include <mmsystem.h>
+#endif
 
 #include "SDL_error.h"
 #include "SDL_cdrom.h"
+
+#ifdef _WIN32_WCE
+
+int SDL_SYS_CDInit() {
+	return 0;
+}
+
+static void SDL_SYS_CDClose(SDL_CD *cdrom) {
+}
+
+void SDL_SYS_CDQuit(void) {
+}
+
+#else
+
 #include "SDL_syscdrom.h"
 
+
 /* This really broken?? */
 #define BROKEN_MCI_PAUSE	/* Pausing actually stops play -- Doh! */
 
@@ -384,3 +402,5 @@
 		SDL_numcds = 0;
 	}
 }
+
+#endif
\ No newline at end of file
diff -Nru /tmp/SDL-1.2.6/src/joystick/win32/SDL_mmjoystick.c SDL-1.2.6/src/joystick/win32/SDL_mmjoystick.c
--- /tmp/SDL-1.2.6/src/joystick/win32/SDL_mmjoystick.c	2003-08-30 22:13:05.000000000 +0300
+++ SDL-1.2.6/src/joystick/win32/SDL_mmjoystick.c	2006-05-14 20:34:40.000000000 +0300
@@ -36,6 +36,39 @@
 #include "SDL_joystick_c.h"
 
 #include <windows.h>
+
+#ifdef _WIN32_WCE
+
+int SDL_SYS_JoystickInit(void)
+{
+	return 0;
+}
+
+void SDL_SYS_JoystickClose(SDL_Joystick *joystick) 
+{
+}
+
+const char *SDL_SYS_JoystickName(int index)
+{
+	return NULL;
+}
+
+int SDL_SYS_JoystickOpen(SDL_Joystick *joystick)
+{
+	return 0;
+}
+
+void SDL_SYS_JoystickQuit(void)
+{
+	return;
+}
+
+void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick)
+{
+}
+
+#else
+
 #include <mmsystem.h>
 
 #define MAX_JOYSTICKS	16
@@ -336,3 +369,5 @@
 	}
 	SDL_SetError("%s", errbuf);
 }
+
+#endif
\ No newline at end of file
diff -Nru /tmp/SDL-1.2.6/src/main/win32/SDL_main.c SDL-1.2.6/src/main/win32/SDL_main.c
--- /tmp/SDL-1.2.6/src/main/win32/SDL_main.c	2003-08-30 22:13:05.000000000 +0300
+++ SDL-1.2.6/src/main/win32/SDL_main.c	2006-09-16 21:11:21.000000000 +0300
@@ -15,8 +15,8 @@
 #ifdef _WIN32_WCE
 # define DIR_SEPERATOR TEXT("\\")
 # define _getcwd(str,len)	wcscpy(str,DIR_SEPERATOR);
-# define setbuf(x)
-# define setvbuf(x)
+# define setbuf(x,y)
+# define setvbuf(x,y,z,w)
 # define fopen		_wfopen
 # define freopen	_wfreopen
 # define remove(x)	DeleteFile(x)
@@ -218,9 +218,12 @@
 	if ( SDL_Init(SDL_INIT_NOPARACHUTE) < 0 ) {
 		ShowError("WinMain() error", SDL_GetError());
 		return(FALSE);
-	}
+	}
+
+#if defined(_WIN32_WCE) && (!defined(GCC_BUILD) && !defined(__GNUC__))
 	atexit(cleanup_output);
-	atexit(SDL_Quit);
+	atexit(SDL_Quit);
+#endif
 
 #ifndef DISABLE_VIDEO
 #if 0
@@ -325,13 +328,17 @@
 	setbuf(stderr, NULL);			/* No buffering */
 #endif /* !NO_STDIO_REDIRECT */
 
-#ifdef _WIN32_WCE
-	nLen = wcslen(szCmdLine)+128+1;
-	bufp = (wchar_t *)alloca(nLen*2);
-	wcscpy (bufp, TEXT("\""));
-	GetModuleFileName(NULL, bufp+1, 128-3);
-	wcscpy (bufp+wcslen(bufp), TEXT("\" "));
-	wcsncpy(bufp+wcslen(bufp), szCmdLine,nLen-wcslen(bufp));
+#ifdef _WIN32_WCE
+	if (wcsncmp(szCmdLine, TEXT("\\"), 1)) {
+		nLen = wcslen(szCmdLine)+128+1;
+		bufp = (wchar_t *)alloca(nLen*2);
+		wcscpy (bufp, TEXT("\""));
+		GetModuleFileName(NULL, bufp+1, 128-3);
+		wcscpy (bufp+wcslen(bufp), TEXT("\" "));
+		wcsncpy(bufp+wcslen(bufp), szCmdLine,nLen-wcslen(bufp));
+	} else
+		bufp = szCmdLine;
+
 	nLen = wcslen(bufp)+1;
 	cmdline = (char *)alloca(nLen);
 	if ( cmdline == NULL ) {
diff -Nru /tmp/SDL-1.2.6/src/thread/win32/win_ce_semaphore.c SDL-1.2.6/src/thread/win32/win_ce_semaphore.c
--- /tmp/SDL-1.2.6/src/thread/win32/win_ce_semaphore.c	2001-05-24 02:35:09.000000000 +0300
+++ SDL-1.2.6/src/thread/win32/win_ce_semaphore.c	2006-09-10 02:46:35.000000000 +0300
@@ -59,17 +59,19 @@
 {
    SYNCHHANDLE hSynch = NULL, result = NULL;
 
-   __try
+//   __try
 	{
       if (lInitialCount > lMaximumCount || lMaximumCount < 0 || lInitialCount < 0) 
 	  {
               /* Bad parameters */
          SetLastError (SYNCH_ERROR);
-         __leave;
+//         __leave;
+         return CleanUp(hSynch, 6);
       }
 
       hSynch = HeapAlloc (GetProcessHeap(), HEAP_ZERO_MEMORY, SYNCH_HANDLE_SIZE);
-      if (hSynch == NULL) __leave;
+//      if (hSynch == NULL) __leave;
+      if (hSynch == NULL) return CleanUp(hSynch, 6);
 
       hSynch->MaxCount = lMaximumCount;
       hSynch->CurCount = lInitialCount;
@@ -85,12 +87,12 @@
       ReleaseMutex (hSynch->hMutex);
       hSynch->hSemph = NULL;
    }
-   __finally
-   {
-       /* Return with the handle, or, if there was any error, return
-        a null after closing any open handles and freeing any allocated memory. */
+//   __finally
+//   {
+//       /* Return with the handle, or, if there was any error, return
+//        a null after closing any open handles and freeing any allocated memory. */
       result=CleanUp(hSynch, 6 /* An event and a mutex, but no semaphore. */);
-   }
+//   }
 
    return result;
 }
@@ -103,7 +105,7 @@
    /* Gain access to the object to assure that the release count
       would not cause the total count to exceed the maximum. */
 
-   __try 
+//   __try 
    {
       WaitForSingleObject (hSemCE->hMutex, INFINITE);
 	  /* reply only if asked to */	
@@ -113,7 +115,9 @@
 	  {
          SetLastError (SYNCH_ERROR);
          Result = FALSE;
-         __leave;
+//         __leave;
+	 ReleaseMutex (hSemCE->hMutex);
+         return Result;
       }
       hSemCE->CurCount += cReleaseCount;
 
@@ -122,10 +126,10 @@
 
       SetEvent (hSemCE->hEvent);
    }
-   __finally
-   {
+//   __finally
+//   {
       ReleaseMutex (hSemCE->hMutex);
-   }
+//   }
 
    return Result;
 }
diff -Nru /tmp/SDL-1.2.6/src/video/SDL_RLEaccel.c SDL-1.2.6/src/video/SDL_RLEaccel.c
--- /tmp/SDL-1.2.6/src/video/SDL_RLEaccel.c	2003-08-30 22:13:06.000000000 +0300
+++ SDL-1.2.6/src/video/SDL_RLEaccel.c	2006-05-14 20:34:40.000000000 +0300
@@ -102,6 +102,28 @@
 #include "SDL_memops.h"
 #include "SDL_RLEaccel_c.h"
 
+#if defined(_WIN32_WCE) && (_WIN32_WCE < 300) && defined(ARM)
+
+/* Crashes the compiler otherwise !!! */
+
+int SDL_RLESurface(SDL_Surface *surface) {
+	return -1;
+}
+
+int SDL_RLEBlit(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect) {
+	return -1;
+}
+
+int SDL_RLEAlphaBlit(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect) {
+	return -1;
+}
+
+void SDL_UnRLESurface(SDL_Surface *surface, int recode) {
+}
+
+#else
+
+
 #if defined(i386) && defined(__GNUC__) && defined(USE_ASMBLIT)
 #include "mmx.h"
 /* Function to check the CPU flags */
@@ -1938,4 +1960,4 @@
     }
 }
 
-
+#endif // HPC workaround
diff -Nru /tmp/SDL-1.2.6/src/video/SDL_sysvideo.h SDL-1.2.6/src/video/SDL_sysvideo.h
--- /tmp/SDL-1.2.6/src/video/SDL_sysvideo.h	2003-08-30 22:13:07.000000000 +0300
+++ SDL-1.2.6/src/video/SDL_sysvideo.h	2006-05-14 20:34:40.000000000 +0300
@@ -362,6 +362,9 @@
 #ifdef ENABLE_WINDIB
 extern VideoBootStrap WINDIB_bootstrap;
 #endif
+#ifdef ENABLE_WINGAPI
+extern VideoBootStrap WINGAPI_bootstrap;
+#endif
 #ifdef ENABLE_DIRECTX
 extern VideoBootStrap DIRECTX_bootstrap;
 #endif
diff -Nru /tmp/SDL-1.2.6/src/video/SDL_video.c SDL-1.2.6/src/video/SDL_video.c
--- /tmp/SDL-1.2.6/src/video/SDL_video.c	2003-08-30 22:13:07.000000000 +0300
+++ SDL-1.2.6/src/video/SDL_video.c	2006-05-14 20:34:40.000000000 +0300
@@ -81,6 +81,9 @@
 #ifdef ENABLE_DIRECTX
 	&DIRECTX_bootstrap,
 #endif
+#ifdef ENABLE_WINGAPI
+	&WINGAPI_bootstrap,
+#endif
 #ifdef ENABLE_WINDIB
 	&WINDIB_bootstrap,
 #endif
@@ -856,6 +859,7 @@
 				(SDL_VideoSurface->flags&SDL_HWSURFACE) &&
 				!(SDL_VideoSurface->flags&SDL_DOUBLEBUF))
 	     ) ) {
+
 		SDL_CreateShadowSurface(bpp);
 		if ( SDL_ShadowSurface == NULL ) {
 			SDL_SetError("Couldn't create shadow surface");
diff -Nru /tmp/SDL-1.2.6/src/video/wincommon/SDL_sysevents.c SDL-1.2.6/src/video/wincommon/SDL_sysevents.c
--- /tmp/SDL-1.2.6/src/video/wincommon/SDL_sysevents.c	2003-08-30 22:13:12.000000000 +0300
+++ SDL-1.2.6/src/video/wincommon/SDL_sysevents.c	2006-07-10 22:11:27.000000000 +0300
@@ -41,6 +41,8 @@
 #include "SDL_syswm_c.h"
 #include "SDL_main.h"
 
+#include "SDL_dibvideo.h"
+
 #ifdef WMMSG_DEBUG
 #include "wmmsg.h"
 #endif
@@ -53,6 +55,7 @@
 /* The window we use for everything... */
 #ifdef _WIN32_WCE
 LPWSTR SDL_Appname = NULL;
+#undef WM_GETMINMAXINFO
 #else
 LPSTR SDL_Appname = NULL;
 #endif
@@ -172,6 +175,37 @@
 #endif /* !NO_GETKEYBOARDSTATE */
 }
 
+void transform(SDL_RotateAttr rotate, char ozone, Sint16 *x, Sint16 *y) {
+	Sint16 rotatedX;
+	Sint16 rotatedY;
+
+	if (ozone) {
+		*x = *x * 2;
+		*y = *y * 2;
+	}
+
+	switch(rotate) {
+		case SDL_ROTATE_NONE:
+			break;
+		case SDL_ROTATE_LEFT:
+			if (!SDL_VideoSurface)
+				break;
+			rotatedX = SDL_VideoSurface->w - *y;
+			rotatedY = *x;
+			*x = rotatedX;
+			*y = rotatedY;
+			break;
+		case SDL_ROTATE_RIGHT:
+			if (!SDL_VideoSurface)
+				break;
+			rotatedX = *y;
+			rotatedY = SDL_VideoSurface->h - *x;
+			*x = rotatedX;
+			*y = rotatedY;
+			break;
+	}
+}
+
 /* The main Win32 event handler
 DJM: This is no longer static as (DX5/DIB)_CreateWindow needs it
 */
@@ -180,6 +214,7 @@
 	SDL_VideoDevice *this = current_video;
 	static int mouse_pressed = 0;
 	static int in_window = 0;
+
 #ifdef WMMSG_DEBUG
 	fprintf(stderr, "Received windows message:  ");
 	if ( msg > MAX_WMMSG ) {
@@ -272,6 +307,8 @@
 						posted = SDL_PrivateMouseMotion(0, 1, x, y);
 					}
 				} else {
+					if (SDL_VideoSurface)
+						transform(rotation, ozoneHack, &x, &y);
 					posted = SDL_PrivateMouseMotion(0, 0, x, y);
 				}
 			}
@@ -360,7 +397,13 @@
 				} else {
 					x = (Sint16)LOWORD(lParam);
 					y = (Sint16)HIWORD(lParam);
+					if (SDL_VideoSurface)
+						transform(rotation, ozoneHack, &x, &y);
 				}
+#ifdef _WIN32_WCE
+				/* Since stylus movements are not continuous */
+				posted = SDL_PrivateMouseMotion(0, 0, x, y);
+#endif
 				posted = SDL_PrivateMouseButton(
 							state, button, x, y);
 			}
diff -Nru /tmp/SDL-1.2.6/src/video/wincommon/SDL_sysmouse.c SDL-1.2.6/src/video/wincommon/SDL_sysmouse.c
--- /tmp/SDL-1.2.6/src/video/wincommon/SDL_sysmouse.c	2003-08-30 22:13:12.000000000 +0300
+++ SDL-1.2.6/src/video/wincommon/SDL_sysmouse.c	2006-05-14 20:34:40.000000000 +0300
@@ -251,6 +251,7 @@
 /* Check to see if we need to enter or leave mouse relative mode */
 void WIN_CheckMouseMode(_THIS)
 {
+#ifndef _WIN32_WCE
         /* If the mouse is hidden and input is grabbed, we use relative mode */
         if ( !(SDL_cursorstate & CURSOR_VISIBLE) &&
              (this->input_grab != SDL_GRAB_OFF) ) {
@@ -258,4 +259,7 @@
         } else {
                 mouse_relative = 0;
         }
+#else
+		mouse_relative =  0;
+#endif
 }
diff -Nru /tmp/SDL-1.2.6/src/video/windib/SDL_dibevents.c SDL-1.2.6/src/video/windib/SDL_dibevents.c
--- /tmp/SDL-1.2.6/src/video/windib/SDL_dibevents.c	2003-08-30 22:13:12.000000000 +0300
+++ SDL-1.2.6/src/video/windib/SDL_dibevents.c	2006-05-14 20:34:40.000000000 +0300
@@ -59,6 +59,29 @@
    and give him a chance to handle some messages. */
 static WNDPROC userWindowProc = NULL;
 
+#ifdef _WIN32_WCE
+
+WPARAM rotateKey(WPARAM key, SDL_RotateAttr direction) {
+	if (direction != SDL_ROTATE_LEFT)
+		return key;
+
+	switch (key) {
+		case 0x26: /* up */
+			return 0x27;
+		case 0x27: /* right */
+			return 0x28;
+		case 0x28: /* down */
+			return 0x25;
+		case 0x25: /* left */
+			return 0x26;
+	}
+
+	return key;
+}
+
+#endif
+
+
 /* The main Win32 event handler */
 LONG
  DIB_HandleMessage(_THIS, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
@@ -70,6 +93,16 @@
 		case WM_KEYDOWN: {
 			SDL_keysym keysym;
 
+#ifdef _WIN32_WCE
+			// Drop GAPI artefacts
+			if (wParam == 0x84 || wParam == 0x5B)
+				return 0;
+
+			// Rotate key if necessary
+			if (rotation != SDL_ROTATE_NONE)
+				wParam = rotateKey(wParam, rotation);	
+#endif
+
 			/* Ignore repeated keys */
 			if ( lParam&REPEATED_KEYMASK ) {
 				return(0);
@@ -100,6 +133,7 @@
 						wParam = VK_LMENU;
 					break;
 			}
+
 #ifdef NO_GETKEYBOARDSTATE
 			/* this is the workaround for the missing ToAscii() and ToUnicode() in CE (not necessary at KEYUP!) */
 			if ( SDL_TranslateUNICODE ) {
@@ -114,12 +148,13 @@
 					GetMessage(&m, hwnd, 0, WM_USER);
 			    		wParam = m.wParam;
 				} else {
-					wParam = 0;
+						//wParam = 0;  // I don't get it !
 				}
 			} else {
-				wParam = 0;
+				//wParam = 0;   // I don't get it !
 			}
 #endif /* NO_GETKEYBOARDSTATE */
+
 			posted = SDL_PrivateKeyboard(SDL_PRESSED,
 				TranslateKey(wParam,HIWORD(lParam),&keysym,1));
 		}
@@ -129,6 +164,16 @@
 		case WM_KEYUP: {
 			SDL_keysym keysym;
 
+#ifdef _WIN32_WCE
+			// Drop GAPI artefacts
+			if (wParam == 0x84 || wParam == 0x5B)
+				return 0;
+
+			// Rotate key if necessary
+			if (rotation != SDL_ROTATE_NONE)
+				wParam = rotateKey(wParam, rotation);
+#endif
+
 			switch (wParam) {
 				case VK_CONTROL:
 					if ( lParam&EXTENDED_KEYMASK )
@@ -155,6 +200,7 @@
 						wParam = VK_LMENU;
 					break;
 			}
+			
 			posted = SDL_PrivateKeyboard(SDL_RELEASED,
 				TranslateKey(wParam,HIWORD(lParam),&keysym,0));
 		}
@@ -325,6 +371,15 @@
 
 	prev_shiftstates[0] = FALSE;
 	prev_shiftstates[1] = FALSE;
+
+#ifdef _WIN32_WCE
+	/* Hardcode the 4 magic keys to F1 F2 F3 F4 - the actual location of the keys varies ... */
+	VK_keymap[0xC1] = SDLK_F1;
+	VK_keymap[0xC2] = SDLK_F2;
+	VK_keymap[0xC3] = SDLK_F3;
+	VK_keymap[0xC4] = SDLK_F4;
+#endif
+
 }
 
 static SDL_keysym *TranslateKey(UINT vkey, UINT scancode, SDL_keysym *keysym, int pressed)
@@ -356,8 +411,14 @@
 #ifndef CS_BYTEALIGNCLIENT
 #define CS_BYTEALIGNCLIENT	0
 #endif
+#ifndef _WIN32_WCE
 	SDL_RegisterApp("SDL_app", CS_BYTEALIGNCLIENT, 0);
+#else
+	SDL_RegisterApp("SDL_app", CS_BYTEALIGNCLIENT | CS_HREDRAW | CS_VREDRAW, 0);
+#endif
 	if ( SDL_windowid ) {
+// FIXME 
+#ifndef _WIN32_WCE
 		SDL_Window = (HWND)strtol(SDL_windowid, NULL, 0);
 
       /* DJM: we want all event's for the user specified
@@ -367,16 +428,28 @@
          userWindowProc = (WNDPROC)GetWindowLong(SDL_Window, GWL_WNDPROC);
          SetWindowLong(SDL_Window, GWL_WNDPROC, (LONG)WinMessage);
       }
+#endif
 	} else {
+				
+#ifndef _WIN32_WCE
 		SDL_Window = CreateWindow(SDL_Appname, SDL_Appname,
                         (WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX),
                                  0, 0, 0, 0, NULL, NULL, SDL_Instance, NULL);
+#else		
+
+		SDL_Window = CreateWindow(SDL_Appname, SDL_Appname, (WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX),
+						0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), 
+						NULL, NULL, SDL_Instance, NULL);
+
+#endif	
 		if ( SDL_Window == NULL ) {
 			SDL_SetError("Couldn't create window");
 			return(-1);
 		}
-		ShowWindow(SDL_Window, SW_HIDE);
+
+		ShowWindow(SDL_Window, SW_HIDE);		
 	}
+
 	return(0);
 }
 
diff -Nru /tmp/SDL-1.2.6/src/video/windib/SDL_dibvideo.c SDL-1.2.6/src/video/windib/SDL_dibvideo.c
--- /tmp/SDL-1.2.6/src/video/windib/SDL_dibvideo.c	2003-08-30 22:13:12.000000000 +0300
+++ SDL-1.2.6/src/video/windib/SDL_dibvideo.c	2006-07-10 22:02:26.000000000 +0300
@@ -29,9 +29,14 @@
 #include <stdlib.h>
 #include <malloc.h>
 #include <windows.h>
-#if defined(WIN32_PLATFORM_PSPC)
-#include <aygshell.h>                      // Add Pocket PC includes
+#if defined(UNDER_CE) && (_WIN32_WCE >= 300)
+/*#include <aygshell.h>                      // Add Pocket PC includes
 #pragma comment( lib, "aygshell" )         // Link Pocket PC library
+*/
+#include <windows.h>
+#endif
+#ifdef _MSC_VER
+#define inline __inline
 #endif
 
 /* Not yet in the mingw32 cross-compile headers */
@@ -39,6 +44,10 @@
 #define CDS_FULLSCREEN	4
 #endif
 
+#ifndef WS_THICKFRAME
+#define WS_THICKFRAME 0
+#endif
+
 #include "SDL.h"
 #include "SDL_mutex.h"
 #include "SDL_syswm.h"
@@ -56,6 +65,17 @@
 #define NO_GETDIBITS
 #define NO_CHANGEDISPLAYSETTINGS
 #define NO_GAMMA_SUPPORT
+
+/* uncomment this line if you target WinCE 3.x platform: */
+//#define NO_SETDIBCOLORTABLE
+
+/* these 2 variables are used to suport paletted DIBs on WinCE 3.x that 
+   does not implement SetDIBColorTable, and when SetDIBColorTable is not working.
+   Slow. DIB is recreated every time.
+*/
+static BITMAPINFO *last_bitmapinfo;
+static void** last_bits;
+
 #endif
 #ifndef WS_MAXIMIZE
 #define WS_MAXIMIZE		0
@@ -94,6 +114,13 @@
 /* helper fn */
 static int DIB_SussScreenDepth();
 
+#ifdef _WIN32_WCE
+void DIB_ShowTaskBar(BOOL taskBarShown);
+#ifdef ENABLE_WINGAPI
+extern void GAPI_GrabHardwareKeys(BOOL grab);
+#endif
+#endif
+
 /* DIB driver bootstrap functions */
 
 static int DIB_Available(void)
@@ -350,6 +377,9 @@
 	/* Fill in some window manager capabilities */
 	this->info.wm_available = 1;
 
+	/* Rotation information */
+	rotation = SDL_ROTATE_NONE;
+
 	/* We're done! */
 	return(0);
 }
@@ -368,6 +398,42 @@
 #endif
 }
 
+#ifdef _WIN32_WCE
+
+void DIB_ShowTaskBar(BOOL taskBarShown) {
+#if !defined(WIN32_PLATFORM_PSPC) || (_WIN32_WCE < 300)
+	// Hide taskbar, WinCE 2.x style - from EasyCE
+	HKEY hKey=0;
+	DWORD dwValue = 0;
+	unsigned long lSize = sizeof( DWORD );
+	DWORD dwType = REG_DWORD;
+	HWND hWnd;
+
+	RegOpenKeyEx( HKEY_LOCAL_MACHINE, TEXT("\\software\\microsoft\\shell"), 0, KEY_ALL_ACCESS, &hKey );
+	RegQueryValueEx( hKey, TEXT("TBOpt"), 0, &dwType, (BYTE*)&dwValue, &lSize );
+	if (taskBarShown)
+		dwValue &= 0xFFFFFFFF - 8;	// reset bit to show taskbar
+    else 
+		dwValue |= 8;	// set bit to hide taskbar
+	RegSetValueEx( hKey, TEXT("TBOpt"), 0, REG_DWORD, (BYTE*)&dwValue, lSize );
+	hWnd = FindWindow( TEXT("HHTaskBar"), NULL );
+	SendMessage(hWnd, WM_COMMAND, 0x03EA, 0 );
+	SetForegroundWindow(SDL_Window);
+#else
+	if (taskBarShown) 
+		SHFullScreen(SDL_Window, SHFS_SHOWTASKBAR | SHFS_SHOWSIPBUTTON | SHFS_SHOWSTARTICON);
+	else 
+		SHFullScreen(SDL_Window, SHFS_HIDETASKBAR | SHFS_HIDESIPBUTTON | SHFS_HIDESTARTICON);
+#endif
+	if (FindWindow(TEXT("HHTaskBar"), NULL)) { // is it valid for HPC ?
+		if (taskBarShown) 
+			ShowWindow(FindWindow(TEXT("HHTaskBar"),NULL),SW_SHOWNORMAL);
+		else 
+			ShowWindow(FindWindow(TEXT("HHTaskBar"),NULL),SW_HIDE);
+	}
+}
+
+#endif
 
 /*
   Helper fn to work out which screen depth windows is currently using.
@@ -442,6 +508,7 @@
 
 /* Various screen update functions available */
 static void DIB_NormalUpdate(_THIS, int numrects, SDL_Rect *rects);
+static void DIB_RotatedUpdate(_THIS, int numrects, SDL_Rect *rects);
 
 SDL_Surface *DIB_SetVideoMode(_THIS, SDL_Surface *current,
 				int width, int height, int bpp, Uint32 flags)
@@ -462,14 +529,17 @@
 	int x, y;
 	BOOL was_visible;
 	Uint32 Rmask, Gmask, Bmask;
+	int screenWidth, screenHeight, i;
 
 	/* See whether or not we should center the window */
 	was_visible = IsWindowVisible(SDL_Window);
 
+#ifdef HAVE_OPENGL
 	/* Clean up any GL context that may be hanging around */
 	if ( current->flags & SDL_OPENGL ) {
 		WIN_GL_ShutDown(this);
 	}
+#endif
 
 	/* Recalculate the bitmasks if necessary */
 	if ( bpp == current->format->BitsPerPixel ) {
@@ -518,23 +588,30 @@
 	video->h = height;
 	video->pitch = SDL_CalculatePitch(video);
 
-#ifdef WIN32_PLATFORM_PSPC
+//#ifdef WIN32_PLATFORM_PSPC
 	 /* Stuff to hide that $#!^%#$ WinCE taskbar in fullscreen... */
 	if ( flags & SDL_FULLSCREEN ) {
 		if ( !(prev_flags & SDL_FULLSCREEN) ) {
-			SHFullScreen(SDL_Window, SHFS_HIDETASKBAR);
-			SHFullScreen(SDL_Window, SHFS_HIDESIPBUTTON);
-			ShowWindow(FindWindow(TEXT("HHTaskBar"),NULL),SW_HIDE);
+
+			//ShowWindow(SDL_Window, SW_SHOW);
+			//SetWindowPos(SDL_Window, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
+			//SetForegroundWindow(SDL_Window);
+
+			//SHFullScreen(SDL_Window, SHFS_HIDETASKBAR | SHFS_HIDESIPBUTTON | SHFS_HIDESTARTICON);
+			//ShowWindow(FindWindow(TEXT("HHTaskBar"),NULL),SW_HIDE);
+
+			DIB_ShowTaskBar(FALSE);
+
 		}
 		video->flags |= SDL_FULLSCREEN;
 	} else {
 		if ( prev_flags & SDL_FULLSCREEN ) {
-			SHFullScreen(SDL_Window, SHFS_SHOWTASKBAR);
-			SHFullScreen(SDL_Window, SHFS_SHOWSIPBUTTON);
-			ShowWindow(FindWindow(TEXT("HHTaskBar"),NULL),SW_SHOWNORMAL);
+			//SHFullScreen(SDL_Window, SHFS_SHOWTASKBAR | SHFS_SHOWSIPBUTTON | SHFS_SHOWSTARTICON);
+			//ShowWindow(FindWindow(TEXT("HHTaskBar"),NULL),SW_SHOWNORMAL);
+			DIB_ShowTaskBar(TRUE);
 		}
 	}
-#endif
+//#endif
 #ifndef NO_CHANGEDISPLAYSETTINGS
 	/* Set fullscreen mode if appropriate */
 	if ( (flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
@@ -560,6 +637,7 @@
 		DeleteObject(screen_pal);
 		screen_pal = NULL;
 	}
+
 	if ( bpp <= 8 )
 	{
 	/*	RJR: March 28, 2000
@@ -591,7 +669,7 @@
 			}
 		}
 #if WS_MAXIMIZE
-		if (IsZoomed(SDL_Window)) style |= WS_MAXIMIZE;
+//		if (IsZoomed(SDL_Window)) style |= WS_MAXIMIZE;
 #endif
 	}
 
@@ -615,6 +693,7 @@
 			binfo_size += video->format->palette->ncolors *
 							sizeof(RGBQUAD);
 		}
+
 		binfo = (BITMAPINFO *)malloc(binfo_size);
 		if ( ! binfo ) {
 			if ( video != current ) {
@@ -642,19 +721,65 @@
 			((Uint32*)binfo->bmiColors)[1] = video->format->Gmask;
 			((Uint32*)binfo->bmiColors)[2] = video->format->Bmask;
 		} else {
+#ifdef UNDER_CE
+			binfo->bmiHeader.biCompression = BI_RGB;	/* 332 */
+			if ( video->format->palette ) {
+				binfo->bmiHeader.biClrUsed = video->format->palette->ncolors;
+				for(i=0; i<video->format->palette->ncolors; i++)
+				{
+					binfo->bmiColors[i].rgbRed=i&(7<<5);
+					binfo->bmiColors[i].rgbGreen=(i&(7<<2))<<3;
+					binfo->bmiColors[i].rgbBlue=(i&3)<<5;
+					binfo->bmiColors[i].rgbReserved=0;
+			   }
+			}
+#else
 			binfo->bmiHeader.biCompression = BI_RGB;	/* BI_BITFIELDS for 565 vs 555 */
 			if ( video->format->palette ) {
 				memset(binfo->bmiColors, 0,
 					video->format->palette->ncolors*sizeof(RGBQUAD));
 			}
+#endif
 		}
 
 		/* Create the offscreen bitmap buffer */
 		hdc = GetDC(SDL_Window);
+		/* See if we need to rotate the buffer (WinCE specific) */
+		screenWidth = GetDeviceCaps(hdc, HORZRES);
+		screenHeight = GetDeviceCaps(hdc, VERTRES);
+		rotation = SDL_ROTATE_NONE;
+		work_pixels = NULL;
+		if (rotation_pixels) {
+			free(rotation_pixels);
+			rotation_pixels = NULL;
+		}
+
+		if ((flags & SDL_FULLSCREEN) && (width>height) && (width > screenWidth) ) {
+			/* OK, we rotate the screen */
+			video->pixels = malloc(video->h * video->pitch);
+			rotation_pixels = video->pixels;
+			if (video->pixels)
+				rotation = SDL_ROTATE_LEFT;
+			OutputDebugString(TEXT("will rotate\r\n"));
+		}
+
 		screen_bmp = CreateDIBSection(hdc, binfo, DIB_RGB_COLORS,
-					(void **)(&video->pixels), NULL, 0);
+			(rotation == SDL_ROTATE_NONE ? (void **)(&video->pixels) : (void**)&work_pixels), NULL, 0);
 		ReleaseDC(SDL_Window, hdc);
+#if defined(UNDER_CE) 
+/* keep bitmapinfo for palette in 8-bit modes for devices that don't have SetDIBColorTable */
+		last_bits = (rotation == SDL_ROTATE_NONE ? (void **)(&video->pixels) : (void**)&work_pixels);
+		if(last_bitmapinfo)
+			free(last_bitmapinfo);
+		if(is16bitmode)
+		{
+			last_bitmapinfo = 0;
+			free(binfo);
+		} else
+			last_bitmapinfo = binfo;
+#else
 		free(binfo);
+#endif
 		if ( screen_bmp == NULL ) {
 			if ( video != current ) {
 				SDL_FreeSurface(video);
@@ -662,7 +787,7 @@
 			SDL_SetError("Couldn't create DIB section");
 			return(NULL);
 		}
-		this->UpdateRects = DIB_NormalUpdate;
+		this->UpdateRects = (work_pixels ? DIB_RotatedUpdate : DIB_NormalUpdate);
 
 		/* Set video surface flags */
 		if ( bpp <= 8 ) {
@@ -681,6 +806,14 @@
 		bounds.top = 0;
 		bounds.right = video->w;
 		bounds.bottom = video->h;
+#ifdef UNDER_CE
+		if(rotation != SDL_ROTATE_NONE)
+		{   
+			int t=bounds.right;
+			bounds.right = bounds.bottom;
+			bounds.bottom=t;
+		}
+#endif
 		AdjustWindowRectEx(&bounds, GetWindowLong(SDL_Window, GWL_STYLE), FALSE, 0);
 		width = bounds.right-bounds.left;
 		height = bounds.bottom-bounds.top;
@@ -690,27 +823,56 @@
 			y -= GetSystemMetrics(SM_CYCAPTION)/2;
 		}
 		swp_flags = (SWP_NOCOPYBITS | SWP_FRAMECHANGED | SWP_SHOWWINDOW);
-		if ( was_visible && !(flags & SDL_FULLSCREEN) ) {
+#ifndef UNDER_CE
+		if ( was_visible && !(flags & SDL_FULLSCREEN)) {
 			swp_flags |= SWP_NOMOVE;
 		}
+#endif
 		if ( flags & SDL_FULLSCREEN ) {
 			top = HWND_TOPMOST;
 		} else {
 			top = HWND_NOTOPMOST;
 		}
+#ifndef _WIN32_WCE
 		SetWindowPos(SDL_Window, top, x, y, width, height, swp_flags);
+#else
+		if (flags & SDL_FULLSCREEN) {
+/* When WinCE program switches resolution from larger to smaller we should move its window so it would be visible in fullscreen */
+//			SetWindowPos(SDL_Window, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
+			DIB_ShowTaskBar(FALSE);
+			if(x>0) x=0;	// remove space from the left side of a screen in 320x200 mode
+			if(y>0) y=0;
+			SetWindowPos(SDL_Window, HWND_TOPMOST, x, y, width, height, SWP_NOCOPYBITS);
+			ShowWindow(SDL_Window, SW_SHOW);
+		}
+		else
+			SetWindowPos(SDL_Window, top, x, y, width, height, swp_flags);
+#endif
+		
 		SDL_resizing = 0;
 		SetForegroundWindow(SDL_Window);
 	}
 
 	/* Set up for OpenGL */
 	if ( flags & SDL_OPENGL ) {
+#ifdef HAVE_OPENGL
 		if ( WIN_GL_SetupWindow(this) < 0 ) {
 			return(NULL);
 		}
 		video->flags |= SDL_OPENGL;
+#else
+		return (NULL);
+#endif
+
 	}
 
+#ifdef ENABLE_WINGAPI
+	/* Grab hardware keys if necessary */
+	if ( flags & SDL_FULLSCREEN ) {
+		GAPI_GrabHardwareKeys(TRUE);
+	}
+#endif
+
 	/* We're live! */
 	return(video);
 }
@@ -726,28 +888,163 @@
 }
 static int DIB_LockHWSurface(_THIS, SDL_Surface *surface)
 {
-	return(0);
+	return(0); 
 }
 static void DIB_UnlockHWSurface(_THIS, SDL_Surface *surface)
 {
 	return;
 }
 
+static inline void rotateBlit(unsigned short *src, unsigned short *dest, SDL_Rect *rect, int pitch) {
+	int i=rect->w, j=rect->h;
+	src+=i;
+
+	for (;i--;) {
+		register unsigned short *S=src--;
+// I use loop unrolling to spedup things a little
+		int cnt = j;
+		if(cnt&1)
+		{
+			*(dest++) = *S;
+			S+=pitch;
+		}
+		cnt>>=1;
+		if(cnt&1)
+		{
+			*(dest++) = *S;
+			S+=pitch;
+			*(dest++) = *S;
+			S+=pitch;
+		}
+		cnt>>=1;
+		for (; cnt--; ) {
+			*(dest++) = *S;
+			S+=pitch;
+			*(dest++) = *S;
+			S+=pitch;
+			*(dest++) = *S;
+			S+=pitch;
+			*(dest++) = *S;
+			S+=pitch;
+		}
+	}
+/* tiny optimization
+	int i, j;
+	src+=rect->w;
+
+	for (i=0; i<rect->w; i++) {
+		register unsigned short *S=src--;
+		for (j=0; j<rect->h; j++) {
+			*(dest++) = *S;
+			S+=pitch;
+		}
+	}
+*/
+/* original unoptimized version
+	int i, j;
+
+	for (i=0; i<rect->w; i++) {
+		for (j=0; j<rect->h; j++) {
+			dest[i * rect->h + j] = src[pitch * j + (rect->w - i)];
+		}
+	}
+*/
+}
+
+static inline void rotateBlit8(unsigned char *src, unsigned char *dest, SDL_Rect *rect, int pitch) {
+	int i=rect->w, j=rect->h;
+	src+=i;
+
+	for (;i--;) {
+		register unsigned char *S=src--;
+// I use loop unrolling to spedup things a little
+		int cnt = j;
+		if(cnt&1)
+		{
+			*(dest++) = *S;
+			S+=pitch;
+		}
+		cnt>>=1;
+		if(cnt&1)
+		{
+			*(dest++) = *S;
+			S+=pitch;
+			*(dest++) = *S;
+			S+=pitch;
+		}
+		cnt>>=1;
+		for (; cnt--; ) {
+			*(dest++) = *S;
+			S+=pitch;
+			*(dest++) = *S;
+			S+=pitch;
+			*(dest++) = *S;
+			S+=pitch;
+			*(dest++) = *S;
+			S+=pitch;
+		}
+	}
+}
+
+static void DIB_RotatedUpdate(_THIS, int numrects, SDL_Rect *rects) 
+{
+	HDC hdc, mdc;
+	HBITMAP hb, old;
+	int i;
+
+	hdc = GetDC(SDL_Window);
+	if ( screen_pal ) {
+		SelectPalette(hdc, screen_pal, FALSE);
+	}
+	mdc = CreateCompatibleDC(hdc);
+	/*SelectObject(mdc, screen_bmp);*/
+	if(this->screen->format->BytesPerPixel == 2) {
+		for ( i=0; i<numrects; ++i ) {	
+			unsigned short *src = (unsigned short*)this->screen->pixels;
+			rotateBlit(src + (this->screen->w * rects[i].y) + rects[i].x, work_pixels, &rects[i], this->screen->w);		
+			hb = CreateBitmap(rects[i].h, rects[i].w, 1, 16, work_pixels);
+			old = (HBITMAP)SelectObject(mdc, hb);
+			BitBlt(hdc, rects[i].y, this->screen->w - (rects[i].x + rects[i].w), rects[i].h, rects[i].w,
+					mdc, 0, 0, SRCCOPY);
+			SelectObject(mdc, old);
+			DeleteObject(hb);
+		}
+	} else {
+		if ( screen_pal ) {
+			SelectPalette(mdc, screen_pal, FALSE);
+		}
+		for ( i=0; i<numrects; ++i ) {	
+			unsigned char *src = (unsigned char*)this->screen->pixels;
+			rotateBlit8(src + (this->screen->w * rects[i].y) + rects[i].x, work_pixels, &rects[i], this->screen->w);
+			hb = CreateBitmap(rects[i].h, rects[i].w, 1, 8, work_pixels);
+			old = (HBITMAP)SelectObject(mdc, hb);
+			BitBlt(hdc, rects[i].y, this->screen->w - (rects[i].x + rects[i].w), rects[i].h, rects[i].w,
+					mdc, 0, 0, SRCCOPY);
+			SelectObject(mdc, old);
+			DeleteObject(hb); 
+		}
+	}
+	DeleteDC(mdc);
+	ReleaseDC(SDL_Window, hdc);
+}
+
 static void DIB_NormalUpdate(_THIS, int numrects, SDL_Rect *rects)
 {
 	HDC hdc, mdc;
 	int i;
+	HBITMAP old;
 
 	hdc = GetDC(SDL_Window);
 	if ( screen_pal ) {
 		SelectPalette(hdc, screen_pal, FALSE);
 	}
 	mdc = CreateCompatibleDC(hdc);
-	SelectObject(mdc, screen_bmp);
+	old = (HBITMAP)SelectObject(mdc, screen_bmp);
 	for ( i=0; i<numrects; ++i ) {
 		BitBlt(hdc, rects[i].x, rects[i].y, rects[i].w, rects[i].h,
 					mdc, rects[i].x, rects[i].y, SRCCOPY);
 	}
+	SelectObject(mdc, old);
 	DeleteDC(mdc);
 	ReleaseDC(SDL_Window, hdc);
 }
@@ -756,10 +1053,11 @@
 {
 	RGBQUAD *pal;
 	int i;
-#ifndef _WIN32_WCE
 	HDC hdc, mdc;
-#else
-	HDC hdc;
+
+#if defined(UNDER_CE) && defined(NO_SETDIBCOLORTABLE)
+	if(last_bitmapinfo==0)
+		return 0;
 #endif
 
 	/* Update the display palette */
@@ -789,14 +1087,39 @@
 	}
 
 	/* Set the DIB palette and update the display */
-#ifndef _WIN32_WCE
 	mdc = CreateCompatibleDC(hdc);
+
+#if defined(UNDER_CE) 
+#if !defined(NO_SETDIBCOLORTABLE)
+/* BUG: For some reason SetDIBColorTable is not working when screen is not rotated */
+	if(rotation == SDL_ROTATE_NONE && last_bitmapinfo)
+#else
+	if(1)
+#endif
+	{
+		DeleteObject(screen_bmp);
+		last_bitmapinfo->bmiHeader.biClrUsed=256;
+		for ( i=firstcolor; i<firstcolor+ncolors; ++i )
+			last_bitmapinfo->bmiColors[i]=pal[i];
+		screen_bmp = CreateDIBSection(hdc, last_bitmapinfo, DIB_RGB_COLORS,
+			last_bits, NULL, 0);
+    }
+#else
 	SelectObject(mdc, screen_bmp);
 	SetDIBColorTable(mdc, firstcolor, ncolors, pal);
+#endif
+#ifndef UNDER_CE
 	BitBlt(hdc, 0, 0, this->screen->w, this->screen->h,
 	       mdc, 0, 0, SRCCOPY);
-	DeleteDC(mdc);
+#else
+	{
+		SDL_Rect rect;
+		rect.x=0; rect.y=0;
+		rect.w=this->screen->w; rect.h=this->screen->h;
+// Fixme: screen flickers:		(this->UpdateRects)(this, 1, &rect) ;
+	}
 #endif
+	DeleteDC(mdc);
 	ReleaseDC(SDL_Window, hdc);
 	return(1);
 }
@@ -916,26 +1239,34 @@
 void DIB_VideoQuit(_THIS)
 {
 	/* Destroy the window and everything associated with it */
+	DIB_ShowTaskBar(TRUE);
+#ifdef ENABLE_WINGAPI
+	GAPI_GrabHardwareKeys(FALSE);
+#endif
+
 	if ( SDL_Window ) {
 		/* Delete the screen bitmap (also frees screen->pixels) */
 		if ( this->screen ) {
-#ifdef WIN32_PLATFORM_PSPC
+//#ifdef WIN32_PLATFORM_PSPC
 			if ( this->screen->flags & SDL_FULLSCREEN ) {
 				/* Unhide taskbar, etc. */
-				SHFullScreen(SDL_Window, SHFS_SHOWTASKBAR);
-				SHFullScreen(SDL_Window, SHFS_SHOWSIPBUTTON);
-				ShowWindow(FindWindow(TEXT("HHTaskBar"),NULL),SW_SHOWNORMAL);
+				//SHFullScreen(SDL_Window, SHFS_SHOWTASKBAR | SHFS_SHOWSIPBUTTON | SHFS_SHOWSTARTICON);
+				//ShowWindow(FindWindow(TEXT("HHTaskBar"),NULL),SW_SHOWNORMAL);
 			}
-#endif
+//#endif
 #ifndef NO_CHANGEDISPLAYSETTINGS
 			if ( this->screen->flags & SDL_FULLSCREEN ) {
 				ChangeDisplaySettings(NULL, 0);
 				ShowWindow(SDL_Window, SW_HIDE);
 			}
 #endif
+
+#ifdef HAVE_OPENGL
 			if ( this->screen->flags & SDL_OPENGL ) {
 				WIN_GL_ShutDown(this);
 			}
+#endif
+
 			this->screen->pixels = NULL;
 		}
 		if ( screen_bmp ) {
diff -Nru /tmp/SDL-1.2.6/src/video/windib/SDL_dibvideo.h SDL-1.2.6/src/video/windib/SDL_dibvideo.h
--- /tmp/SDL-1.2.6/src/video/windib/SDL_dibvideo.h	2002-04-11 18:23:07.000000000 +0300
+++ SDL-1.2.6/src/video/windib/SDL_dibvideo.h	2006-05-14 20:34:40.000000000 +0300
@@ -30,19 +30,34 @@
 
 #include <windows.h>
 
+/* Rotation direction */
+typedef enum {
+	SDL_ROTATE_NONE,
+	SDL_ROTATE_LEFT,
+	SDL_ROTATE_RIGHT
+} SDL_RotateAttr;
+
 /* Private display data */
 struct SDL_PrivateVideoData {
     HBITMAP screen_bmp;
     HPALETTE screen_pal;
+	void *work_pixels; /* if the display needs to be rotated, memory allocated by the API */
+	void *rotation_pixels; /* if the display needs to be rotated, memory allocated by the code */
+	SDL_RotateAttr rotation;
+	char ozoneHack; /* force stylus translation if running without Hi Res flag */
 
 #define NUM_MODELISTS	4		/* 8, 16, 24, and 32 bits-per-pixel */
     int SDL_nummodes[NUM_MODELISTS];
     SDL_Rect **SDL_modelist[NUM_MODELISTS];
 };
 /* Old variable names */
-#define screen_bmp		(this->hidden->screen_bmp)
-#define screen_pal		(this->hidden->screen_pal)
+#define screen_bmp			(this->hidden->screen_bmp)
+#define screen_pal			(this->hidden->screen_pal)
 #define SDL_nummodes		(this->hidden->SDL_nummodes)
 #define SDL_modelist		(this->hidden->SDL_modelist)
+#define work_pixels			(this->hidden->work_pixels)
+#define rotation			(this->hidden->rotation)
+#define rotation_pixels		(this->hidden->rotation_pixels)
+#define ozoneHack			(this->hidden->ozoneHack)
 
 #endif /* _SDL_dibvideo_h */
diff -Nru /tmp/SDL-1.2.6/src/video/wingapi/SDL_gapivideo_1_2_6.c SDL-1.2.6/src/video/wingapi/SDL_gapivideo_1_2_6.c
--- /tmp/SDL-1.2.6/src/video/wingapi/SDL_gapivideo_1_2_6.c	1970-01-01 02:00:00.000000000 +0200
+++ SDL-1.2.6/src/video/wingapi/SDL_gapivideo_1_2_6.c	2004-05-30 15:57:48.000000000 +0300
@@ -0,0 +1,956 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  Sam Lantinga
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public
+    License along with this library; if not, write to the Free
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+    Sam Lantinga
+    slouken@libsdl.org
+*/
+
+#ifdef SAVE_RCSID
+static char rcsid =
+ "@(#) $Id: SDL_gapivideo.c,v 1.5 2004/02/29 21:54:11 lemure Exp $";
+#endif
+
+/* Dummy SDL video driver implementation; this is just enough to make an
+ *  SDL-based application THINK it's got a working video driver, for
+ *  applications that call SDL_Init(SDL_INIT_VIDEO) when they don't need it,
+ *  and also for use as a collection of stubs when porting SDL to a new
+ *  platform for which you haven't yet written a valid video driver.
+ *
+ * This is also a great way to determine bottlenecks: if you think that SDL
+ *  is a performance problem for a given platform, enable this driver, and
+ *  then see if your application runs faster without video overhead.
+ *
+ * Initial work by Ryan C. Gordon (icculus@linuxgames.com). A good portion
+ *  of this was cut-and-pasted from Stephane Peter's work in the AAlib
+ *  SDL video driver.  Renamed to "DUMMY" by Sam Lantinga.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <malloc.h>
+#include <windows.h>
+
+/* Not yet in the mingw32 cross-compile headers */
+#ifndef CDS_FULLSCREEN
+#define CDS_FULLSCREEN	4
+#endif
+
+#ifndef WS_THICKFRAME
+#define WS_THICKFRAME 0
+#endif
+
+#include "SDL.h"
+#include "SDL_mutex.h"
+#include "SDL_syswm.h"
+#include "SDL_sysvideo.h"
+#include "SDL_sysevents.h"
+#include "SDL_events_c.h"
+#include "SDL_pixels_c.h"
+#include "SDL_syswm_c.h"
+#include "SDL_sysmouse_c.h"
+#include "SDL_dibevents_c.h"
+#include "SDL_gapivideo.h"
+
+#if defined(WIN32_PLATFORM_PSPC)
+#include <aygshell.h>                      // Add Pocket PC includes
+#pragma comment( lib, "aygshell" )         // Link Pocket PC library
+#endif
+
+#ifdef _WIN32_WCE
+extern void DIB_ShowTaskBar(BOOL taskBarShown);
+#endif
+
+
+/* Initialization/Query functions */
+static int GAPI_VideoInit(_THIS, SDL_PixelFormat *vformat);
+static SDL_Rect **GAPI_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
+static SDL_Surface *GAPI_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
+static int GAPI_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
+static void GAPI_VideoQuit(_THIS);
+
+
+/* Hardware surface functions */
+static int GAPI_AllocHWSurface(_THIS, SDL_Surface *surface);
+static int GAPI_LockHWSurface(_THIS, SDL_Surface *surface);
+static void GAPI_UnlockHWSurface(_THIS, SDL_Surface *surface);
+static void GAPI_FreeHWSurface(_THIS, SDL_Surface *surface);
+
+/* Windows message handling functions, will not be processed */
+static void GAPI_RealizePalette(_THIS);
+static void GAPI_PaletteChanged(_THIS, HWND window);
+static void GAPI_WinPAINT(_THIS, HDC hdc);
+
+static void GAPI_UpdateRects(_THIS, int numrects, SDL_Rect *rects); 
+/*static void GAPI_UpdateRectsMono(_THIS, int numrects, SDL_Rect *rects);*/
+
+static int GAPI_Available(void);
+static SDL_VideoDevice *GAPI_CreateDevice(int devindex);
+
+void GAPI_GrabHardwareKeys(BOOL grab);
+
+VideoBootStrap WINGAPI_bootstrap = {
+	"wingapi", "WinCE GAPI",
+	GAPI_Available, GAPI_CreateDevice
+};
+
+/* 2003 SE GAPI emulation */
+
+#define GETRAWFRAMEBUFFER   0x00020001
+
+#define FORMAT_565 1
+#define FORMAT_555 2
+#define FORMAT_OTHER 3
+
+static void* _OzoneFrameBuffer = NULL;
+static struct GXDisplayProperties _OzoneDisplayProperties;
+static char _OzoneAvailable = 0;
+
+typedef struct _RawFrameBufferInfo
+{
+   WORD wFormat;
+   WORD wBPP;
+   VOID *pFramePointer;
+   int  cxStride;
+   int  cyStride;
+   int  cxPixels;
+   int  cyPixels;
+} RawFrameBufferInfo;
+
+
+struct GXDisplayProperties Ozone_GetDisplayProperties(void) {
+	return _OzoneDisplayProperties;
+}
+
+int Ozone_OpenDisplay(HWND window, unsigned long flag) {
+	return 1;
+}
+
+int Ozone_CloseDisplay(void) {
+	return 1;
+}
+
+void* Ozone_BeginDraw(void) {
+	return _OzoneFrameBuffer;
+}
+
+int Ozone_EndDraw(void) {
+	return 1;
+}
+
+int Ozone_Suspend(void) {
+	return 1;
+}
+
+int Ozone_Resume(void) {
+	return 1;
+}
+
+static HINSTANCE checkOzone(tGXDisplayProperties *gxGetDisplayProperties, tGXOpenDisplay *gxOpenDisplay,
+					  tGXVoidFunction *gxCloseDisplay, tGXBeginDraw *gxBeginDraw, 
+					  tGXVoidFunction *gxEndDraw, tGXVoidFunction *gxSuspend, tGXVoidFunction *gxResume) {
+#ifdef ARM
+
+	int result;
+	RawFrameBufferInfo frameBufferInfo;
+	HDC hdc = GetDC(NULL);
+	result = ExtEscape(hdc, GETRAWFRAMEBUFFER, 0, NULL, sizeof(RawFrameBufferInfo), (char *)&frameBufferInfo);
+	ReleaseDC(NULL, hdc);
+	if (result < 0)
+		return NULL;
+	OutputDebugString(TEXT("Running on Ozone\r\n"));
+	_OzoneAvailable = 1;
+
+	// Initializing global parameters
+	_OzoneFrameBuffer = frameBufferInfo.pFramePointer;
+	_OzoneDisplayProperties.cBPP = frameBufferInfo.wBPP;
+	_OzoneDisplayProperties.cbxPitch = frameBufferInfo.cxStride;
+	_OzoneDisplayProperties.cbyPitch = frameBufferInfo.cyStride;
+	_OzoneDisplayProperties.cxWidth = frameBufferInfo.cxPixels;
+	_OzoneDisplayProperties.cyHeight = frameBufferInfo.cyPixels;
+	if (frameBufferInfo.wFormat == FORMAT_565)
+		_OzoneDisplayProperties.ffFormat = kfDirect565;
+	else
+	if (frameBufferInfo.wFormat == FORMAT_555)
+		_OzoneDisplayProperties.ffFormat = kfDirect555;
+	else {
+		OutputDebugString(TEXT("Ozone unknown screen format"));
+		return NULL;
+	}
+
+	if (gxGetDisplayProperties)
+		*gxGetDisplayProperties = Ozone_GetDisplayProperties;
+	if (gxOpenDisplay)
+		*gxOpenDisplay = Ozone_OpenDisplay;
+	if (gxCloseDisplay)
+		*gxCloseDisplay = Ozone_CloseDisplay;
+	if (gxBeginDraw)
+		*gxBeginDraw = Ozone_BeginDraw;
+	if (gxEndDraw)
+		*gxEndDraw = Ozone_EndDraw;
+	if (gxSuspend)
+		*gxSuspend = Ozone_Suspend;
+	if (gxResume)
+		*gxResume = Ozone_Resume;
+
+	return (HINSTANCE)1;
+
+#else
+
+	return NULL;
+
+#endif
+}
+
+int getScreenWidth() {
+	return (_OzoneFrameBuffer ? _OzoneDisplayProperties.cxWidth : GetSystemMetrics(SM_CXSCREEN));
+}
+
+int getScreenHeight() {
+	return (_OzoneFrameBuffer ? _OzoneDisplayProperties.cyHeight : GetSystemMetrics(SM_CYSCREEN));
+}
+
+
+/* Check GAPI library */
+
+#define IMPORT(Handle,Variable,Type,Function, Store) \
+        Variable = GetProcAddress(Handle, TEXT(Function)); \
+		if (!Variable) { \
+			FreeLibrary(Handle); \
+			return NULL; \
+		} \
+		if (Store) \
+			*Store = (Type)Variable;
+
+static HINSTANCE checkGAPI(tGXDisplayProperties *gxGetDisplayProperties, tGXOpenDisplay *gxOpenDisplay,
+					  tGXVoidFunction *gxCloseDisplay, tGXBeginDraw *gxBeginDraw, 
+					  tGXVoidFunction *gxEndDraw, tGXVoidFunction *gxSuspend, tGXVoidFunction *gxResume,
+					  BOOL bypassOzone) {
+	HMODULE gapiLibrary;
+	FARPROC proc;
+	HINSTANCE result;
+	// FIXME paletted !
+	tGXDisplayProperties temp_gxGetDisplayProperties;
+
+	// Workaround for Windows Mobile 2003 SE
+	_OzoneFrameBuffer = NULL;
+	if (!bypassOzone) {
+		result = checkOzone(gxGetDisplayProperties, gxOpenDisplay, gxCloseDisplay, gxBeginDraw, gxEndDraw, gxSuspend, gxResume);
+		if (result)
+			return result;
+	}
+
+	gapiLibrary = LoadLibrary(TEXT("gx.dll"));
+	if (!gapiLibrary)
+		return NULL;
+
+	IMPORT(gapiLibrary, proc, tGXDisplayProperties, "?GXGetDisplayProperties@@YA?AUGXDisplayProperties@@XZ", gxGetDisplayProperties)
+	IMPORT(gapiLibrary, proc, tGXOpenDisplay, "?GXOpenDisplay@@YAHPAUHWND__@@K@Z", gxOpenDisplay)
+	IMPORT(gapiLibrary, proc, tGXVoidFunction, "?GXCloseDisplay@@YAHXZ", gxCloseDisplay)
+	IMPORT(gapiLibrary, proc, tGXBeginDraw, "?GXBeginDraw@@YAPAXXZ", gxBeginDraw)
+	IMPORT(gapiLibrary, proc, tGXVoidFunction, "?GXEndDraw@@YAHXZ", gxEndDraw)
+	IMPORT(gapiLibrary, proc, tGXVoidFunction, "?GXSuspend@@YAHXZ", gxSuspend)
+	IMPORT(gapiLibrary, proc, tGXVoidFunction, "?GXResume@@YAHXZ", gxResume)
+	
+	// FIXME paletted ! for the moment we just bail out	
+	if (!gxGetDisplayProperties) {
+		IMPORT(gapiLibrary, proc, tGXDisplayProperties, "?GXGetDisplayProperties@@YA?AUGXDisplayProperties@@XZ", &temp_gxGetDisplayProperties)
+		if (temp_gxGetDisplayProperties().ffFormat & kfPalette) {
+			FreeLibrary(gapiLibrary);
+			return NULL;
+		}
+		FreeLibrary(gapiLibrary);		
+		gapiLibrary = (HINSTANCE)1;
+	}
+	
+	return gapiLibrary;
+}
+
+
+/* GAPI driver bootstrap functions */
+
+static int GAPI_Available(void)
+{
+	/* Check if the GAPI library is available */
+
+	if (!checkGAPI(NULL, NULL, NULL, NULL, NULL, NULL, NULL, FALSE)) {
+		OutputDebugString(TEXT("GAPI driver not available\r\n"));
+		return 0;
+	}
+	else {
+		OutputDebugString(TEXT("GAPI driver available\r\n"));
+		return 1;
+	}
+}
+
+static void GAPI_DeleteDevice(SDL_VideoDevice *device)
+{
+	if (device && device->hidden && device->hidden->gapiFuncs.dynamicGXCloseDisplay)
+		device->hidden->gapiFuncs.dynamicGXCloseDisplay();
+
+	if (device && device->hidden)	
+		free(device->hidden);
+	if (device)
+		free(device);
+
+}
+
+static SDL_VideoDevice *GAPI_CreateDevice(int devindex)
+{
+	SDL_VideoDevice *device;
+
+	/* Initialize all variables that we clean on shutdown */
+	device = (SDL_VideoDevice *)malloc(sizeof(SDL_VideoDevice));
+	if ( device ) {
+		memset(device, 0, (sizeof *device));
+		device->hidden = (struct SDL_PrivateVideoData *)
+				malloc((sizeof *device->hidden));
+	}
+	if ( (device == NULL) || (device->hidden == NULL) ) {
+		SDL_OutOfMemory();
+		if ( device ) {
+			free(device);
+		}
+		return(0);
+	}
+	memset(device->hidden, 0, (sizeof *device->hidden));
+
+	/* Set GAPI pointers */
+
+	checkGAPI(&device->hidden->gapiFuncs.dynamicGXGetDisplayProperties, 
+			  &device->hidden->gapiFuncs.dynamicGXOpenDisplay, 
+			  &device->hidden->gapiFuncs.dynamicGXCloseDisplay, 
+			  &device->hidden->gapiFuncs.dynamicGXBeginDraw, 
+			  &device->hidden->gapiFuncs.dynamicGXEndDraw, 
+			  &device->hidden->gapiFuncs.dynamicGXSuspend, 
+			  &device->hidden->gapiFuncs.dynamicGXResume, 
+			  FALSE);
+	device->hidden->displayProps = device->hidden->gapiFuncs.dynamicGXGetDisplayProperties();
+
+	/* Set the function pointers */
+
+	device->VideoInit = GAPI_VideoInit;
+	device->ListModes = GAPI_ListModes;
+	device->SetVideoMode = GAPI_SetVideoMode;
+	device->UpdateMouse = WIN_UpdateMouse;
+	device->SetColors = GAPI_SetColors;
+	device->UpdateRects = NULL;
+	device->VideoQuit = GAPI_VideoQuit;
+	device->AllocHWSurface = GAPI_AllocHWSurface;
+	device->CheckHWBlit = NULL;
+	device->FillHWRect = NULL;
+	device->SetHWColorKey = NULL;
+	device->SetHWAlpha = NULL;
+	device->LockHWSurface = GAPI_LockHWSurface;
+	device->UnlockHWSurface = GAPI_UnlockHWSurface;
+	device->FlipHWSurface = NULL;
+	device->FreeHWSurface = GAPI_FreeHWSurface;
+	device->SetCaption = WIN_SetWMCaption;
+	device->SetIcon = WIN_SetWMIcon;
+	device->IconifyWindow = WIN_IconifyWindow;
+	device->GrabInput = WIN_GrabInput;
+	device->GetWMInfo = WIN_GetWMInfo;
+	device->FreeWMCursor = WIN_FreeWMCursor;
+	device->CreateWMCursor = WIN_CreateWMCursor;
+	device->ShowWMCursor = WIN_ShowWMCursor;
+	device->WarpWMCursor = WIN_WarpWMCursor;
+	device->CheckMouseMode = WIN_CheckMouseMode;
+	device->InitOSKeymap = DIB_InitOSKeymap;
+	device->PumpEvents = DIB_PumpEvents;
+
+	device->SetColors = GAPI_SetColors;
+
+	/* Set up the windows message handling functions */
+	WIN_RealizePalette = GAPI_RealizePalette;
+	WIN_PaletteChanged = GAPI_PaletteChanged;
+	WIN_WinPAINT = GAPI_WinPAINT;
+	HandleMessage = DIB_HandleMessage;
+
+	device->free = GAPI_DeleteDevice;
+	
+	
+	/*
+	device->VideoInit = GAPI_VideoInit;
+	device->ListModes = GAPI_ListModes;
+	device->SetVideoMode = GAPI_SetVideoMode;
+	device->CreateYUVOverlay = NULL;
+	device->SetColors = DUMMY_SetColors;
+	device->UpdateRects = DUMMY_UpdateRects;
+	device->VideoQuit = DUMMY_VideoQuit;
+	device->AllocHWSurface = DUMMY_AllocHWSurface;
+	device->CheckHWBlit = NULL;
+	device->FillHWRect = NULL;
+	device->SetHWColorKey = NULL;
+	device->SetHWAlpha = NULL;
+	device->LockHWSurface = DUMMY_LockHWSurface;
+	device->UnlockHWSurface = DUMMY_UnlockHWSurface;
+	device->FlipHWSurface = NULL;
+	device->FreeHWSurface = DUMMY_FreeHWSurface;
+	device->SetCaption = NULL;
+	device->SetIcon = NULL;
+	device->IconifyWindow = NULL;
+	device->GrabInput = NULL;
+	device->GetWMInfo = NULL;
+	device->InitOSKeymap = DUMMY_InitOSKeymap;
+	device->PumpEvents = DUMMY_PumpEvents;
+
+	device->free = DUMMY_DeleteDevice;
+	*/
+
+	return device;
+}
+
+
+int GAPI_VideoInit(_THIS, SDL_PixelFormat *vformat)
+{
+
+	/* Create the window */
+	if ( DIB_CreateWindow(this) < 0 ) {
+		return(-1);
+	}
+
+	vformat->BitsPerPixel = (unsigned char)displayProperties.cBPP;	
+
+	// Get color mask
+	if (displayProperties.ffFormat & kfDirect565) {
+		vformat->BitsPerPixel = 16;
+		vformat->Rmask = 0x0000f800;
+		vformat->Gmask = 0x000007e0;
+		vformat->Bmask = 0x0000001f;
+		videoMode = GAPI_DIRECT_565;
+	}
+	else
+	if (displayProperties.ffFormat & kfDirect555) {
+		vformat->BitsPerPixel = 16;
+		vformat->Rmask = 0x00007c00;
+		vformat->Gmask = 0x000003e0;
+		vformat->Bmask = 0x0000001f;
+		videoMode = GAPI_DIRECT_555;
+	}
+	else
+	if ((displayProperties.ffFormat & kfDirect) && (displayProperties.cBPP <= 8)) {
+		// We'll perform the conversion
+		vformat->BitsPerPixel = 24;
+		vformat->Rmask = 0x00ff0000;
+		vformat->Gmask = 0x0000ff00;
+		vformat->Bmask = 0x000000ff;
+		if (displayProperties.ffFormat & kfDirectInverted)
+			invert = (1 << displayProperties.cBPP) - 1;
+		colorscale = displayProperties.cBPP < 8 ? 8 - displayProperties.cBPP : 0;
+		videoMode = GAPI_MONO;
+	}
+	else
+	if (displayProperties.ffFormat & kfPalette) {
+		videoMode = GAPI_PALETTE;
+	}
+
+	/* Set UpdateRect callback */
+	// FIXME
+	/*
+	if (videoMode != GAPI_MONO)
+		this->UpdateRects = GAPI_UpdateRects;
+	else
+		this->UpdateRects = GAPI_UpdateRectsMono;
+	*/
+
+	this->UpdateRects = GAPI_UpdateRects;
+	
+	/* We're done! */
+	return(0);
+}
+
+SDL_Rect **GAPI_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
+{
+   	 return (SDL_Rect **) -1;
+}
+
+SDL_Surface *GAPI_SetVideoMode(_THIS, SDL_Surface *current,
+				int width, int height, int bpp, Uint32 flags)
+{
+	SDL_Surface *video;
+	Uint32 Rmask, Gmask, Bmask;
+	Uint32 prev_flags;
+	DWORD style;
+	const DWORD directstyle =
+			(WS_POPUP);
+	const DWORD windowstyle = 
+			(WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX);
+	const DWORD resizestyle =
+			(WS_THICKFRAME|WS_MAXIMIZEBOX);
+	int screenWidth, screenHeight;
+	BOOL was_visible;
+
+	/* We negociate legacy GAPI if we want a screen that fits in QVGA */
+	if (_OzoneAvailable && _OzoneFrameBuffer && (width <= GetSystemMetrics(SM_CXSCREEN) || width <= GetSystemMetrics(SM_CYSCREEN)) &&
+						     (height <= GetSystemMetrics(SM_CXSCREEN) || height <= GetSystemMetrics(SM_CYSCREEN))) {
+			OutputDebugString(TEXT("Ozone workaround, switching back to GAPI\r\n"));
+			ozoneHack = 0;
+			checkGAPI(&this->hidden->gapiFuncs.dynamicGXGetDisplayProperties, 
+				&this->hidden->gapiFuncs.dynamicGXOpenDisplay, 
+				&this->hidden->gapiFuncs.dynamicGXCloseDisplay, 
+				&this->hidden->gapiFuncs.dynamicGXBeginDraw, 
+				&this->hidden->gapiFuncs.dynamicGXEndDraw, 
+				&this->hidden->gapiFuncs.dynamicGXSuspend, 
+				&this->hidden->gapiFuncs.dynamicGXResume, 
+				TRUE);
+			this->hidden->displayProps = this->hidden->gapiFuncs.dynamicGXGetDisplayProperties();
+	}
+	/* Otherwise we'll use the new system call */
+	if (_OzoneAvailable && !_OzoneFrameBuffer && (width > GetSystemMetrics(SM_CXSCREEN) && width > GetSystemMetrics(SM_CYSCREEN)) && 
+		                                         (height > GetSystemMetrics(SM_CXSCREEN) && height > GetSystemMetrics(SM_CYSCREEN))) {
+			OutputDebugString(TEXT("Ozone workaround, switching back to true Ozone\r\n"));
+			checkGAPI(&this->hidden->gapiFuncs.dynamicGXGetDisplayProperties, 
+				&this->hidden->gapiFuncs.dynamicGXOpenDisplay, 
+				&this->hidden->gapiFuncs.dynamicGXCloseDisplay, 
+				&this->hidden->gapiFuncs.dynamicGXBeginDraw, 
+				&this->hidden->gapiFuncs.dynamicGXEndDraw, 
+				&this->hidden->gapiFuncs.dynamicGXSuspend, 
+				&this->hidden->gapiFuncs.dynamicGXResume, 
+				FALSE);
+			this->hidden->displayProps = this->hidden->gapiFuncs.dynamicGXGetDisplayProperties();
+	}
+	/* Which will need a tiny input hack if the original code does not have the "Hi Res" aware ressource property set */
+	ozoneHack = 0;
+	if (_OzoneFrameBuffer && (GetSystemMetrics(SM_CXSCREEN) != _OzoneDisplayProperties.cxWidth ||
+							  GetSystemMetrics(SM_CYSCREEN) != _OzoneDisplayProperties.cyHeight)) {
+				OutputDebugString(TEXT("Running true Ozone with stylus hack\r\n"));
+				ozoneHack = 1;
+	}
+
+	/* See whether or not we should center the window */
+	was_visible = IsWindowVisible(SDL_Window);
+
+	/* Recalculate bitmasks if necessary */
+	if (bpp == current->format->BitsPerPixel) {
+		video = current;
+	}
+	else {
+		switch(bpp) {
+			case 8:
+				Rmask = 0;
+				Gmask = 0;
+				Bmask = 0;
+				break;
+			case 15:				
+			case 16:
+				/* Default is 565 unless the display is specifically 555 */
+				if (displayProperties.ffFormat & kfDirect555) {
+					Rmask = 0x00007c00;
+					Gmask = 0x000003e0;
+					Bmask = 0x0000001f;
+				}
+				else {
+					Rmask = 0x0000f800;
+					Gmask = 0x000007e0;
+					Bmask = 0x0000001f;
+				}
+				break;
+			case 24:
+			case 32:
+				Rmask = 0x00ff0000;
+				Gmask = 0x0000ff00;
+				Bmask = 0x000000ff;
+				break;
+			default:
+				SDL_SetError("Unsupported Bits Per Pixel format requested");
+				return NULL;
+		}
+		video = SDL_CreateRGBSurface(SDL_SWSURFACE,
+					0, 0, bpp, Rmask, Gmask, Bmask, 0);
+		if ( video == NULL ) {
+			SDL_OutOfMemory();
+			return(NULL);
+		}
+	}
+	
+	/* Fill in part of the video surface */
+	prev_flags = video->flags;
+	video->flags = 0;	/* Clear flags */
+	video->w = width;
+	video->h = height;
+	video->pitch = SDL_CalculatePitch(video);
+	mainSurfaceWidth = width;
+	mainSurfaceHeight = height;	
+
+//#ifdef WIN32_PLATFORM_PSPC
+	/* Hide taskbar */	
+	if ( flags & SDL_FULLSCREEN ) {
+		if ( !(prev_flags & SDL_FULLSCREEN) ) {
+			//SHFullScreen(SDL_Window, SHFS_HIDETASKBAR | SHFS_HIDESIPBUTTON | SHFS_HIDESTARTICON);
+			//ShowWindow(FindWindow(TEXT("HHTaskBar"),NULL),SW_HIDE);
+			DIB_ShowTaskBar(FALSE);
+		}
+		video->flags |= SDL_FULLSCREEN;
+	} else {
+		if ( prev_flags & SDL_FULLSCREEN ) {
+			//SHFullScreen(SDL_Window, SHFS_SHOWTASKBAR | SHFS_SHOWSIPBUTTON | SHFS_SHOWSTARTICON);
+			//ShowWindow(FindWindow(TEXT("HHTaskBar"),NULL),SW_SHOWNORMAL);
+			DIB_ShowTaskBar(TRUE);
+		}
+	}
+//#endif
+
+	/* Reset the palette and create a new one if necessary */	
+	if (screenPal != NULL) {
+		DeleteObject(screenPal);
+		screenPal = NULL;
+	}
+
+	/* See if we need to create a translation palette */
+	if (convertPalette != NULL) {
+		free(convertPalette);
+	}
+	if (bpp == 8) {
+		OutputDebugString(TEXT("creating palette\r\n"));
+		convertPalette = (unsigned short*)malloc(256 * sizeof(unsigned short));
+	}
+
+	if (displayProperties.ffFormat & kfPalette) {
+		/* Will only be able to support 256 colors in this mode */
+		// FIXME
+		//screenPal = GAPI_CreatePalette();
+	}
+
+	/* Set Window style */
+	style = GetWindowLong(SDL_Window, GWL_STYLE);
+	if ( (video->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
+		style &= ~windowstyle;
+		style |= directstyle;
+	} else {
+		if ( flags & SDL_NOFRAME ) {
+			style &= ~windowstyle;
+			style |= directstyle;
+			video->flags |= SDL_NOFRAME;
+		} else {
+			style &= ~directstyle;
+			style |= windowstyle;
+			if ( flags & SDL_RESIZABLE ) {
+				style |= resizestyle;
+				video->flags |= SDL_RESIZABLE;
+			}
+		}
+#if WS_MAXIMIZE
+		if (IsZoomed(SDL_Window)) style |= WS_MAXIMIZE;
+#endif
+	}
+
+	if (!SDL_windowid)
+		SetWindowLong(SDL_Window, GWL_STYLE, style);
+
+	/* Allocate bitmap */
+	if (gapiBuffer) {
+		free(gapiBuffer);
+		gapiBuffer = NULL;
+	}
+	gapiBuffer = malloc(video->h * video->pitch);
+	video->pixels = gapiBuffer;
+
+	/* See if we will rotate */
+	rotation = SDL_ROTATE_NONE;
+	screenWidth = getScreenWidth();
+	screenHeight = getScreenHeight();
+	if ((flags & SDL_FULLSCREEN) && 
+		(width > screenWidth && width <= screenHeight)
+		) 
+	{
+			rotation = SDL_ROTATE_LEFT;
+	}
+	/* Compute the different drawing properties */
+	switch(rotation) {
+		case SDL_ROTATE_NONE:
+			dstPixelstep = displayProperties.cbxPitch;
+			dstLinestep = displayProperties.cbyPitch;
+			startOffset = 0;
+			break;
+		case SDL_ROTATE_LEFT:
+			dstPixelstep = -displayProperties.cbyPitch;
+			dstLinestep = displayProperties.cbxPitch;
+			startOffset = displayProperties.cbyPitch * (displayProperties.cyHeight - 1);
+			break;
+		case SDL_ROTATE_RIGHT:
+			dstPixelstep = displayProperties.cbyPitch;
+			dstLinestep = -displayProperties.cbxPitch;
+			startOffset = displayProperties.cbxPitch * (displayProperties.cxWidth - 1);
+			break;
+	}
+	/* Compute padding */
+	padWidth = 0;
+	padHeight = 0;
+	if (rotation == SDL_ROTATE_NONE) {
+		if (getScreenWidth() > width)
+			padWidth = (getScreenWidth() - width) / 2;
+		if (getScreenHeight() > height)
+			padHeight = (getScreenHeight() - height) / 2;
+	}
+	else {
+		if (getScreenWidth() > height)
+			padWidth = (getScreenWidth() - height) / 2;
+		if (getScreenHeight() > width)
+			padHeight = (getScreenHeight() - width) / 2;
+	}
+	srcLinestep = video->pitch;
+	srcPixelstep = (bpp == 15 ? 2 : bpp / 8);
+	
+	MoveWindow(SDL_Window, 0, 0, getScreenWidth(), getScreenHeight(), FALSE);
+	ShowWindow(SDL_Window, SW_SHOW);
+
+	/* Resize the window */
+	//if ( SDL_windowid == NULL ) {
+	if (0) {
+		HWND top;
+		UINT swp_flags;
+		RECT bounds;
+		int x,y;
+
+		SDL_resizing = 1;
+		bounds.left = 0;
+		bounds.top = 0;
+		bounds.right = video->w;
+		bounds.bottom = video->h;
+		AdjustWindowRectEx(&bounds, GetWindowLong(SDL_Window, GWL_STYLE), FALSE, 0);
+		width = bounds.right-bounds.left;
+		height = bounds.bottom-bounds.top;
+		x = (getScreenWidth()-width)/2;
+		y = (getScreenHeight()-height)/2;
+		if ( y < 0 ) { /* Cover up title bar for more client area */
+			y -= GetSystemMetrics(SM_CYCAPTION)/2;
+		}
+		swp_flags = (SWP_FRAMECHANGED | SWP_SHOWWINDOW);
+		if ( was_visible && !(flags & SDL_FULLSCREEN) ) {
+			swp_flags |= SWP_NOMOVE;
+		}
+		if ( flags & SDL_FULLSCREEN ) {
+			top = HWND_TOPMOST;
+		} else {
+			top = HWND_NOTOPMOST;
+		}
+
+		if (flags & SDL_FULLSCREEN) {
+			SetWindowPos(SDL_Window, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
+			ShowWindow(SDL_Window, SW_SHOW);
+		}
+		else
+			SetWindowPos(SDL_Window, top, x, y, width, height, swp_flags);
+		
+		SDL_resizing = 0;
+		SetForegroundWindow(SDL_Window);
+	}
+	
+	/* Open GAPI display */
+	GXOpenDisplay(SDL_Window, (flags & SDL_FULLSCREEN ? GX_FULLSCREEN : 0));
+
+	/* Grab hardware keys if necessary */
+	if (flags & SDL_FULLSCREEN)
+		GAPI_GrabHardwareKeys(TRUE);
+
+	/* Blank screen */
+	memset(GXBeginDraw(), 0, getScreenWidth() * getScreenHeight() * 2);
+	GXEndDraw();
+
+	/* We're done */
+	return(video);
+}
+
+/* We don't actually allow hardware surfaces other than the main one */
+static int GAPI_AllocHWSurface(_THIS, SDL_Surface *surface)
+{
+	return(-1);
+}
+static void GAPI_FreeHWSurface(_THIS, SDL_Surface *surface)
+{
+	return;
+}
+
+/* We need to wait for vertical retrace on page flipped displays */
+static int GAPI_LockHWSurface(_THIS, SDL_Surface *surface)
+{
+	return(0);
+}
+
+static void GAPI_UnlockHWSurface(_THIS, SDL_Surface *surface)
+{
+	return;
+}
+
+static void updateLine(_THIS, unsigned char *srcPointer, unsigned char *destPointer, int width) {
+	// FIXME, we assume everything is in the correct format, either 16 bits 565 or 555, or 8 bits
+	int i;
+	for (i=0; i<width; i++) {
+		if (!convertPalette) {
+			*(unsigned short*)destPointer = *(unsigned short*)srcPointer;
+		}
+		else {
+			*(unsigned short*)destPointer = convertPalette[*srcPointer];
+		}
+			
+		destPointer += dstPixelstep;
+		srcPointer += srcPixelstep;
+	}
+}
+
+static void GAPI_UpdateRects(_THIS, int numrects, SDL_Rect *rects)
+{
+	int i;
+	unsigned char *screenBuffer;
+
+	screenBuffer = GXBeginDraw();
+
+	for (i=0; i<numrects; i++) {
+		unsigned char *destPointer = screenBuffer + startOffset + ((rects[i].x + padWidth) * dstPixelstep) + ((rects[i].y + padHeight) * dstLinestep);
+		unsigned char *srcPointer = (unsigned char*)gapiBuffer + (rects[i].x * srcPixelstep) + (rects[i].y * srcLinestep);
+		int height = rects[i].h;
+
+		while (height) {
+			updateLine(this, srcPointer, destPointer, rects[i].w);
+			destPointer += dstLinestep;
+			srcPointer += srcLinestep;
+			height--;
+		}
+	}
+
+	GXEndDraw();
+}
+
+/*
+#define ADVANCE_PARTIAL(address, step) \
+	bitshift += displayProperties.cBPP;             \
+	if(bitshift >= 8)                  \
+	{                                  \
+		bitshift = 0;                  \
+		bitmask = (1<<displayProperties.cBPP)-1;    \
+		address += step;               \
+	}                                  \
+	else                               \
+		bitmask <<= displayProperties.cBPP;
+
+#define ADVANCE_REV_PARTIAL(address, step)        \
+	bitshift -= gxdp.cBPP;                        \
+	if(bitshift < 0)                              \
+	{                                             \
+		bitshift = 8-displayProperties.cBPP;                   \
+		bitmask = ((1<<displayProperties.cBPP)-1)<<bitshift;   \
+		address += step;                          \
+	}                                             \
+	else                                          \
+		bitmask >>= displayProperties.cBPP;
+
+
+static void GAPI_UpdateRectsMono(_THIS, int numrects, SDL_Rect *rects)
+{
+	int i;
+	unsigned char *screenBuffer;
+
+	screenBuffer = GXBeginDraw();
+
+	for (i=0; i<numrects; i++) {
+		unsigned char *destPointer = screenBuffer + startOffset + (rects[i].x * dstPixelstep) + (rects[i].y * dstLinestep);
+		unsigned char *srcPointer = (unsigned char*)gapiBuffer + (rects[i].x * srcPixelstep) + (rects[i].y * srcLinestep);
+		unsigned char bitmask;
+		int bitshift;
+
+		int height = rects[i].h;
+		while (height) {
+			updateLine(_THIS, srcPointer, destPointer, rects[i].w);
+			destPointer += dstLinestep;
+			srcPointer += srcLinestep;
+			height--;
+		}
+	}
+
+	GXEndDraw();
+}
+*/
+
+/* -------------------------------------------------------------------------------- */
+// Global fixme for paletted mode !
+
+#define COLORCONV565(r,g,b) (((r&0xf8)<<(11-3))|((g&0xfc)<<(5-2))|((b&0xf8)>>3))
+
+#define COLORCONV555(r,g,b) (((r&0xf8)<<(10-3))|((g&0xf8)<<(5-2))|((b&0xf8)>>3))
+
+int GAPI_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
+{
+	int i;
+	/* Convert colors to appropriate 565 or 555 mapping */
+	for (i=0; i<ncolors; i++) 
+		convertPalette[firstcolor + i] = (videoMode == GAPI_DIRECT_565 ? 
+			COLORCONV565(colors[i].r, colors[i].g, colors[i].b) :
+			COLORCONV555(colors[i].r, colors[i].g, colors[i].b));
+	return(1);
+}
+
+static void GAPI_RealizePalette(_THIS)
+{
+	OutputDebugString(TEXT("GAPI_RealizePalette NOT IMPLEMENTED !\r\n"));
+}
+
+static void GAPI_PaletteChanged(_THIS, HWND window)
+{
+	OutputDebugString(TEXT("GAPI_PaletteChanged NOT IMPLEMENTED !\r\n"));
+}
+
+/* Exported for the windows message loop only */
+static void GAPI_WinPAINT(_THIS, HDC hdc)
+{
+	OutputDebugString(TEXT("GAPI_WinPAINT NOT IMPLEMENTED !\r\n"));
+}
+
+
+/* Note:  If we are terminated, this could be called in the middle of
+   another SDL video routine -- notably UpdateRects.
+*/
+void GAPI_VideoQuit(_THIS)
+{
+	/* Destroy the window and everything associated with it */
+	if ( SDL_Window ) {
+		/* Delete the screen bitmap (also frees screen->pixels) */
+		if ( this->screen ) {
+//#ifdef WIN32_PLATFORM_PSPC
+			if ( this->screen->flags & SDL_FULLSCREEN ) {
+				/* Unhide taskbar, etc. */
+				//SHFullScreen(SDL_Window, SHFS_SHOWTASKBAR | SHFS_SHOWSIPBUTTON | SHFS_SHOWSTARTICON);
+				//ShowWindow(FindWindow(TEXT("HHTaskBar"),NULL),SW_SHOWNORMAL);
+				DIB_ShowTaskBar(TRUE);
+				GAPI_GrabHardwareKeys(FALSE);
+			}
+//#endif
+
+			if (this->screen->pixels != NULL)
+			{
+				free(this->screen->pixels);
+				this->screen->pixels = NULL;
+			}
+
+			if (GXCloseDisplay)
+				GXCloseDisplay();
+		}
+	}
+}
+
+void GAPI_GrabHardwareKeys(BOOL grab) {
+	HINSTANCE GAPI_handle;
+	tGXVoidFunction GAPIActionInput;
+
+	GAPI_handle = LoadLibrary(TEXT("gx.dll"));
+	if (!GAPI_handle)
+		return;
+	GAPIActionInput = (tGXVoidFunction)GetProcAddress(GAPI_handle, (grab ? TEXT("?GXOpenInput@@YAHXZ") : TEXT("?GXCloseInput@@YAHXZ")));
+	if (GAPIActionInput) {
+		GAPIActionInput();
+	}
+	FreeLibrary(GAPI_handle);
+}
diff -Nru /tmp/SDL-1.2.6/src/video/wingapi/SDL_gapivideo.c SDL-1.2.6/src/video/wingapi/SDL_gapivideo.c
--- /tmp/SDL-1.2.6/src/video/wingapi/SDL_gapivideo.c	1970-01-01 02:00:00.000000000 +0200
+++ SDL-1.2.6/src/video/wingapi/SDL_gapivideo.c	2006-07-10 22:04:18.000000000 +0300
@@ -0,0 +1,1052 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  Sam Lantinga
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public
+    License along with this library; if not, write to the Free
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+    Sam Lantinga
+    slouken@libsdl.org
+*/
+
+#ifdef SAVE_RCSID
+static char rcsid =
+ "@(#) $Id: SDL_gapivideo.c,v 1.5 2004/02/29 21:54:11 lemure Exp $";
+#endif
+
+/* Dummy SDL video driver implementation; this is just enough to make an
+ *  SDL-based application THINK it's got a working video driver, for
+ *  applications that call SDL_Init(SDL_INIT_VIDEO) when they don't need it,
+ *  and also for use as a collection of stubs when porting SDL to a new
+ *  platform for which you haven't yet written a valid video driver.
+ *
+ * This is also a great way to determine bottlenecks: if you think that SDL
+ *  is a performance problem for a given platform, enable this driver, and
+ *  then see if your application runs faster without video overhead.
+ *
+ * Initial work by Ryan C. Gordon (icculus@linuxgames.com). A good portion
+ *  of this was cut-and-pasted from Stephane Peter's work in the AAlib
+ *  SDL video driver.  Renamed to "DUMMY" by Sam Lantinga.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <malloc.h>
+#include <windows.h>
+
+/* Not yet in the mingw32 cross-compile headers */
+#ifndef CDS_FULLSCREEN
+#define CDS_FULLSCREEN	4
+#endif
+
+#ifndef WS_THICKFRAME
+#define WS_THICKFRAME 0
+#endif
+
+#include "SDL.h"
+#include "SDL_mutex.h"
+#include "SDL_syswm.h"
+#include "SDL_sysvideo.h"
+#include "SDL_sysevents.h"
+#include "SDL_events_c.h"
+#include "SDL_pixels_c.h"
+#include "SDL_syswm_c.h"
+#include "SDL_sysmouse_c.h"
+#include "SDL_dibevents_c.h"
+#include "SDL_gapivideo.h"
+
+//#if defined(WIN32_PLATFORM_PSPC)
+//#include <aygshell.h>                      // Add Pocket PC includes
+//#pragma comment( lib, "aygshell" )         // Link Pocket PC library
+//#endif
+
+#ifdef _WIN32_WCE
+extern void DIB_ShowTaskBar(BOOL taskBarShown);
+#endif
+
+
+/* Initialization/Query functions */
+static int GAPI_VideoInit(_THIS, SDL_PixelFormat *vformat);
+static SDL_Rect **GAPI_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
+static SDL_Surface *GAPI_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
+static int GAPI_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
+static void GAPI_VideoQuit(_THIS);
+
+
+/* Hardware surface functions */
+static int GAPI_AllocHWSurface(_THIS, SDL_Surface *surface);
+static int GAPI_LockHWSurface(_THIS, SDL_Surface *surface);
+static void GAPI_UnlockHWSurface(_THIS, SDL_Surface *surface);
+static void GAPI_FreeHWSurface(_THIS, SDL_Surface *surface);
+
+/* Windows message handling functions, will not be processed */
+static void GAPI_RealizePalette(_THIS);
+static void GAPI_PaletteChanged(_THIS, HWND window);
+static void GAPI_WinPAINT(_THIS, HDC hdc);
+
+static void GAPI_UpdateRects(_THIS, int numrects, SDL_Rect *rects); 
+/*static void GAPI_UpdateRectsMono(_THIS, int numrects, SDL_Rect *rects);*/
+
+static int GAPI_Available(void);
+static SDL_VideoDevice *GAPI_CreateDevice(int devindex);
+
+void GAPI_GrabHardwareKeys(BOOL grab);
+
+VideoBootStrap WINGAPI_bootstrap = {
+	"wingapi", "WinCE GAPI",
+	GAPI_Available, GAPI_CreateDevice
+};
+
+/* 2003 SE GAPI emulation */
+
+#define GETRAWFRAMEBUFFER   0x00020001
+
+#define FORMAT_565 1
+#define FORMAT_555 2
+#define FORMAT_OTHER 3
+
+static void* _OzoneFrameBuffer = NULL;
+static struct GXDisplayProperties _OzoneDisplayProperties;
+static char _OzoneAvailable = 0;
+
+typedef struct _RawFrameBufferInfo
+{
+   WORD wFormat;
+   WORD wBPP;
+   VOID *pFramePointer;
+   int  cxStride;
+   int  cyStride;
+   int  cxPixels;
+   int  cyPixels;
+} RawFrameBufferInfo;
+
+
+struct GXDisplayProperties Ozone_GetDisplayProperties(void) {
+	return _OzoneDisplayProperties;
+}
+
+int Ozone_OpenDisplay(HWND window, unsigned long flag) {
+	return 1;
+}
+
+int Ozone_CloseDisplay(void) {
+	return 1;
+}
+
+void* Ozone_BeginDraw(void) {
+	return _OzoneFrameBuffer;
+}
+
+int Ozone_EndDraw(void) {
+	return 1;
+}
+
+int Ozone_Suspend(void) {
+	return 1;
+}
+
+int Ozone_Resume(void) {
+	return 1;
+}
+
+/*
+void debugLog(char *txt) {
+	FILE *logFile;
+	logFile = fopen("\\SDL_log.txt", "a");
+	fprintf(logFile, "%s\n", txt);
+	fclose(logFile);
+}
+
+
+void debugLogInt(char *txt, int x) {
+	FILE *logFile;
+	logFile = fopen("\\SDL_log.txt", "a");
+	fprintf(logFile, "%s %d\n", txt, x);
+	fclose(logFile);
+}
+*/
+
+static HINSTANCE checkOzone(tGXDisplayProperties *gxGetDisplayProperties, tGXOpenDisplay *gxOpenDisplay,
+					  tGXVoidFunction *gxCloseDisplay, tGXBeginDraw *gxBeginDraw, 
+					  tGXVoidFunction *gxEndDraw, tGXVoidFunction *gxSuspend, tGXVoidFunction *gxResume) {
+#ifdef ARM
+
+	int result;
+	RawFrameBufferInfo frameBufferInfo;
+	HDC hdc = GetDC(NULL);
+	result = ExtEscape(hdc, GETRAWFRAMEBUFFER, 0, NULL, sizeof(RawFrameBufferInfo), (char *)&frameBufferInfo);
+	ReleaseDC(NULL, hdc);
+	if (result < 0)
+		return NULL;
+	OutputDebugString(TEXT("Running on Ozone\r\n"));
+
+	//debugLog("Running on Ozone");
+
+	_OzoneAvailable = 1;
+
+	// Initializing global parameters
+	_OzoneFrameBuffer = frameBufferInfo.pFramePointer;
+	_OzoneDisplayProperties.cBPP = frameBufferInfo.wBPP;
+	_OzoneDisplayProperties.cbxPitch = frameBufferInfo.cxStride;
+	_OzoneDisplayProperties.cbyPitch = frameBufferInfo.cyStride;
+	_OzoneDisplayProperties.cxWidth = frameBufferInfo.cxPixels;
+	_OzoneDisplayProperties.cyHeight = frameBufferInfo.cyPixels;
+
+
+	//debugLogInt("Ozone width" ,_OzoneDisplayProperties.cxWidth);
+	//debugLogInt("Ozone height" ,_OzoneDisplayProperties.cyHeight);
+
+	if (frameBufferInfo.wFormat == FORMAT_565)
+		_OzoneDisplayProperties.ffFormat = kfDirect565;
+	else
+	if (frameBufferInfo.wFormat == FORMAT_555)
+		_OzoneDisplayProperties.ffFormat = kfDirect555;
+	else {
+		OutputDebugString(TEXT("Ozone unknown screen format"));
+		return NULL;
+	}
+
+	if (gxGetDisplayProperties)
+		*gxGetDisplayProperties = Ozone_GetDisplayProperties;
+	if (gxOpenDisplay)
+		*gxOpenDisplay = Ozone_OpenDisplay;
+	if (gxCloseDisplay)
+		*gxCloseDisplay = Ozone_CloseDisplay;
+	if (gxBeginDraw)
+		*gxBeginDraw = Ozone_BeginDraw;
+	if (gxEndDraw)
+		*gxEndDraw = Ozone_EndDraw;
+	if (gxSuspend)
+		*gxSuspend = Ozone_Suspend;
+	if (gxResume)
+		*gxResume = Ozone_Resume;
+
+	return (HINSTANCE)1;
+
+#else
+
+	return NULL;
+
+#endif
+}
+
+int getScreenWidth() {
+	return (_OzoneFrameBuffer ? _OzoneDisplayProperties.cxWidth : GetSystemMetrics(SM_CXSCREEN));
+}
+
+int getScreenHeight() {
+	return (_OzoneFrameBuffer ? _OzoneDisplayProperties.cyHeight : GetSystemMetrics(SM_CYSCREEN));
+}
+
+
+/* Check GAPI library */
+
+#define IMPORT(Handle,Variable,Type,Function, Store) \
+        Variable = GetProcAddress(Handle, TEXT(Function)); \
+		if (!Variable) { \
+			FreeLibrary(Handle); \
+			return NULL; \
+		} \
+		if (Store) \
+			*Store = (Type)Variable;
+
+static HINSTANCE checkGAPI(tGXDisplayProperties *gxGetDisplayProperties, tGXOpenDisplay *gxOpenDisplay,
+					  tGXVoidFunction *gxCloseDisplay, tGXBeginDraw *gxBeginDraw, 
+					  tGXVoidFunction *gxEndDraw, tGXVoidFunction *gxSuspend, tGXVoidFunction *gxResume,
+					  BOOL bypassOzone) {
+	HMODULE gapiLibrary;
+	FARPROC proc;
+	HINSTANCE result;
+	// FIXME paletted !
+	tGXDisplayProperties temp_gxGetDisplayProperties;
+
+	// Workaround for Windows Mobile 2003 SE
+	_OzoneFrameBuffer = NULL; // FIXME !!
+	if (!bypassOzone) {
+		//debugLog("No bypassOzone");
+		//_OzoneFrameBuffer = NULL;
+		result = checkOzone(gxGetDisplayProperties, gxOpenDisplay, gxCloseDisplay, gxBeginDraw, gxEndDraw, gxSuspend, gxResume);
+		if (result)
+			return result;
+	}
+
+	gapiLibrary = LoadLibrary(TEXT("gx.dll"));
+	if (!gapiLibrary)
+		return NULL;
+
+	IMPORT(gapiLibrary, proc, tGXDisplayProperties, "?GXGetDisplayProperties@@YA?AUGXDisplayProperties@@XZ", gxGetDisplayProperties)
+	IMPORT(gapiLibrary, proc, tGXOpenDisplay, "?GXOpenDisplay@@YAHPAUHWND__@@K@Z", gxOpenDisplay)
+	IMPORT(gapiLibrary, proc, tGXVoidFunction, "?GXCloseDisplay@@YAHXZ", gxCloseDisplay)
+	IMPORT(gapiLibrary, proc, tGXBeginDraw, "?GXBeginDraw@@YAPAXXZ", gxBeginDraw)
+	IMPORT(gapiLibrary, proc, tGXVoidFunction, "?GXEndDraw@@YAHXZ", gxEndDraw)
+	IMPORT(gapiLibrary, proc, tGXVoidFunction, "?GXSuspend@@YAHXZ", gxSuspend)
+	IMPORT(gapiLibrary, proc, tGXVoidFunction, "?GXResume@@YAHXZ", gxResume)
+	
+	// FIXME paletted ! for the moment we just bail out	
+	if (!gxGetDisplayProperties) {
+		IMPORT(gapiLibrary, proc, tGXDisplayProperties, "?GXGetDisplayProperties@@YA?AUGXDisplayProperties@@XZ", &temp_gxGetDisplayProperties)
+		if (temp_gxGetDisplayProperties().ffFormat & kfPalette) {
+			FreeLibrary(gapiLibrary);
+			return NULL;
+		}
+		FreeLibrary(gapiLibrary);		
+		gapiLibrary = (HINSTANCE)1;
+	}
+	
+	return gapiLibrary;
+}
+
+
+/* GAPI driver bootstrap functions */
+
+static int GAPI_Available(void)
+{
+	/* Check if the GAPI library is available */
+#ifndef GCC_BUILD
+	if (!checkGAPI(NULL, NULL, NULL, NULL, NULL, NULL, NULL, TRUE)) {
+		OutputDebugString(TEXT("GAPI driver not available\r\n"));
+		return 0;
+	}
+	else {
+		OutputDebugString(TEXT("GAPI driver available\r\n"));
+		return 1;
+	}
+#else
+	return 1;
+#endif
+}
+
+static void GAPI_DeleteDevice(SDL_VideoDevice *device)
+{
+	if (device && device->hidden && device->hidden->gapiFuncs.dynamicGXCloseDisplay)
+		device->hidden->gapiFuncs.dynamicGXCloseDisplay();
+
+	if (device && device->hidden)	
+		free(device->hidden);
+	if (device)
+		free(device);
+
+}
+
+static SDL_VideoDevice *GAPI_CreateDevice(int devindex)
+{
+	SDL_VideoDevice *device;
+/*	HINSTANCE ret;
+	GXDisplayProperties temp_gxdp;
+*/
+	/* Initialize all variables that we clean on shutdown */
+	device = (SDL_VideoDevice *)malloc(sizeof(SDL_VideoDevice));
+	if ( device ) {
+		memset(device, 0, (sizeof *device));
+		device->hidden = (struct SDL_PrivateVideoData *)
+				malloc((sizeof *device->hidden));
+	}
+	if ( (device == NULL) || (device->hidden == NULL) ) {
+		SDL_OutOfMemory();
+		if ( device ) {
+			free(device);
+		}
+		return(0);
+	}
+	memset(device->hidden, 0, (sizeof *device->hidden));
+
+	/* Set GAPI pointers */
+
+	/* Set the function pointers */
+
+	device->VideoInit = GAPI_VideoInit;
+	device->ListModes = GAPI_ListModes;
+	device->SetVideoMode = GAPI_SetVideoMode;
+	device->UpdateMouse = WIN_UpdateMouse;
+	device->SetColors = GAPI_SetColors;
+	device->UpdateRects = NULL;
+	device->VideoQuit = GAPI_VideoQuit;
+	device->AllocHWSurface = GAPI_AllocHWSurface;
+	device->CheckHWBlit = NULL;
+	device->FillHWRect = NULL;
+	device->SetHWColorKey = NULL;
+	device->SetHWAlpha = NULL;
+	device->LockHWSurface = GAPI_LockHWSurface;
+	device->UnlockHWSurface = GAPI_UnlockHWSurface;
+	device->FlipHWSurface = NULL;
+	device->FreeHWSurface = GAPI_FreeHWSurface;
+	device->SetCaption = WIN_SetWMCaption;
+	device->SetIcon = WIN_SetWMIcon;
+	device->IconifyWindow = WIN_IconifyWindow;
+	device->GrabInput = WIN_GrabInput;
+	device->GetWMInfo = WIN_GetWMInfo;
+	device->FreeWMCursor = WIN_FreeWMCursor;
+	device->CreateWMCursor = WIN_CreateWMCursor;
+	device->ShowWMCursor = WIN_ShowWMCursor;
+	device->WarpWMCursor = WIN_WarpWMCursor;
+	device->CheckMouseMode = WIN_CheckMouseMode;
+	device->InitOSKeymap = DIB_InitOSKeymap;
+	device->PumpEvents = DIB_PumpEvents;
+
+	device->SetColors = GAPI_SetColors;
+
+	/* Set up the windows message handling functions */
+	WIN_RealizePalette = GAPI_RealizePalette;
+	WIN_PaletteChanged = GAPI_PaletteChanged;
+	WIN_WinPAINT = GAPI_WinPAINT;
+	HandleMessage = DIB_HandleMessage;
+
+	device->free = GAPI_DeleteDevice;
+	
+	
+	/*
+	device->VideoInit = GAPI_VideoInit;
+	device->ListModes = GAPI_ListModes;
+	device->SetVideoMode = GAPI_SetVideoMode;
+	device->CreateYUVOverlay = NULL;
+	device->SetColors = DUMMY_SetColors;
+	device->UpdateRects = DUMMY_UpdateRects;
+	device->VideoQuit = DUMMY_VideoQuit;
+	device->AllocHWSurface = DUMMY_AllocHWSurface;
+	device->CheckHWBlit = NULL;
+	device->FillHWRect = NULL;
+	device->SetHWColorKey = NULL;
+	device->SetHWAlpha = NULL;
+	device->LockHWSurface = DUMMY_LockHWSurface;
+	device->UnlockHWSurface = DUMMY_UnlockHWSurface;
+	device->FlipHWSurface = NULL;
+	device->FreeHWSurface = DUMMY_FreeHWSurface;
+	device->SetCaption = NULL;
+	device->SetIcon = NULL;
+	device->IconifyWindow = NULL;
+	device->GrabInput = NULL;
+	device->GetWMInfo = NULL;
+	device->InitOSKeymap = DUMMY_InitOSKeymap;
+	device->PumpEvents = DUMMY_PumpEvents;
+
+	device->free = DUMMY_DeleteDevice;
+	*/
+
+	return device;
+}
+
+
+int GAPI_VideoInit(_THIS, SDL_PixelFormat *vformat)
+{
+	HINSTANCE ret;
+	TCHAR dbgstr[150];
+
+	/* Create the window */
+	if ( DIB_CreateWindow(this) < 0 ) {
+		return(-1);
+	}
+
+	/* first try to get basic gapi support */
+	OutputDebugString(TEXT("Checking for GAPI\r\n"));
+	ret = checkGAPI(&this->hidden->gapiFuncs.dynamicGXGetDisplayProperties, 
+					&this->hidden->gapiFuncs.dynamicGXOpenDisplay, 
+					&this->hidden->gapiFuncs.dynamicGXCloseDisplay, 
+					&this->hidden->gapiFuncs.dynamicGXBeginDraw, 
+					&this->hidden->gapiFuncs.dynamicGXEndDraw, 
+					&this->hidden->gapiFuncs.dynamicGXSuspend, 
+					&this->hidden->gapiFuncs.dynamicGXResume, 
+					TRUE);
+	if (ret) {	/* found gapi */
+		OutputDebugString(TEXT("Found GAPI\r\n"));
+		this->hidden->gapiFuncs.dynamicGXOpenDisplay(SDL_Window, GX_FULLSCREEN);
+		this->hidden->displayProps = this->hidden->gapiFuncs.dynamicGXGetDisplayProperties();
+	}
+	if (((unsigned int) GetSystemMetrics(SM_CXSCREEN) != displayProperties.cxWidth) 
+		|| ((unsigned int) GetSystemMetrics(SM_CYSCREEN) != displayProperties.cyHeight)
+		|| ! ret) {
+		OutputDebugString(TEXT("Going for Ozone\r\n"));
+		/* gapi reports incorrect extents (or unavailable) so force ozone */
+		ret = checkGAPI(&this->hidden->gapiFuncs.dynamicGXGetDisplayProperties, 
+						&this->hidden->gapiFuncs.dynamicGXOpenDisplay, 
+						&this->hidden->gapiFuncs.dynamicGXCloseDisplay, 
+						&this->hidden->gapiFuncs.dynamicGXBeginDraw, 
+						&this->hidden->gapiFuncs.dynamicGXEndDraw, 
+						&this->hidden->gapiFuncs.dynamicGXSuspend, 
+						&this->hidden->gapiFuncs.dynamicGXResume, 
+						FALSE);
+		this->hidden->displayProps = this->hidden->gapiFuncs.dynamicGXGetDisplayProperties();
+	}
+
+	vformat->BitsPerPixel = (unsigned char)displayProperties.cBPP;
+
+	// print a nice debug info string
+	swprintf(dbgstr, TEXT("Running on %s driver at %dx%d (real %d, %d)\n"),
+			 _OzoneAvailable ? TEXT("Ozone") : TEXT("GAPI"),
+			 displayProperties.cxWidth, displayProperties.cyHeight,
+			 GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN) );
+	OutputDebugString(dbgstr);
+
+	// Get color mask
+	if (displayProperties.ffFormat & kfDirect565) {
+		vformat->BitsPerPixel = 16;
+		vformat->Rmask = 0x0000f800;
+		vformat->Gmask = 0x000007e0;
+		vformat->Bmask = 0x0000001f;
+		videoMode = GAPI_DIRECT_565;
+	}
+	else
+	if (displayProperties.ffFormat & kfDirect555) {
+		vformat->BitsPerPixel = 16;
+		vformat->Rmask = 0x00007c00;
+		vformat->Gmask = 0x000003e0;
+		vformat->Bmask = 0x0000001f;
+		videoMode = GAPI_DIRECT_555;
+	}
+	else
+	if ((displayProperties.ffFormat & kfDirect) && (displayProperties.cBPP <= 8)) {
+		// We'll perform the conversion
+		vformat->BitsPerPixel = 24;
+		vformat->Rmask = 0x00ff0000;
+		vformat->Gmask = 0x0000ff00;
+		vformat->Bmask = 0x000000ff;
+		if (displayProperties.ffFormat & kfDirectInverted)
+			invert = (1 << displayProperties.cBPP) - 1;
+		colorscale = displayProperties.cBPP < 8 ? 8 - displayProperties.cBPP : 0;
+		videoMode = GAPI_MONO;
+	}
+	else
+	if (displayProperties.ffFormat & kfPalette) {
+		videoMode = GAPI_PALETTE;
+	}
+
+	/* Set UpdateRect callback */
+	// FIXME
+	/*
+	if (videoMode != GAPI_MONO)
+		this->UpdateRects = GAPI_UpdateRects;
+	else
+		this->UpdateRects = GAPI_UpdateRectsMono;
+	*/
+
+	this->UpdateRects = GAPI_UpdateRects;
+	
+	/* We're done! */
+	return(0);
+}
+
+SDL_Rect **GAPI_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
+{
+   	 return (SDL_Rect **) -1;
+}
+
+SDL_Surface *GAPI_SetVideoMode(_THIS, SDL_Surface *current,
+				int width, int height, int bpp, Uint32 flags)
+{
+	SDL_Surface *video;
+	Uint32 Rmask, Gmask, Bmask;
+	Uint32 prev_flags;
+	DWORD style;
+	const DWORD directstyle =
+			(WS_VISIBLE|WS_POPUP);
+	const DWORD windowstyle = 
+			(WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX);
+	const DWORD resizestyle =
+			(WS_THICKFRAME|WS_MAXIMIZEBOX);
+	int screenWidth, screenHeight;
+	BOOL was_visible;
+	OSVERSIONINFO windowsVersion = { 0 };
+	//TCHAR platformId[100];
+
+	ozoneHack = 0;
+	/* We negociate legacy GAPI if we want a screen that fits in QVGA */
+	/* Size check was added to work properly with 3rd party VGA tools */
+
+	/*debugLog("********************REINIT**********************");
+
+	debugLogInt("Width", width);
+	debugLogInt("Height", height);
+	debugLogInt("Advertised width", GetSystemMetrics(SM_CXSCREEN));
+	debugLogInt("Advertised height", GetSystemMetrics(SM_CYSCREEN));
+	debugLogInt("OzoneAvailable", _OzoneAvailable);
+	debugLogInt("OzoneFrameBuffer", _OzoneFrameBuffer);*/
+
+	/* Switching back to GAPI on WM 5.0 seems to create funky effects */
+
+	windowsVersion.dwOSVersionInfoSize = sizeof(LPOSVERSIONINFO);
+	GetVersionEx(&windowsVersion);
+
+	// Do not revert to GAPI if Ozone is available on a Smartphone
+/*	SystemParametersInfo(SPI_GETPLATFORMTYPE, sizeof(platformId) / sizeof(TCHAR), platformId, 0);
+	if (!(_OzoneAvailable && _OzoneFrameBuffer && wcscmp(platformId, TEXT("SmartPhone")) == 0)) {
+		if (windowsVersion.dwMajorVersion < 5 && _OzoneAvailable && _OzoneFrameBuffer && !(GetSystemMetrics(SM_CXSCREEN) == 480 && GetSystemMetrics(SM_CYSCREEN) == 640) && (width <= GetSystemMetrics(SM_CXSCREEN) || width <= GetSystemMetrics(SM_CYSCREEN)) &&
+							     (height <= GetSystemMetrics(SM_CXSCREEN) || height <= GetSystemMetrics(SM_CYSCREEN))) {
+				OutputDebugString(TEXT("Ozone workaround, switching back to GAPI\r\n"));
+				//debugLog("Ozone workaround, switching back to GAPI");
+				checkGAPI(&this->hidden->gapiFuncs.dynamicGXGetDisplayProperties, 
+					&this->hidden->gapiFuncs.dynamicGXOpenDisplay, 
+					&this->hidden->gapiFuncs.dynamicGXCloseDisplay, 
+					&this->hidden->gapiFuncs.dynamicGXBeginDraw, 
+					&this->hidden->gapiFuncs.dynamicGXEndDraw,  
+					&this->hidden->gapiFuncs.dynamicGXSuspend, 
+					&this->hidden->gapiFuncs.dynamicGXResume,  
+					TRUE);
+				this->hidden->displayProps = this->hidden->gapiFuncs.dynamicGXGetDisplayProperties();
+		}
+	}
+*/	
+	/* Otherwise we'll use the new system call */
+/*	if (_OzoneAvailable && !_OzoneFrameBuffer && (width > GetSystemMetrics(SM_CXSCREEN) && width > GetSystemMetrics(SM_CYSCREEN)) && 
+		                                         (height > GetSystemMetrics(SM_CXSCREEN) && height > GetSystemMetrics(SM_CYSCREEN))) {
+			OutputDebugString(TEXT("Ozone workaround, switching back to true Ozone\r\n"));
+			//debugLog("Ozone workaround, switching back to true ozone");
+			checkGAPI(&this->hidden->gapiFuncs.dynamicGXGetDisplayProperties, 
+				&this->hidden->gapiFuncs.dynamicGXOpenDisplay, 
+				&this->hidden->gapiFuncs.dynamicGXCloseDisplay, 
+				&this->hidden->gapiFuncs.dynamicGXBeginDraw, 
+				&this->hidden->gapiFuncs.dynamicGXEndDraw, 
+				&this->hidden->gapiFuncs.dynamicGXSuspend, 
+				&this->hidden->gapiFuncs.dynamicGXResume, 
+				FALSE);
+			this->hidden->displayProps = this->hidden->gapiFuncs.dynamicGXGetDisplayProperties();
+	}
+*/	/* Which will need a tiny input hack if the original code does not have the "Hi Res" aware ressource property set */
+	if (_OzoneFrameBuffer && (GetSystemMetrics(SM_CXSCREEN) != _OzoneDisplayProperties.cxWidth ||
+							  GetSystemMetrics(SM_CYSCREEN) != _OzoneDisplayProperties.cyHeight)) {
+				OutputDebugString(TEXT("Running true Ozone with stylus hack\r\n"));
+				//debugLog("True ozone with stylus hack");
+				ozoneHack = 1;
+	}
+
+	/* See whether or not we should center the window */
+	was_visible = IsWindowVisible(SDL_Window);
+
+	/* Recalculate bitmasks if necessary */
+	if (bpp == current->format->BitsPerPixel) {
+		video = current;
+	}
+	else {
+		switch(bpp) {
+			case 8:
+				Rmask = 0;
+				Gmask = 0;
+				Bmask = 0;
+				break;
+			case 15:				
+			case 16:
+				/* Default is 565 unless the display is specifically 555 */
+				if (displayProperties.ffFormat & kfDirect555) {
+					Rmask = 0x00007c00;
+					Gmask = 0x000003e0;
+					Bmask = 0x0000001f;
+				}
+				else {
+					Rmask = 0x0000f800;
+					Gmask = 0x000007e0;
+					Bmask = 0x0000001f;
+				}
+				break;
+			case 24:
+			case 32:
+				Rmask = 0x00ff0000;
+				Gmask = 0x0000ff00;
+				Bmask = 0x000000ff;
+				break;
+			default:
+				SDL_SetError("Unsupported Bits Per Pixel format requested");
+				return NULL;
+		}
+		video = SDL_CreateRGBSurface(SDL_SWSURFACE,
+					0, 0, bpp, Rmask, Gmask, Bmask, 0);
+		if ( video == NULL ) {
+			SDL_OutOfMemory();
+			return(NULL);
+		}
+	}
+	
+	/* Fill in part of the video surface */
+	prev_flags = video->flags;
+	//video->flags = 0;	/* Clear flags */
+	video->flags = SDL_HWPALETTE; /* Clear flags */
+	video->w = width;
+	video->h = height;
+	video->pitch = SDL_CalculatePitch(video);
+	mainSurfaceWidth = width;
+	mainSurfaceHeight = height;	
+
+//#ifdef WIN32_PLATFORM_PSPC
+	/* Hide taskbar */	
+	if ( flags & SDL_FULLSCREEN ) {
+		if ( !(prev_flags & SDL_FULLSCREEN) ) {
+			//SHFullScreen(SDL_Window, SHFS_HIDETASKBAR | SHFS_HIDESIPBUTTON | SHFS_HIDESTARTICON);
+			//ShowWindow(FindWindow(TEXT("HHTaskBar"),NULL),SW_HIDE);
+			DIB_ShowTaskBar(FALSE);
+		}
+		video->flags |= SDL_FULLSCREEN;
+	} else {
+		if ( prev_flags & SDL_FULLSCREEN ) {
+			//SHFullScreen(SDL_Window, SHFS_SHOWTASKBAR | SHFS_SHOWSIPBUTTON | SHFS_SHOWSTARTICON);
+			//ShowWindow(FindWindow(TEXT("HHTaskBar"),NULL),SW_SHOWNORMAL);
+			DIB_ShowTaskBar(TRUE);
+		}
+	}
+//#endif
+
+	/* Reset the palette and create a new one if necessary */	
+	if (screenPal != NULL) {
+		DeleteObject(screenPal);
+		screenPal = NULL;
+	}
+
+	/* See if we need to create a translation palette */
+	if (convertPalette != NULL) {
+		free(convertPalette);
+	}
+	if (bpp == 8) {
+		OutputDebugString(TEXT("creating palette\r\n"));
+		convertPalette = (unsigned short*)malloc(256 * sizeof(unsigned short));
+	}
+
+	if (displayProperties.ffFormat & kfPalette) {
+		/* Will only be able to support 256 colors in this mode */
+		// FIXME
+		//screenPal = GAPI_CreatePalette();
+	}
+
+	/* Set Window style */
+	style = GetWindowLong(SDL_Window, GWL_STYLE);
+	if ( (video->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
+		style &= ~windowstyle;
+		style |= directstyle;
+	} else {
+		if ( flags & SDL_NOFRAME ) {
+			style &= ~windowstyle;
+			style |= directstyle;
+			video->flags |= SDL_NOFRAME;
+		} else {
+			style &= ~directstyle;
+			style |= windowstyle;
+			if ( flags & SDL_RESIZABLE ) {
+				style |= resizestyle;
+				video->flags |= SDL_RESIZABLE;
+			}
+		}
+#if WS_MAXIMIZE
+//		if (IsZoomed(SDL_Window)) style |= WS_MAXIMIZE;
+#endif
+	}
+
+	if (!SDL_windowid)
+		SetWindowLong(SDL_Window, GWL_STYLE, style);
+
+	/* Allocate bitmap */
+	if (gapiBuffer) {
+		free(gapiBuffer);
+		gapiBuffer = NULL;
+	}
+	gapiBuffer = malloc(video->h * video->pitch);
+	video->pixels = gapiBuffer;
+
+	/* See if we will rotate */
+	rotation = SDL_ROTATE_NONE;
+	screenWidth = getScreenWidth();
+	screenHeight = getScreenHeight();
+	//debugLog("Rotate check");
+	if ((flags & SDL_FULLSCREEN) && 
+		(width > screenWidth && width <= screenHeight)
+		) 
+	{
+			//debugLog("Need to rotate");
+			rotation = SDL_ROTATE_LEFT;
+			if (flags & SDL_FLIPVIDEO)
+				rotation = SDL_ROTATE_RIGHT;
+	}
+
+	/* Compute the different drawing properties */
+	switch(rotation) {
+		case SDL_ROTATE_NONE:
+			dstPixelstep = displayProperties.cbxPitch;
+			dstLinestep = displayProperties.cbyPitch;
+			startOffset = 0;
+			break;
+		case SDL_ROTATE_LEFT:
+			dstPixelstep = -displayProperties.cbyPitch;
+			dstLinestep = displayProperties.cbxPitch;
+			startOffset = displayProperties.cbyPitch * (displayProperties.cyHeight - 1);
+			break;
+		case SDL_ROTATE_RIGHT:
+			dstPixelstep = displayProperties.cbyPitch;
+			dstLinestep = -displayProperties.cbxPitch;
+			startOffset = displayProperties.cbxPitch * (displayProperties.cxWidth - 1);
+			break;
+	}
+	/* Compute padding */
+	padWidth = 0;
+	padHeight = 0;
+	/*
+	if (rotation == SDL_ROTATE_NONE) {
+		if (getScreenWidth() > width)
+			padWidth = (getScreenWidth() - width) / 2;
+		if (getScreenHeight() > height)
+			padHeight = (getScreenHeight() - height) / 2;
+	}
+	else {
+		if (getScreenWidth() > height)
+			padWidth = (getScreenWidth() - height) / 2;
+		if (getScreenHeight() > width)
+			padHeight = (getScreenHeight() - width) / 2;
+	}
+	*/
+	srcLinestep = video->pitch;
+	srcPixelstep = (bpp == 15 ? 2 : bpp / 8);
+	
+	MoveWindow(SDL_Window, 0, 0, getScreenWidth(), getScreenHeight(), FALSE);
+	SetWindowPos(SDL_Window, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
+	ShowWindow(SDL_Window, SW_SHOW);
+
+	/* Resize the window */
+	//if ( SDL_windowid == NULL ) {
+	if (0) {
+		HWND top;
+		UINT swp_flags;
+		RECT bounds;
+		int x,y;
+
+		SDL_resizing = 1;
+		bounds.left = 0;
+		bounds.top = 0;
+		bounds.right = video->w;
+		bounds.bottom = video->h;
+		AdjustWindowRectEx(&bounds, GetWindowLong(SDL_Window, GWL_STYLE), FALSE, 0);
+		width = bounds.right-bounds.left;
+		height = bounds.bottom-bounds.top;
+		x = (getScreenWidth()-width)/2;
+		y = (getScreenHeight()-height)/2;
+		if ( y < 0 ) { /* Cover up title bar for more client area */
+			y -= GetSystemMetrics(SM_CYCAPTION)/2;
+		}
+		swp_flags = (SWP_FRAMECHANGED | SWP_SHOWWINDOW);
+		if ( was_visible && !(flags & SDL_FULLSCREEN) ) {
+			swp_flags |= SWP_NOMOVE;
+		}
+		if ( flags & SDL_FULLSCREEN ) {
+			top = HWND_TOPMOST;
+		} else {
+			top = HWND_NOTOPMOST;
+		}
+
+		if (flags & SDL_FULLSCREEN) {
+			SetWindowPos(SDL_Window, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
+			ShowWindow(SDL_Window, SW_SHOW);
+		}
+		else
+			SetWindowPos(SDL_Window, top, x, y, width, height, swp_flags);
+		
+		SDL_resizing = 0;
+		SetForegroundWindow(SDL_Window);
+	}
+	
+	/* Open GAPI display */
+	//GXOpenDisplay(SDL_Window, (flags & SDL_FULLSCREEN ? GX_FULLSCREEN : 0));
+
+	/* Grab hardware keys if necessary */
+	if (flags & SDL_FULLSCREEN)
+		GAPI_GrabHardwareKeys(TRUE);
+
+	/* Blank screen */
+	memset(GXBeginDraw(), 0, getScreenWidth() * getScreenHeight() * 2);
+	GXEndDraw();
+
+	/* We're done */
+	return(video);
+}
+
+/* We don't actually allow hardware surfaces other than the main one */
+static int GAPI_AllocHWSurface(_THIS, SDL_Surface *surface)
+{
+	return(-1);
+}
+static void GAPI_FreeHWSurface(_THIS, SDL_Surface *surface)
+{
+	return;
+}
+
+/* We need to wait for vertical retrace on page flipped displays */
+static int GAPI_LockHWSurface(_THIS, SDL_Surface *surface)
+{
+	return(0);
+}
+
+static void GAPI_UnlockHWSurface(_THIS, SDL_Surface *surface)
+{
+	return;
+}
+
+static void updateLine(_THIS, unsigned char *srcPointer, unsigned char *destPointer, int width) {
+	// FIXME, we assume everything is in the correct format, either 16 bits 565 or 555, or 8 bits
+	int i;
+	for (i=0; i<width; i++) {
+		if (!convertPalette) {
+			*(unsigned short*)destPointer = *(unsigned short*)srcPointer;
+		}
+		else {
+			*(unsigned short*)destPointer = convertPalette[*srcPointer];
+		}
+			
+		destPointer += dstPixelstep;
+		srcPointer += srcPixelstep; 
+	}
+}
+
+static void GAPI_UpdateRects(_THIS, int numrects, SDL_Rect *rects)
+{
+	int i;
+	unsigned char *screenBuffer;
+
+	screenBuffer = GXBeginDraw();
+
+	for (i=0; i<numrects; i++) {
+		unsigned char *destPointer = screenBuffer + startOffset + ((rects[i].x + padWidth) * dstPixelstep) + ((rects[i].y + padHeight) * dstLinestep);
+		unsigned char *srcPointer = (unsigned char*)gapiBuffer + (rects[i].x * srcPixelstep) + (rects[i].y * srcLinestep);
+		int height = rects[i].h;
+
+		while (height) {
+			updateLine(this, srcPointer, destPointer, rects[i].w);
+			destPointer += dstLinestep;
+			srcPointer += srcLinestep;
+			height--;
+		}
+	}
+
+	GXEndDraw();
+}
+
+/*
+#define ADVANCE_PARTIAL(address, step) \
+	bitshift += displayProperties.cBPP;             \
+	if(bitshift >= 8)                  \
+	{                                  \
+		bitshift = 0;                  \
+		bitmask = (1<<displayProperties.cBPP)-1;    \
+		address += step;               \
+	}                                  \
+	else                               \
+		bitmask <<= displayProperties.cBPP;
+
+#define ADVANCE_REV_PARTIAL(address, step)        \
+	bitshift -= gxdp.cBPP;                        \
+	if(bitshift < 0)                              \
+	{                                             \
+		bitshift = 8-displayProperties.cBPP;                   \
+		bitmask = ((1<<displayProperties.cBPP)-1)<<bitshift;   \
+		address += step;                          \
+	}                                             \
+	else                                          \
+		bitmask >>= displayProperties.cBPP;
+
+
+static void GAPI_UpdateRectsMono(_THIS, int numrects, SDL_Rect *rects)
+{
+	int i;
+	unsigned char *screenBuffer;
+
+	screenBuffer = GXBeginDraw();
+
+	for (i=0; i<numrects; i++) {
+		unsigned char *destPointer = screenBuffer + startOffset + (rects[i].x * dstPixelstep) + (rects[i].y * dstLinestep);
+		unsigned char *srcPointer = (unsigned char*)gapiBuffer + (rects[i].x * srcPixelstep) + (rects[i].y * srcLinestep);
+		unsigned char bitmask;
+		int bitshift;
+
+		int height = rects[i].h;
+		while (height) {
+			updateLine(_THIS, srcPointer, destPointer, rects[i].w);
+			destPointer += dstLinestep;
+			srcPointer += srcLinestep;
+			height--;
+		}
+	}
+
+	GXEndDraw();
+}
+*/
+
+/* -------------------------------------------------------------------------------- */
+// Global fixme for paletted mode !
+
+#define COLORCONV565(r,g,b) (((r&0xf8)<<(11-3))|((g&0xfc)<<(5-2))|((b&0xf8)>>3))
+
+#define COLORCONV555(r,g,b) (((r&0xf8)<<(10-3))|((g&0xf8)<<(5-2))|((b&0xf8)>>3))
+
+int GAPI_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
+{
+	int i;
+	/* Convert colors to appropriate 565 or 555 mapping */
+	for (i=0; i<ncolors; i++) 
+		convertPalette[firstcolor + i] = (videoMode == GAPI_DIRECT_565 ? 
+			COLORCONV565(colors[i].r, colors[i].g, colors[i].b) :
+			COLORCONV555(colors[i].r, colors[i].g, colors[i].b));
+	return(1);
+}
+
+static void GAPI_RealizePalette(_THIS)
+{
+	OutputDebugString(TEXT("GAPI_RealizePalette NOT IMPLEMENTED !\r\n"));
+}
+
+static void GAPI_PaletteChanged(_THIS, HWND window)
+{
+	OutputDebugString(TEXT("GAPI_PaletteChanged NOT IMPLEMENTED !\r\n"));
+}
+
+/* Exported for the windows message loop only */
+static void GAPI_WinPAINT(_THIS, HDC hdc)
+{
+	OutputDebugString(TEXT("GAPI_WinPAINT NOT IMPLEMENTED !\r\n"));
+}
+
+
+/* Note:  If we are terminated, this could be called in the middle of
+   another SDL video routine -- notably UpdateRects.
+*/
+void GAPI_VideoQuit(_THIS)
+{
+	/* Destroy the window and everything associated with it */
+	if ( SDL_Window ) {
+		/* Delete the screen bitmap (also frees screen->pixels) */
+		if ( this->screen ) {
+//#ifdef WIN32_PLATFORM_PSPC
+			if ( this->screen->flags & SDL_FULLSCREEN ) {
+				/* Unhide taskbar, etc. */
+				//SHFullScreen(SDL_Window, SHFS_SHOWTASKBAR | SHFS_SHOWSIPBUTTON | SHFS_SHOWSTARTICON);
+				//ShowWindow(FindWindow(TEXT("HHTaskBar"),NULL),SW_SHOWNORMAL);
+				DIB_ShowTaskBar(TRUE);
+				GAPI_GrabHardwareKeys(FALSE);
+			}
+//#endif
+
+			if (this->screen->pixels != NULL)
+			{
+				free(this->screen->pixels);
+				this->screen->pixels = NULL;
+			}
+
+			if (GXCloseDisplay)
+				GXCloseDisplay();
+		}
+	}
+}
+
+void GAPI_GrabHardwareKeys(BOOL grab) {
+	HINSTANCE GAPI_handle;
+	tGXVoidFunction GAPIActionInput;
+
+	GAPI_handle = LoadLibrary(TEXT("gx.dll"));
+	if (!GAPI_handle)
+		return;
+	GAPIActionInput = (tGXVoidFunction)GetProcAddress(GAPI_handle, (grab ? TEXT("?GXOpenInput@@YAHXZ") : TEXT("?GXCloseInput@@YAHXZ")));
+	if (GAPIActionInput) {
+		GAPIActionInput();
+	}
+	FreeLibrary(GAPI_handle);
+}
diff -Nru /tmp/SDL-1.2.6/src/video/wingapi/SDL_gapivideo.h SDL-1.2.6/src/video/wingapi/SDL_gapivideo.h
--- /tmp/SDL-1.2.6/src/video/wingapi/SDL_gapivideo.h	1970-01-01 02:00:00.000000000 +0200
+++ SDL-1.2.6/src/video/wingapi/SDL_gapivideo.h	2004-05-30 15:57:48.000000000 +0300
@@ -0,0 +1,192 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  Sam Lantinga
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public
+    License along with this library; if not, write to the Free
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+    Sam Lantinga
+    slouken@libsdl.org
+*/
+
+#ifdef SAVE_RCSID
+static char rcsid =
+ "@(#) $Id: SDL_gapivideo.h,v 1.1 2004/02/02 23:25:35 lemure Exp $";
+#endif
+
+#ifndef _SDL_gapivideo_h
+#define _SDL_gapivideo_h
+
+#include <windows.h>
+
+/* -------------------------------------------------------------------------------------------- */
+
+/* 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;
+};
+
+#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()
+
+/* -------------------------------------------------------------------------------------------- */
+
+/* Rotation direction */
+typedef enum {
+	SDL_ROTATE_NONE,
+	SDL_ROTATE_LEFT,
+	SDL_ROTATE_RIGHT
+} SDL_RotateAttr;
+
+/* GAPI video mode */
+typedef enum {
+	GAPI_NONE = 0,
+	GAPI_DIRECT_565,
+	GAPI_DIRECT_555,
+	GAPI_MONO,
+	GAPI_PALETTE
+} SDL_GAPIVideoMode;
+
+
+/* Hidden "this" pointer for the video functions */
+#define _THIS	SDL_VideoDevice *this
+
+/* GAPI functions definitions */
+
+typedef struct GXDisplayProperties (*tGXDisplayProperties)(void);
+typedef int (*tGXOpenDisplay)(HWND, unsigned long);
+typedef void* (*tGXBeginDraw)(void);
+typedef int (*tGXVoidFunction)(void);
+
+/* Private display data */
+
+struct GAPI_funcs {
+	tGXDisplayProperties dynamicGXGetDisplayProperties;
+	tGXOpenDisplay	dynamicGXOpenDisplay;
+	tGXVoidFunction	dynamicGXCloseDisplay;
+	tGXBeginDraw	dynamicGXBeginDraw;
+	tGXVoidFunction	dynamicGXEndDraw;
+	tGXVoidFunction	dynamicGXSuspend;
+	tGXVoidFunction	dynamicGXResume;
+};
+
+struct GAPI_properties {
+	unsigned char invert;
+	int colorscale;
+	int dstPixelstep;
+	int dstLinestep;
+	int startOffset;
+	SDL_GAPIVideoMode videoMode;
+};
+
+#define MAX_CLR         0x100
+
+struct palette_properties {
+	unsigned char *palRed;
+	unsigned char *palGreen;
+	unsigned char *palBlue;
+	unsigned short *pal;
+};
+
+
+struct SDL_PrivateVideoData {
+	/* --- <Hack> --- begin with DIB private structure to allow DIB events code sharing */
+	HBITMAP screen_bmp;
+    HPALETTE screen_pal;
+	void *work_pixels; /* if the display needs to be rotated, memory allocated by the API */
+	void *rotation_pixels; /* if the display needs to be rotated, memory allocated by the code */
+	SDL_RotateAttr rotation;
+	char ozoneHack; /* force stylus translation if running without Hi Res flag */
+
+#define NUM_MODELISTS	4		/* 8, 16, 24, and 32 bits-per-pixel */
+    int SDL_nummodes[NUM_MODELISTS];
+    SDL_Rect **SDL_modelist[NUM_MODELISTS];
+
+	/* --- </Hack> --- */
+
+    int w, h;
+    void *gapiBuffer;
+	HPALETTE screenPal;
+	struct GAPI_funcs gapiFuncs;
+	struct GAPI_properties gapiProperties;
+	struct GXDisplayProperties displayProps;
+	int srcLinestep;
+	int srcPixelstep;
+
+	int padWidth;
+	int padHeight;
+
+	unsigned short *convertPalette;
+};
+
+#define gapiBuffer (this->hidden->gapiBuffer)
+#define mainSurfaceWidth (this->hidden->w)
+#define mainSurfaceHeight (this->hidden->h)
+#define rotation (this->hidden->rotation)
+#define ozoneHack (this->hidden->ozoneHack)
+#define displayProperties (this->hidden->displayProps)
+#define screenPal (this->hidden->screenPal)
+#define GXGetDisplayProperties (this->hidden->gapiFuncs.dynamicGXGetDisplayProperties)
+#define GXOpenDisplay (this->hidden->gapiFuncs.dynamicGXOpenDisplay)
+#define GXCloseDisplay (this->hidden->gapiFuncs.dynamicGXCloseDisplay)
+#define GXBeginDraw (this->hidden->gapiFuncs.dynamicGXBeginDraw)
+#define GXEndDraw (this->hidden->gapiFuncs.dynamicGXEndDraw)
+#define GXSuspend (this->hidden->gapiFuncs.dynamicGXSuspend)
+#define GXResume (this->hidden->gapiFuncs.dynamicGXResume)
+#define invert (this->hidden->gapiProperties.invert)
+#define colorscale (this->hidden->gapiProperties.colorscale)
+#define videoMode (this->hidden->gapiProperties.videoMode)
+#define srcPixelstep (this->hidden->srcPixelstep)
+#define srcLinestep (this->hidden->srcLinestep)
+#define dstPixelstep (this->hidden->gapiProperties.dstPixelstep)
+#define dstLinestep (this->hidden->gapiProperties.dstLinestep)
+#define startOffset (this->hidden->gapiProperties.startOffset)
+#define padWidth (this->hidden->padWidth)
+#define padHeight (this->hidden->padHeight)
+#define convertPalette (this->hidden->convertPalette)
+
+#endif /* _SDL_gapivideo_h */
diff -Nru /tmp/SDL-1.2.6/src/video/wingapi/SDL_gapivideo_wingapi2005.c SDL-1.2.6/src/video/wingapi/SDL_gapivideo_wingapi2005.c
--- /tmp/SDL-1.2.6/src/video/wingapi/SDL_gapivideo_wingapi2005.c	1970-01-01 02:00:00.000000000 +0200
+++ SDL-1.2.6/src/video/wingapi/SDL_gapivideo_wingapi2005.c	2005-10-29 22:29:54.000000000 +0300
@@ -0,0 +1,1008 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  Sam Lantinga
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public
+    License along with this library; if not, write to the Free
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+    Sam Lantinga
+    slouken@libsdl.org
+*/
+
+#ifdef SAVE_RCSID
+static char rcsid =
+ "@(#) $Id: SDL_gapivideo.c,v 1.5 2004/02/29 21:54:11 lemure Exp $";
+#endif
+
+/* Dummy SDL video driver implementation; this is just enough to make an
+ *  SDL-based application THINK it's got a working video driver, for
+ *  applications that call SDL_Init(SDL_INIT_VIDEO) when they don't need it,
+ *  and also for use as a collection of stubs when porting SDL to a new
+ *  platform for which you haven't yet written a valid video driver.
+ *
+ * This is also a great way to determine bottlenecks: if you think that SDL
+ *  is a performance problem for a given platform, enable this driver, and
+ *  then see if your application runs faster without video overhead.
+ *
+ * Initial work by Ryan C. Gordon (icculus@linuxgames.com). A good portion
+ *  of this was cut-and-pasted from Stephane Peter's work in the AAlib
+ *  SDL video driver.  Renamed to "DUMMY" by Sam Lantinga.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <malloc.h>
+#include <windows.h>
+
+/* Not yet in the mingw32 cross-compile headers */
+#ifndef CDS_FULLSCREEN
+#define CDS_FULLSCREEN	4
+#endif
+
+#ifndef WS_THICKFRAME
+#define WS_THICKFRAME 0
+#endif
+
+#include "SDL.h"
+#include "SDL_mutex.h"
+#include "SDL_syswm.h"
+#include "SDL_sysvideo.h"
+#include "SDL_sysevents.h"
+#include "SDL_events_c.h"
+#include "SDL_pixels_c.h"
+#include "SDL_syswm_c.h"
+#include "SDL_sysmouse_c.h"
+#include "SDL_dibevents_c.h"
+#include "SDL_gapivideo.h"
+
+//#if defined(WIN32_PLATFORM_PSPC)
+//#include <aygshell.h>                      // Add Pocket PC includes
+//#pragma comment( lib, "aygshell" )         // Link Pocket PC library
+//#endif
+
+#ifdef _WIN32_WCE
+extern void DIB_ShowTaskBar(BOOL taskBarShown);
+#endif
+
+
+/* Initialization/Query functions */
+static int GAPI_VideoInit(_THIS, SDL_PixelFormat *vformat);
+static SDL_Rect **GAPI_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
+static SDL_Surface *GAPI_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
+static int GAPI_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
+static void GAPI_VideoQuit(_THIS);
+
+
+/* Hardware surface functions */
+static int GAPI_AllocHWSurface(_THIS, SDL_Surface *surface);
+static int GAPI_LockHWSurface(_THIS, SDL_Surface *surface);
+static void GAPI_UnlockHWSurface(_THIS, SDL_Surface *surface);
+static void GAPI_FreeHWSurface(_THIS, SDL_Surface *surface);
+
+/* Windows message handling functions, will not be processed */
+static void GAPI_RealizePalette(_THIS);
+static void GAPI_PaletteChanged(_THIS, HWND window);
+static void GAPI_WinPAINT(_THIS, HDC hdc);
+
+static void GAPI_UpdateRects(_THIS, int numrects, SDL_Rect *rects); 
+/*static void GAPI_UpdateRectsMono(_THIS, int numrects, SDL_Rect *rects);*/
+
+static int GAPI_Available(void);
+static SDL_VideoDevice *GAPI_CreateDevice(int devindex);
+
+void GAPI_GrabHardwareKeys(BOOL grab);
+
+VideoBootStrap WINGAPI_bootstrap = {
+	"wingapi", "WinCE GAPI",
+	GAPI_Available, GAPI_CreateDevice
+};
+
+/* 2003 SE GAPI emulation */
+
+#define GETRAWFRAMEBUFFER   0x00020001
+
+#define FORMAT_565 1
+#define FORMAT_555 2
+#define FORMAT_OTHER 3
+
+static void* _OzoneFrameBuffer = NULL;
+static struct GXDisplayProperties _OzoneDisplayProperties;
+static char _OzoneAvailable = 0;
+
+typedef struct _RawFrameBufferInfo
+{
+   WORD wFormat;
+   WORD wBPP;
+   VOID *pFramePointer;
+   int  cxStride;
+   int  cyStride;
+   int  cxPixels;
+   int  cyPixels;
+} RawFrameBufferInfo;
+
+
+struct GXDisplayProperties Ozone_GetDisplayProperties(void) {
+	return _OzoneDisplayProperties;
+}
+
+int Ozone_OpenDisplay(HWND window, unsigned long flag) {
+	return 1;
+}
+
+int Ozone_CloseDisplay(void) {
+	return 1;
+}
+
+void* Ozone_BeginDraw(void) {
+	return _OzoneFrameBuffer;
+}
+
+int Ozone_EndDraw(void) {
+	return 1;
+}
+
+int Ozone_Suspend(void) {
+	return 1;
+}
+
+int Ozone_Resume(void) {
+	return 1;
+}
+
+/*
+void debugLog(char *txt) {
+	FILE *logFile;
+	logFile = fopen("\\SDL_log.txt", "a");
+	fprintf(logFile, "%s\n", txt);
+	fclose(logFile);
+}
+
+
+void debugLogInt(char *txt, int x) {
+	FILE *logFile;
+	logFile = fopen("\\SDL_log.txt", "a");
+	fprintf(logFile, "%s %d\n", txt, x);
+	fclose(logFile);
+}
+*/
+
+static HINSTANCE checkOzone(tGXDisplayProperties *gxGetDisplayProperties, tGXOpenDisplay *gxOpenDisplay,
+					  tGXVoidFunction *gxCloseDisplay, tGXBeginDraw *gxBeginDraw, 
+					  tGXVoidFunction *gxEndDraw, tGXVoidFunction *gxSuspend, tGXVoidFunction *gxResume) {
+#ifdef ARM
+
+	int result;
+	RawFrameBufferInfo frameBufferInfo;
+	HDC hdc = GetDC(NULL);
+	result = ExtEscape(hdc, GETRAWFRAMEBUFFER, 0, NULL, sizeof(RawFrameBufferInfo), (char *)&frameBufferInfo);
+	ReleaseDC(NULL, hdc);
+	if (result < 0)
+		return NULL;
+	OutputDebugString(TEXT("Running on Ozone\r\n"));
+
+	//debugLog("Running on Ozone");
+
+	_OzoneAvailable = 1;
+
+	// Initializing global parameters
+	_OzoneFrameBuffer = frameBufferInfo.pFramePointer;
+	_OzoneDisplayProperties.cBPP = frameBufferInfo.wBPP;
+	_OzoneDisplayProperties.cbxPitch = frameBufferInfo.cxStride;
+	_OzoneDisplayProperties.cbyPitch = frameBufferInfo.cyStride;
+	_OzoneDisplayProperties.cxWidth = frameBufferInfo.cxPixels;
+	_OzoneDisplayProperties.cyHeight = frameBufferInfo.cyPixels;
+
+
+	//debugLogInt("Ozone width" ,_OzoneDisplayProperties.cxWidth);
+	//debugLogInt("Ozone height" ,_OzoneDisplayProperties.cyHeight);
+
+	if (frameBufferInfo.wFormat == FORMAT_565)
+		_OzoneDisplayProperties.ffFormat = kfDirect565;
+	else
+	if (frameBufferInfo.wFormat == FORMAT_555)
+		_OzoneDisplayProperties.ffFormat = kfDirect555;
+	else {
+		OutputDebugString(TEXT("Ozone unknown screen format"));
+		return NULL;
+	}
+
+	if (gxGetDisplayProperties)
+		*gxGetDisplayProperties = Ozone_GetDisplayProperties;
+	if (gxOpenDisplay)
+		*gxOpenDisplay = Ozone_OpenDisplay;
+	if (gxCloseDisplay)
+		*gxCloseDisplay = Ozone_CloseDisplay;
+	if (gxBeginDraw)
+		*gxBeginDraw = Ozone_BeginDraw;
+	if (gxEndDraw)
+		*gxEndDraw = Ozone_EndDraw;
+	if (gxSuspend)
+		*gxSuspend = Ozone_Suspend;
+	if (gxResume)
+		*gxResume = Ozone_Resume;
+
+	return (HINSTANCE)1;
+
+#else
+
+	return NULL;
+
+#endif
+}
+
+int getScreenWidth() {
+	return (_OzoneFrameBuffer ? _OzoneDisplayProperties.cxWidth : GetSystemMetrics(SM_CXSCREEN));
+}
+
+int getScreenHeight() {
+	return (_OzoneFrameBuffer ? _OzoneDisplayProperties.cyHeight : GetSystemMetrics(SM_CYSCREEN));
+}
+
+
+/* Check GAPI library */
+
+#define IMPORT(Handle,Variable,Type,Function, Store) \
+        Variable = GetProcAddress(Handle, TEXT(Function)); \
+		if (!Variable) { \
+			FreeLibrary(Handle); \
+			return NULL; \
+		} \
+		if (Store) \
+			*Store = (Type)Variable;
+
+static HINSTANCE checkGAPI(tGXDisplayProperties *gxGetDisplayProperties, tGXOpenDisplay *gxOpenDisplay,
+					  tGXVoidFunction *gxCloseDisplay, tGXBeginDraw *gxBeginDraw, 
+					  tGXVoidFunction *gxEndDraw, tGXVoidFunction *gxSuspend, tGXVoidFunction *gxResume,
+					  BOOL bypassOzone) {
+	HMODULE gapiLibrary;
+	FARPROC proc;
+	HINSTANCE result;
+	// FIXME paletted !
+	tGXDisplayProperties temp_gxGetDisplayProperties;
+
+	// Workaround for Windows Mobile 2003 SE
+	_OzoneFrameBuffer = NULL; // FIXME !!
+	if (!bypassOzone) {
+		//debugLog("No bypassOzone");
+		//_OzoneFrameBuffer = NULL;
+		result = checkOzone(gxGetDisplayProperties, gxOpenDisplay, gxCloseDisplay, gxBeginDraw, gxEndDraw, gxSuspend, gxResume);
+		if (result)
+			return result;
+	}
+
+	gapiLibrary = LoadLibrary(TEXT("gx.dll"));
+	if (!gapiLibrary)
+		return NULL;
+
+	IMPORT(gapiLibrary, proc, tGXDisplayProperties, "?GXGetDisplayProperties@@YA?AUGXDisplayProperties@@XZ", gxGetDisplayProperties)
+	IMPORT(gapiLibrary, proc, tGXOpenDisplay, "?GXOpenDisplay@@YAHPAUHWND__@@K@Z", gxOpenDisplay)
+	IMPORT(gapiLibrary, proc, tGXVoidFunction, "?GXCloseDisplay@@YAHXZ", gxCloseDisplay)
+	IMPORT(gapiLibrary, proc, tGXBeginDraw, "?GXBeginDraw@@YAPAXXZ", gxBeginDraw)
+	IMPORT(gapiLibrary, proc, tGXVoidFunction, "?GXEndDraw@@YAHXZ", gxEndDraw)
+	IMPORT(gapiLibrary, proc, tGXVoidFunction, "?GXSuspend@@YAHXZ", gxSuspend)
+	IMPORT(gapiLibrary, proc, tGXVoidFunction, "?GXResume@@YAHXZ", gxResume)
+	
+	// FIXME paletted ! for the moment we just bail out	
+	if (!gxGetDisplayProperties) {
+		IMPORT(gapiLibrary, proc, tGXDisplayProperties, "?GXGetDisplayProperties@@YA?AUGXDisplayProperties@@XZ", &temp_gxGetDisplayProperties)
+		if (temp_gxGetDisplayProperties().ffFormat & kfPalette) {
+			FreeLibrary(gapiLibrary);
+			return NULL;
+		}
+		FreeLibrary(gapiLibrary);		
+		gapiLibrary = (HINSTANCE)1;
+	}
+	
+	return gapiLibrary;
+}
+
+
+/* GAPI driver bootstrap functions */
+
+static int GAPI_Available(void)
+{
+	/* Check if the GAPI library is available */
+
+	if (!checkGAPI(NULL, NULL, NULL, NULL, NULL, NULL, NULL, FALSE)) {
+		OutputDebugString(TEXT("GAPI driver not available\r\n"));
+		return 0;
+	}
+	else {
+		OutputDebugString(TEXT("GAPI driver available\r\n"));
+		return 1;
+	}
+}
+
+static void GAPI_DeleteDevice(SDL_VideoDevice *device)
+{
+	if (device && device->hidden && device->hidden->gapiFuncs.dynamicGXCloseDisplay)
+		device->hidden->gapiFuncs.dynamicGXCloseDisplay();
+
+	if (device && device->hidden)	
+		free(device->hidden);
+	if (device)
+		free(device);
+
+}
+
+static SDL_VideoDevice *GAPI_CreateDevice(int devindex)
+{
+	SDL_VideoDevice *device;
+
+	/* Initialize all variables that we clean on shutdown */
+	device = (SDL_VideoDevice *)malloc(sizeof(SDL_VideoDevice));
+	if ( device ) {
+		memset(device, 0, (sizeof *device));
+		device->hidden = (struct SDL_PrivateVideoData *)
+				malloc((sizeof *device->hidden));
+	}
+	if ( (device == NULL) || (device->hidden == NULL) ) {
+		SDL_OutOfMemory();
+		if ( device ) {
+			free(device);
+		}
+		return(0);
+	}
+	memset(device->hidden, 0, (sizeof *device->hidden));
+
+	/* Set GAPI pointers */
+
+	checkGAPI(&device->hidden->gapiFuncs.dynamicGXGetDisplayProperties, 
+			  &device->hidden->gapiFuncs.dynamicGXOpenDisplay, 
+			  &device->hidden->gapiFuncs.dynamicGXCloseDisplay, 
+			  &device->hidden->gapiFuncs.dynamicGXBeginDraw, 
+			  &device->hidden->gapiFuncs.dynamicGXEndDraw, 
+			  &device->hidden->gapiFuncs.dynamicGXSuspend, 
+			  &device->hidden->gapiFuncs.dynamicGXResume, 
+			  FALSE);
+	device->hidden->displayProps = device->hidden->gapiFuncs.dynamicGXGetDisplayProperties();
+
+	/* Set the function pointers */
+
+	device->VideoInit = GAPI_VideoInit;
+	device->ListModes = GAPI_ListModes;
+	device->SetVideoMode = GAPI_SetVideoMode;
+	device->UpdateMouse = WIN_UpdateMouse;
+	device->SetColors = GAPI_SetColors;
+	device->UpdateRects = NULL;
+	device->VideoQuit = GAPI_VideoQuit;
+	device->AllocHWSurface = GAPI_AllocHWSurface;
+	device->CheckHWBlit = NULL;
+	device->FillHWRect = NULL;
+	device->SetHWColorKey = NULL;
+	device->SetHWAlpha = NULL;
+	device->LockHWSurface = GAPI_LockHWSurface;
+	device->UnlockHWSurface = GAPI_UnlockHWSurface;
+	device->FlipHWSurface = NULL;
+	device->FreeHWSurface = GAPI_FreeHWSurface;
+	device->SetCaption = WIN_SetWMCaption;
+	device->SetIcon = WIN_SetWMIcon;
+	device->IconifyWindow = WIN_IconifyWindow;
+	device->GrabInput = WIN_GrabInput;
+	device->GetWMInfo = WIN_GetWMInfo;
+	device->FreeWMCursor = WIN_FreeWMCursor;
+	device->CreateWMCursor = WIN_CreateWMCursor;
+	device->ShowWMCursor = WIN_ShowWMCursor;
+	device->WarpWMCursor = WIN_WarpWMCursor;
+	device->CheckMouseMode = WIN_CheckMouseMode;
+	device->InitOSKeymap = DIB_InitOSKeymap;
+	device->PumpEvents = DIB_PumpEvents;
+
+	device->SetColors = GAPI_SetColors;
+
+	/* Set up the windows message handling functions */
+	WIN_RealizePalette = GAPI_RealizePalette;
+	WIN_PaletteChanged = GAPI_PaletteChanged;
+	WIN_WinPAINT = GAPI_WinPAINT;
+	HandleMessage = DIB_HandleMessage;
+
+	device->free = GAPI_DeleteDevice;
+	
+	
+	/*
+	device->VideoInit = GAPI_VideoInit;
+	device->ListModes = GAPI_ListModes;
+	device->SetVideoMode = GAPI_SetVideoMode;
+	device->CreateYUVOverlay = NULL;
+	device->SetColors = DUMMY_SetColors;
+	device->UpdateRects = DUMMY_UpdateRects;
+	device->VideoQuit = DUMMY_VideoQuit;
+	device->AllocHWSurface = DUMMY_AllocHWSurface;
+	device->CheckHWBlit = NULL;
+	device->FillHWRect = NULL;
+	device->SetHWColorKey = NULL;
+	device->SetHWAlpha = NULL;
+	device->LockHWSurface = DUMMY_LockHWSurface;
+	device->UnlockHWSurface = DUMMY_UnlockHWSurface;
+	device->FlipHWSurface = NULL;
+	device->FreeHWSurface = DUMMY_FreeHWSurface;
+	device->SetCaption = NULL;
+	device->SetIcon = NULL;
+	device->IconifyWindow = NULL;
+	device->GrabInput = NULL;
+	device->GetWMInfo = NULL;
+	device->InitOSKeymap = DUMMY_InitOSKeymap;
+	device->PumpEvents = DUMMY_PumpEvents;
+
+	device->free = DUMMY_DeleteDevice;
+	*/
+
+	return device;
+}
+
+
+int GAPI_VideoInit(_THIS, SDL_PixelFormat *vformat)
+{
+
+	/* Create the window */
+	if ( DIB_CreateWindow(this) < 0 ) {
+		return(-1);
+	}
+
+	vformat->BitsPerPixel = (unsigned char)displayProperties.cBPP;	
+
+	// Get color mask
+	if (displayProperties.ffFormat & kfDirect565) {
+		vformat->BitsPerPixel = 16;
+		vformat->Rmask = 0x0000f800;
+		vformat->Gmask = 0x000007e0;
+		vformat->Bmask = 0x0000001f;
+		videoMode = GAPI_DIRECT_565;
+	}
+	else
+	if (displayProperties.ffFormat & kfDirect555) {
+		vformat->BitsPerPixel = 16;
+		vformat->Rmask = 0x00007c00;
+		vformat->Gmask = 0x000003e0;
+		vformat->Bmask = 0x0000001f;
+		videoMode = GAPI_DIRECT_555;
+	}
+	else
+	if ((displayProperties.ffFormat & kfDirect) && (displayProperties.cBPP <= 8)) {
+		// We'll perform the conversion
+		vformat->BitsPerPixel = 24;
+		vformat->Rmask = 0x00ff0000;
+		vformat->Gmask = 0x0000ff00;
+		vformat->Bmask = 0x000000ff;
+		if (displayProperties.ffFormat & kfDirectInverted)
+			invert = (1 << displayProperties.cBPP) - 1;
+		colorscale = displayProperties.cBPP < 8 ? 8 - displayProperties.cBPP : 0;
+		videoMode = GAPI_MONO;
+	}
+	else
+	if (displayProperties.ffFormat & kfPalette) {
+		videoMode = GAPI_PALETTE;
+	}
+
+	/* Set UpdateRect callback */
+	// FIXME
+	/*
+	if (videoMode != GAPI_MONO)
+		this->UpdateRects = GAPI_UpdateRects;
+	else
+		this->UpdateRects = GAPI_UpdateRectsMono;
+	*/
+
+	this->UpdateRects = GAPI_UpdateRects;
+	
+	/* We're done! */
+	return(0);
+}
+
+SDL_Rect **GAPI_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
+{
+   	 return (SDL_Rect **) -1;
+}
+
+SDL_Surface *GAPI_SetVideoMode(_THIS, SDL_Surface *current,
+				int width, int height, int bpp, Uint32 flags)
+{
+	SDL_Surface *video;
+	Uint32 Rmask, Gmask, Bmask;
+	Uint32 prev_flags;
+	DWORD style;
+	const DWORD directstyle =
+			(WS_POPUP);
+	const DWORD windowstyle = 
+			(WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX);
+	const DWORD resizestyle =
+			(WS_THICKFRAME|WS_MAXIMIZEBOX);
+	int screenWidth, screenHeight;
+	BOOL was_visible;
+	OSVERSIONINFO windowsVersion = { 0 };
+
+	ozoneHack = 0;
+	/* We negociate legacy GAPI if we want a screen that fits in QVGA */
+	/* Size check was added to work properly with 3rd party VGA tools */
+
+	/*debugLog("********************REINIT**********************");
+
+	debugLogInt("Width", width);
+	debugLogInt("Height", height);
+	debugLogInt("Advertised width", GetSystemMetrics(SM_CXSCREEN));
+	debugLogInt("Advertised height", GetSystemMetrics(SM_CYSCREEN));
+	debugLogInt("OzoneAvailable", _OzoneAvailable);
+	debugLogInt("OzoneFrameBuffer", _OzoneFrameBuffer);*/
+
+	/* Switching back to GAPI on WM 5.0 seems to create funky effects */
+
+	windowsVersion.dwOSVersionInfoSize = sizeof(LPOSVERSIONINFO);
+	GetVersionEx(&windowsVersion);
+	
+	if (windowsVersion.dwMajorVersion < 5 && _OzoneAvailable && _OzoneFrameBuffer && !(GetSystemMetrics(SM_CXSCREEN) == 480 && GetSystemMetrics(SM_CYSCREEN) == 640) && (width <= GetSystemMetrics(SM_CXSCREEN) || width <= GetSystemMetrics(SM_CYSCREEN)) &&
+						     (height <= GetSystemMetrics(SM_CXSCREEN) || height <= GetSystemMetrics(SM_CYSCREEN))) {
+			OutputDebugString(TEXT("Ozone workaround, switching back to GAPI\r\n"));
+			//debugLog("Ozone workaround, switching back to GAPI");
+			checkGAPI(&this->hidden->gapiFuncs.dynamicGXGetDisplayProperties, 
+				&this->hidden->gapiFuncs.dynamicGXOpenDisplay, 
+				&this->hidden->gapiFuncs.dynamicGXCloseDisplay, 
+				&this->hidden->gapiFuncs.dynamicGXBeginDraw, 
+				&this->hidden->gapiFuncs.dynamicGXEndDraw,  
+				&this->hidden->gapiFuncs.dynamicGXSuspend, 
+				&this->hidden->gapiFuncs.dynamicGXResume,  
+				TRUE);
+			this->hidden->displayProps = this->hidden->gapiFuncs.dynamicGXGetDisplayProperties();
+	}
+	
+	/* Otherwise we'll use the new system call */
+	if (_OzoneAvailable && !_OzoneFrameBuffer && (width > GetSystemMetrics(SM_CXSCREEN) && width > GetSystemMetrics(SM_CYSCREEN)) && 
+		                                         (height > GetSystemMetrics(SM_CXSCREEN) && height > GetSystemMetrics(SM_CYSCREEN))) {
+			OutputDebugString(TEXT("Ozone workaround, switching back to true Ozone\r\n"));
+			//debugLog("Ozone workaround, switching back to true ozone");
+			checkGAPI(&this->hidden->gapiFuncs.dynamicGXGetDisplayProperties, 
+				&this->hidden->gapiFuncs.dynamicGXOpenDisplay, 
+				&this->hidden->gapiFuncs.dynamicGXCloseDisplay, 
+				&this->hidden->gapiFuncs.dynamicGXBeginDraw, 
+				&this->hidden->gapiFuncs.dynamicGXEndDraw, 
+				&this->hidden->gapiFuncs.dynamicGXSuspend, 
+				&this->hidden->gapiFuncs.dynamicGXResume, 
+				FALSE);
+			this->hidden->displayProps = this->hidden->gapiFuncs.dynamicGXGetDisplayProperties();
+	}
+	/* Which will need a tiny input hack if the original code does not have the "Hi Res" aware ressource property set */
+	if (_OzoneFrameBuffer && (GetSystemMetrics(SM_CXSCREEN) != _OzoneDisplayProperties.cxWidth ||
+							  GetSystemMetrics(SM_CYSCREEN) != _OzoneDisplayProperties.cyHeight)) {
+				OutputDebugString(TEXT("Running true Ozone with stylus hack\r\n"));
+				//debugLog("True ozone with stylus hack");
+				ozoneHack = 1;
+	}
+
+	/* See whether or not we should center the window */
+	was_visible = IsWindowVisible(SDL_Window);
+
+	/* Recalculate bitmasks if necessary */
+	if (bpp == current->format->BitsPerPixel) {
+		video = current;
+	}
+	else {
+		switch(bpp) {
+			case 8:
+				Rmask = 0;
+				Gmask = 0;
+				Bmask = 0;
+				break;
+			case 15:				
+			case 16:
+				/* Default is 565 unless the display is specifically 555 */
+				if (displayProperties.ffFormat & kfDirect555) {
+					Rmask = 0x00007c00;
+					Gmask = 0x000003e0;
+					Bmask = 0x0000001f;
+				}
+				else {
+					Rmask = 0x0000f800;
+					Gmask = 0x000007e0;
+					Bmask = 0x0000001f;
+				}
+				break;
+			case 24:
+			case 32:
+				Rmask = 0x00ff0000;
+				Gmask = 0x0000ff00;
+				Bmask = 0x000000ff;
+				break;
+			default:
+				SDL_SetError("Unsupported Bits Per Pixel format requested");
+				return NULL;
+		}
+		video = SDL_CreateRGBSurface(SDL_SWSURFACE,
+					0, 0, bpp, Rmask, Gmask, Bmask, 0);
+		if ( video == NULL ) {
+			SDL_OutOfMemory();
+			return(NULL);
+		}
+	}
+	
+	/* Fill in part of the video surface */
+	prev_flags = video->flags;
+	//video->flags = 0;	/* Clear flags */
+	video->flags = SDL_HWPALETTE; /* Clear flags */
+	video->w = width;
+	video->h = height;
+	video->pitch = SDL_CalculatePitch(video);
+	mainSurfaceWidth = width;
+	mainSurfaceHeight = height;	
+
+//#ifdef WIN32_PLATFORM_PSPC
+	/* Hide taskbar */	
+	if ( flags & SDL_FULLSCREEN ) {
+		if ( !(prev_flags & SDL_FULLSCREEN) ) {
+			//SHFullScreen(SDL_Window, SHFS_HIDETASKBAR | SHFS_HIDESIPBUTTON | SHFS_HIDESTARTICON);
+			//ShowWindow(FindWindow(TEXT("HHTaskBar"),NULL),SW_HIDE);
+			DIB_ShowTaskBar(FALSE);
+		}
+		video->flags |= SDL_FULLSCREEN;
+	} else {
+		if ( prev_flags & SDL_FULLSCREEN ) {
+			//SHFullScreen(SDL_Window, SHFS_SHOWTASKBAR | SHFS_SHOWSIPBUTTON | SHFS_SHOWSTARTICON);
+			//ShowWindow(FindWindow(TEXT("HHTaskBar"),NULL),SW_SHOWNORMAL);
+			DIB_ShowTaskBar(TRUE);
+		}
+	}
+//#endif
+
+	/* Reset the palette and create a new one if necessary */	
+	if (screenPal != NULL) {
+		DeleteObject(screenPal);
+		screenPal = NULL;
+	}
+
+	/* See if we need to create a translation palette */
+	if (convertPalette != NULL) {
+		free(convertPalette);
+	}
+	if (bpp == 8) {
+		OutputDebugString(TEXT("creating palette\r\n"));
+		convertPalette = (unsigned short*)malloc(256 * sizeof(unsigned short));
+	}
+
+	if (displayProperties.ffFormat & kfPalette) {
+		/* Will only be able to support 256 colors in this mode */
+		// FIXME
+		//screenPal = GAPI_CreatePalette();
+	}
+
+	/* Set Window style */
+	style = GetWindowLong(SDL_Window, GWL_STYLE);
+	if ( (video->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
+		style &= ~windowstyle;
+		style |= directstyle;
+	} else {
+		if ( flags & SDL_NOFRAME ) {
+			style &= ~windowstyle;
+			style |= directstyle;
+			video->flags |= SDL_NOFRAME;
+		} else {
+			style &= ~directstyle;
+			style |= windowstyle;
+			if ( flags & SDL_RESIZABLE ) {
+				style |= resizestyle;
+				video->flags |= SDL_RESIZABLE;
+			}
+		}
+#if WS_MAXIMIZE
+		if (IsZoomed(SDL_Window)) style |= WS_MAXIMIZE;
+#endif
+	}
+
+	if (!SDL_windowid)
+		SetWindowLong(SDL_Window, GWL_STYLE, style);
+
+	/* Allocate bitmap */
+	if (gapiBuffer) {
+		free(gapiBuffer);
+		gapiBuffer = NULL;
+	}
+	gapiBuffer = malloc(video->h * video->pitch);
+	video->pixels = gapiBuffer;
+
+	/* See if we will rotate */
+	rotation = SDL_ROTATE_NONE;
+	screenWidth = getScreenWidth();
+	screenHeight = getScreenHeight();
+	//debugLog("Rotate check");
+	if ((flags & SDL_FULLSCREEN) && 
+		(width > screenWidth && width <= screenHeight)
+		) 
+	{
+			//debugLog("Need to rotate");
+			rotation = SDL_ROTATE_LEFT;
+	}
+	/* Compute the different drawing properties */
+	switch(rotation) {
+		case SDL_ROTATE_NONE:
+			dstPixelstep = displayProperties.cbxPitch;
+			dstLinestep = displayProperties.cbyPitch;
+			startOffset = 0;
+			break;
+		case SDL_ROTATE_LEFT:
+			dstPixelstep = -displayProperties.cbyPitch;
+			dstLinestep = displayProperties.cbxPitch;
+			startOffset = displayProperties.cbyPitch * (displayProperties.cyHeight - 1);
+			break;
+		case SDL_ROTATE_RIGHT:
+			dstPixelstep = displayProperties.cbyPitch;
+			dstLinestep = -displayProperties.cbxPitch;
+			startOffset = displayProperties.cbxPitch * (displayProperties.cxWidth - 1);
+			break;
+	}
+	/* Compute padding */
+	padWidth = 0;
+	padHeight = 0;
+	/*
+	if (rotation == SDL_ROTATE_NONE) {
+		if (getScreenWidth() > width)
+			padWidth = (getScreenWidth() - width) / 2;
+		if (getScreenHeight() > height)
+			padHeight = (getScreenHeight() - height) / 2;
+	}
+	else {
+		if (getScreenWidth() > height)
+			padWidth = (getScreenWidth() - height) / 2;
+		if (getScreenHeight() > width)
+			padHeight = (getScreenHeight() - width) / 2;
+	}
+	*/
+	srcLinestep = video->pitch;
+	srcPixelstep = (bpp == 15 ? 2 : bpp / 8);
+	
+	MoveWindow(SDL_Window, 0, 0, getScreenWidth(), getScreenHeight(), FALSE);
+	ShowWindow(SDL_Window, SW_SHOW);
+
+	/* Resize the window */
+	//if ( SDL_windowid == NULL ) {
+	if (0) {
+		HWND top;
+		UINT swp_flags;
+		RECT bounds;
+		int x,y;
+
+		SDL_resizing = 1;
+		bounds.left = 0;
+		bounds.top = 0;
+		bounds.right = video->w;
+		bounds.bottom = video->h;
+		AdjustWindowRectEx(&bounds, GetWindowLong(SDL_Window, GWL_STYLE), FALSE, 0);
+		width = bounds.right-bounds.left;
+		height = bounds.bottom-bounds.top;
+		x = (getScreenWidth()-width)/2;
+		y = (getScreenHeight()-height)/2;
+		if ( y < 0 ) { /* Cover up title bar for more client area */
+			y -= GetSystemMetrics(SM_CYCAPTION)/2;
+		}
+		swp_flags = (SWP_FRAMECHANGED | SWP_SHOWWINDOW);
+		if ( was_visible && !(flags & SDL_FULLSCREEN) ) {
+			swp_flags |= SWP_NOMOVE;
+		}
+		if ( flags & SDL_FULLSCREEN ) {
+			top = HWND_TOPMOST;
+		} else {
+			top = HWND_NOTOPMOST;
+		}
+
+		if (flags & SDL_FULLSCREEN) {
+			SetWindowPos(SDL_Window, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
+			ShowWindow(SDL_Window, SW_SHOW);
+		}
+		else
+			SetWindowPos(SDL_Window, top, x, y, width, height, swp_flags);
+		
+		SDL_resizing = 0;
+		SetForegroundWindow(SDL_Window);
+	}
+	
+	/* Open GAPI display */
+	GXOpenDisplay(SDL_Window, (flags & SDL_FULLSCREEN ? GX_FULLSCREEN : 0));
+
+	/* Grab hardware keys if necessary */
+	if (flags & SDL_FULLSCREEN)
+		GAPI_GrabHardwareKeys(TRUE);
+
+	/* Blank screen */
+	memset(GXBeginDraw(), 0, getScreenWidth() * getScreenHeight() * 2);
+	GXEndDraw();
+
+	/* We're done */
+	return(video);
+}
+
+/* We don't actually allow hardware surfaces other than the main one */
+static int GAPI_AllocHWSurface(_THIS, SDL_Surface *surface)
+{
+	return(-1);
+}
+static void GAPI_FreeHWSurface(_THIS, SDL_Surface *surface)
+{
+	return;
+}
+
+/* We need to wait for vertical retrace on page flipped displays */
+static int GAPI_LockHWSurface(_THIS, SDL_Surface *surface)
+{
+	return(0);
+}
+
+static void GAPI_UnlockHWSurface(_THIS, SDL_Surface *surface)
+{
+	return;
+}
+
+static void updateLine(_THIS, unsigned char *srcPointer, unsigned char *destPointer, int width) {
+	// FIXME, we assume everything is in the correct format, either 16 bits 565 or 555, or 8 bits
+	int i;
+	for (i=0; i<width; i++) {
+		if (!convertPalette) {
+			*(unsigned short*)destPointer = *(unsigned short*)srcPointer;
+		}
+		else {
+			*(unsigned short*)destPointer = convertPalette[*srcPointer];
+		}
+			
+		destPointer += dstPixelstep;
+		srcPointer += srcPixelstep; 
+	}
+}
+
+static void GAPI_UpdateRects(_THIS, int numrects, SDL_Rect *rects)
+{
+	int i;
+	unsigned char *screenBuffer;
+
+	screenBuffer = GXBeginDraw();
+
+	for (i=0; i<numrects; i++) {
+		unsigned char *destPointer = screenBuffer + startOffset + ((rects[i].x + padWidth) * dstPixelstep) + ((rects[i].y + padHeight) * dstLinestep);
+		unsigned char *srcPointer = (unsigned char*)gapiBuffer + (rects[i].x * srcPixelstep) + (rects[i].y * srcLinestep);
+		int height = rects[i].h;
+
+		while (height) {
+			updateLine(this, srcPointer, destPointer, rects[i].w);
+			destPointer += dstLinestep;
+			srcPointer += srcLinestep;
+			height--;
+		}
+	}
+
+	GXEndDraw();
+}
+
+/*
+#define ADVANCE_PARTIAL(address, step) \
+	bitshift += displayProperties.cBPP;             \
+	if(bitshift >= 8)                  \
+	{                                  \
+		bitshift = 0;                  \
+		bitmask = (1<<displayProperties.cBPP)-1;    \
+		address += step;               \
+	}                                  \
+	else                               \
+		bitmask <<= displayProperties.cBPP;
+
+#define ADVANCE_REV_PARTIAL(address, step)        \
+	bitshift -= gxdp.cBPP;                        \
+	if(bitshift < 0)                              \
+	{                                             \
+		bitshift = 8-displayProperties.cBPP;                   \
+		bitmask = ((1<<displayProperties.cBPP)-1)<<bitshift;   \
+		address += step;                          \
+	}                                             \
+	else                                          \
+		bitmask >>= displayProperties.cBPP;
+
+
+static void GAPI_UpdateRectsMono(_THIS, int numrects, SDL_Rect *rects)
+{
+	int i;
+	unsigned char *screenBuffer;
+
+	screenBuffer = GXBeginDraw();
+
+	for (i=0; i<numrects; i++) {
+		unsigned char *destPointer = screenBuffer + startOffset + (rects[i].x * dstPixelstep) + (rects[i].y * dstLinestep);
+		unsigned char *srcPointer = (unsigned char*)gapiBuffer + (rects[i].x * srcPixelstep) + (rects[i].y * srcLinestep);
+		unsigned char bitmask;
+		int bitshift;
+
+		int height = rects[i].h;
+		while (height) {
+			updateLine(_THIS, srcPointer, destPointer, rects[i].w);
+			destPointer += dstLinestep;
+			srcPointer += srcLinestep;
+			height--;
+		}
+	}
+
+	GXEndDraw();
+}
+*/
+
+/* -------------------------------------------------------------------------------- */
+// Global fixme for paletted mode !
+
+#define COLORCONV565(r,g,b) (((r&0xf8)<<(11-3))|((g&0xfc)<<(5-2))|((b&0xf8)>>3))
+
+#define COLORCONV555(r,g,b) (((r&0xf8)<<(10-3))|((g&0xf8)<<(5-2))|((b&0xf8)>>3))
+
+int GAPI_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
+{
+	int i;
+	/* Convert colors to appropriate 565 or 555 mapping */
+	for (i=0; i<ncolors; i++) 
+		convertPalette[firstcolor + i] = (videoMode == GAPI_DIRECT_565 ? 
+			COLORCONV565(colors[i].r, colors[i].g, colors[i].b) :
+			COLORCONV555(colors[i].r, colors[i].g, colors[i].b));
+	return(1);
+}
+
+static void GAPI_RealizePalette(_THIS)
+{
+	OutputDebugString(TEXT("GAPI_RealizePalette NOT IMPLEMENTED !\r\n"));
+}
+
+static void GAPI_PaletteChanged(_THIS, HWND window)
+{
+	OutputDebugString(TEXT("GAPI_PaletteChanged NOT IMPLEMENTED !\r\n"));
+}
+
+/* Exported for the windows message loop only */
+static void GAPI_WinPAINT(_THIS, HDC hdc)
+{
+	OutputDebugString(TEXT("GAPI_WinPAINT NOT IMPLEMENTED !\r\n"));
+}
+
+
+/* Note:  If we are terminated, this could be called in the middle of
+   another SDL video routine -- notably UpdateRects.
+*/
+void GAPI_VideoQuit(_THIS)
+{
+	/* Destroy the window and everything associated with it */
+	if ( SDL_Window ) {
+		/* Delete the screen bitmap (also frees screen->pixels) */
+		if ( this->screen ) {
+//#ifdef WIN32_PLATFORM_PSPC
+			if ( this->screen->flags & SDL_FULLSCREEN ) {
+				/* Unhide taskbar, etc. */
+				//SHFullScreen(SDL_Window, SHFS_SHOWTASKBAR | SHFS_SHOWSIPBUTTON | SHFS_SHOWSTARTICON);
+				//ShowWindow(FindWindow(TEXT("HHTaskBar"),NULL),SW_SHOWNORMAL);
+				DIB_ShowTaskBar(TRUE);
+				GAPI_GrabHardwareKeys(FALSE);
+			}
+//#endif
+
+			if (this->screen->pixels != NULL)
+			{
+				free(this->screen->pixels);
+				this->screen->pixels = NULL;
+			}
+
+			if (GXCloseDisplay)
+				GXCloseDisplay();
+		}
+	}
+}
+
+void GAPI_GrabHardwareKeys(BOOL grab) {
+	HINSTANCE GAPI_handle;
+	tGXVoidFunction GAPIActionInput;
+
+	GAPI_handle = LoadLibrary(TEXT("gx.dll"));
+	if (!GAPI_handle)
+		return;
+	GAPIActionInput = (tGXVoidFunction)GetProcAddress(GAPI_handle, (grab ? TEXT("?GXOpenInput@@YAHXZ") : TEXT("?GXCloseInput@@YAHXZ")));
+	if (GAPIActionInput) {
+		GAPIActionInput();
+	}
+	FreeLibrary(GAPI_handle);
+}