Updated WinCE support by Dmitry (with some tweaks)
authorSam Lantinga <slouken@libsdl.org>
Sat, 04 Mar 2006 08:24:35 +0000
changeset 1465 8dfa9a6d69a5
parent 1464 af30090c0330
child 1466 3c45c578d480
Updated WinCE support by Dmitry (with some tweaks) Converted the disk audio driver to SDL_RWops for portability
VisualC.zip
VisualCE.zip
include/SDL_config_win32.h
include/SDL_thread.h
src/SDL.c
src/audio/SDL_wave.c
src/audio/disk/SDL_diskaudio.c
src/audio/disk/SDL_diskaudio.h
src/file/SDL_rwops.c
src/main/win32/SDL_win32_main.c
src/stdlib/SDL_malloc.c
src/video/gapi/SDL_gapivideo.c
src/video/gapi/SDL_gapivideo.h
src/video/wincommon/SDL_lowvideo.h
src/video/wincommon/SDL_sysevents.c
src/video/wincommon/SDL_syswm.c
src/video/windib/SDL_dibvideo.c
src/video/windib/SDL_dibvideo.h
test/testalpha.c
Binary file VisualC.zip has changed
Binary file VisualCE.zip has changed
--- a/include/SDL_config_win32.h	Sat Mar 04 05:13:03 2006 +0000
+++ b/include/SDL_config_win32.h	Sat Mar 04 08:24:35 2006 +0000
@@ -26,18 +26,34 @@
 /* This is a set of defines to configure the SDL features */
 
 #ifdef _MSC_VER
-typedef __int8			int8_t;
+typedef signed __int8		int8_t;
 typedef unsigned __int8		uint8_t;
-typedef __int16			int16_t;
+typedef signed __int16		int16_t;
 typedef unsigned __int16	uint16_t;
-typedef __int32			int32_t;
+typedef signed __int32		int32_t;
 typedef unsigned __int32	uint32_t;
-typedef __int64			int64_t;
+typedef signed __int64		int64_t;
 typedef unsigned __int64	uint64_t;
-#if _MSC_VER <= 1200
+#ifndef _UINTPTR_T_DEFINED
+#ifdef  _WIN64
+typedef unsigned __int64    uintptr_t;
+#else
+typedef unsigned int   uintptr_t;
+#endif
+#define _UINTPTR_T_DEFINED
+#endif
+#else
+typedef signed char int8_t;
+typedef unsigned char uint8_t;
+typedef signed short int16_t;
+typedef unsigned short uint16_t;
+typedef signed int int32_t;
+typedef unsigned int uint32_t;
+typedef signed long long int64_t;
+typedef unsigned long long uint64_t;
+typedef unsigned int size_t;
 typedef unsigned long uintptr_t;
-#endif
-#endif
+#endif /* _MSC_VER */
 #define SDL_HAS_64BIT_TYPE	1
 
 /* Useful headers */
@@ -79,8 +95,10 @@
 #define SDL_VIDEO_DRIVER_WINDIB	1
 
 /* Enable OpenGL support */
+#ifndef _WIN32_WCE
 #define SDL_VIDEO_OPENGL	1
 #define SDL_VIDEO_OPENGL_WGL	1
+#endif
 
 /* Enable assembly routines */
 #define SDL_ASSEMBLY_ROUTINES	1
--- a/include/SDL_thread.h	Sat Mar 04 05:13:03 2006 +0000
+++ b/include/SDL_thread.h	Sat Mar 04 08:24:35 2006 +0000
@@ -59,7 +59,9 @@
    So, in short:
    Always use the _beginthread() and _endthread() of the calling runtime library!
 */
+#ifndef _WIN32_WCE
 #include <process.h> // This has _beginthread() and _endthread() defined!
+#endif
 #ifdef __EMX__
 #include <stdlib.h> // This has _beginthread() and _endthread() defined, if -Zmt flag is used!
 #endif
@@ -68,9 +70,6 @@
 typedef int (*pfnSDL_CurrentBeginThread)(void (*func)(void *), void *, unsigned, void *arg); 
 typedef void (*pfnSDL_CurrentEndThread)(void);
 #else
-#ifdef __GNUC__
-#include <stdint.h>
-#endif
 typedef uintptr_t (__cdecl *pfnSDL_CurrentBeginThread) (void *, unsigned,
         unsigned (__stdcall *func)(void *), void *arg, 
         unsigned, unsigned *threadID);
--- a/src/SDL.c	Sat Mar 04 05:13:03 2006 +0000
+++ b/src/SDL.c	Sat Mar 04 08:24:35 2006 +0000
@@ -325,8 +325,8 @@
 
 #elif defined(__WIN32__)
 
-#if !defined(HAVE_LIBC) || defined(_WIN32_WCE) || (defined(__WATCOMC__) && defined(BUILD_DLL))
-/* Need to include DllMain() on Windows CE and Watcom C for some reason.. */
+#if !defined(HAVE_LIBC) || (defined(__WATCOMC__) && defined(BUILD_DLL))
+/* Need to include DllMain() on Watcom C for some reason.. */
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
 
@@ -343,6 +343,6 @@
 	}
 	return TRUE;
 }
-#endif /* _WIN32_WCE and building DLL with Watcom C */
+#endif /* building DLL with Watcom C */
 
 #endif /* OS/2 elif __WIN32__ */
--- a/src/audio/SDL_wave.c	Sat Mar 04 05:13:03 2006 +0000
+++ b/src/audio/SDL_wave.c	Sat Mar 04 08:24:35 2006 +0000
@@ -550,12 +550,13 @@
 	if ( format != NULL ) {
 		SDL_free(format);
 	}
-	if ( freesrc && src ) {
-		SDL_RWclose(src);
-	}
-	else {
-		// seek to the end of the file (given by the RIFF chunk)
-		SDL_RWseek(src, wavelen - chunk.length - headerDiff, RW_SEEK_CUR);
+	if ( src ) {
+		if ( freesrc ) {
+			SDL_RWclose(src);
+		} else {
+			// seek to the end of the file (given by the RIFF chunk)
+			SDL_RWseek(src, wavelen - chunk.length - headerDiff, RW_SEEK_CUR);
+		}
 	}
 	if ( was_error ) {
 		spec = NULL;
--- a/src/audio/disk/SDL_diskaudio.c	Sat Mar 04 05:13:03 2006 +0000
+++ b/src/audio/disk/SDL_diskaudio.c	Sat Mar 04 08:24:35 2006 +0000
@@ -26,16 +26,11 @@
 
 /* Output raw audio data to a file. */
 
+#if HAVE_STDIO_H
 #include <stdio.h>
-#include <string.h>	/* For strerror() */
-#include <errno.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
+#endif
 
-
+#include "SDL_rwops.h"
 #include "SDL_timer.h"
 #include "SDL_audio.h"
 #include "../SDL_audiomem.h"
@@ -61,44 +56,18 @@
 
 static const char *DISKAUD_GetOutputFilename(void)
 {
-    const char *envr = SDL_getenv(DISKENVR_OUTFILE);
-    return((envr != NULL) ? envr : DISKDEFAULT_OUTFILE);
+	const char *envr = SDL_getenv(DISKENVR_OUTFILE);
+	return((envr != NULL) ? envr : DISKDEFAULT_OUTFILE);
 }
 
 /* Audio driver bootstrap functions */
 static int DISKAUD_Available(void)
 {
-#if 0
-    int fd;
-	int available;
-    int exists = 0;
-    struct stat statbuf;
-    const char *fname = DISKAUD_GetOutputFilename();
 	const char *envr = SDL_getenv("SDL_AUDIODRIVER");
-	available = 0;
-
-	if ((envr) && (SDL_strcmp(envr, DISKAUD_DRIVER_NAME) == 0)) {
-		if (stat(fname, &statbuf) == 0)
-			exists = 1;
-
-		fd = open(fname, O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR);
-		if ( fd != -1 ) {
-			available = 1;
-			close(fd);
-			if (!exists) {
-				unlink(fname);
-			}
-		}
-	}
-	return(available);
-#else
-	const char *envr = SDL_getenv("SDL_AUDIODRIVER");
-	if ((envr) && (SDL_strcmp(envr, DISKAUD_DRIVER_NAME) == 0)) {
+	if (envr && (SDL_strcmp(envr, DISKAUD_DRIVER_NAME) == 0)) {
 		return(1);
 	}
-
 	return(0);
-#endif
 }
 
 static void DISKAUD_DeleteDevice(SDL_AudioDevice *device)
@@ -110,7 +79,7 @@
 static SDL_AudioDevice *DISKAUD_CreateDevice(int devindex)
 {
 	SDL_AudioDevice *this;
-    const char *envr;
+	const char *envr;
 
 	/* Initialize all variables that we clean on shutdown */
 	this = (SDL_AudioDevice *)SDL_malloc(sizeof(SDL_AudioDevice));
@@ -128,8 +97,8 @@
 	}
 	SDL_memset(this->hidden, 0, (sizeof *this->hidden));
 
-    envr = SDL_getenv(DISKENVR_WRITEDELAY);
-    this->hidden->write_delay = (envr) ? SDL_atoi(envr) : DISKDEFAULT_WRITEDELAY;
+	envr = SDL_getenv(DISKENVR_WRITEDELAY);
+	this->hidden->write_delay = (envr) ? SDL_atoi(envr) : DISKDEFAULT_WRITEDELAY;
 
 	/* Set the function pointers */
 	this->OpenAudio = DISKAUD_OpenAudio;
@@ -151,26 +120,20 @@
 /* This function waits until it is possible to write a full sound buffer */
 static void DISKAUD_WaitAudio(_THIS)
 {
-    SDL_Delay(this->hidden->write_delay);
+	SDL_Delay(this->hidden->write_delay);
 }
 
 static void DISKAUD_PlayAudio(_THIS)
 {
 	int written;
 
-	/* Write the audio data, checking for EAGAIN on broken audio drivers */
-	do {
-		written = write(this->hidden->audio_fd,
-                        this->hidden->mixbuf,
+	/* Write the audio data */
+	written = SDL_RWwrite(this->hidden->output,
+                        this->hidden->mixbuf, 1,
                         this->hidden->mixlen);
-		if ( (written < 0) && ((errno == 0) || (errno == EAGAIN)) ) {
-			SDL_Delay(1);	/* Let a little CPU time go by */
-		}
-	} while ( (written < 0) && 
-	          ((errno == 0) || (errno == EAGAIN) || (errno == EINTR)) );
 
 	/* If we couldn't write, assume fatal error for now */
-	if ( written < 0 ) {
+	if ( written != this->hidden->mixlen ) {
 		this->enabled = 0;
 	}
 #ifdef DEBUG_AUDIO
@@ -189,25 +152,26 @@
 		SDL_FreeAudioMem(this->hidden->mixbuf);
 		this->hidden->mixbuf = NULL;
 	}
-	if ( this->hidden->audio_fd >= 0 ) {
-		close(this->hidden->audio_fd);
-		this->hidden->audio_fd = -1;
+	if ( this->hidden->output != NULL ) {
+		SDL_RWclose(this->hidden->output);
+		this->hidden->output = NULL;
 	}
 }
 
 static int DISKAUD_OpenAudio(_THIS, SDL_AudioSpec *spec)
 {
-    const char *fname = DISKAUD_GetOutputFilename();
+	const char *fname = DISKAUD_GetOutputFilename();
 
 	/* Open the audio device */
-    this->hidden->audio_fd = open(fname, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
-	if ( this->hidden->audio_fd < 0 ) {
-		SDL_SetError("Couldn't open %s: %s", fname, strerror(errno));
+	this->hidden->output = SDL_RWFromFile(fname, "wb");
+	if ( this->hidden->output == NULL ) {
 		return(-1);
 	}
 
-    fprintf(stderr, "WARNING: You are using the SDL disk writer"
+#if HAVE_STDIO_H
+	fprintf(stderr, "WARNING: You are using the SDL disk writer"
                     " audio driver!\n Writing to file [%s].\n", fname);
+#endif
 
 	/* Allocate mixing buffer */
 	this->hidden->mixlen = spec->size;
--- a/src/audio/disk/SDL_diskaudio.h	Sat Mar 04 05:13:03 2006 +0000
+++ b/src/audio/disk/SDL_diskaudio.h	Sat Mar 04 08:24:35 2006 +0000
@@ -24,6 +24,7 @@
 #ifndef _SDL_diskaudio_h
 #define _SDL_diskaudio_h
 
+#include "SDL_rwops.h"
 #include "../SDL_sysaudio.h"
 
 /* Hidden "this" pointer for the video functions */
@@ -31,10 +32,10 @@
 
 struct SDL_PrivateAudioData {
 	/* The file descriptor for the audio device */
-	int audio_fd;
-    Uint8 *mixbuf;
-    Uint32 mixlen;
-    Uint32 write_delay;
+	SDL_RWops *output;
+	Uint8 *mixbuf;
+	Uint32 mixlen;
+	Uint32 write_delay;
 };
 
 #endif /* _SDL_diskaudio_h */
--- a/src/file/SDL_rwops.c	Sat Mar 04 05:13:03 2006 +0000
+++ b/src/file/SDL_rwops.c	Sat Mar 04 08:24:35 2006 +0000
@@ -29,16 +29,25 @@
 #include "SDL_rwops.h"
 
 
-#ifdef __WIN32__
+#if defined(__WIN32__)
 
 /* Functions to read/write Win32 API file pointers */
+/* Will not use it on WinCE because stdio is buffered, it means
+   faster, and all stdio functions anyway are embedded in coredll.dll - 
+   the main wince dll*/
 
 #define WINDOWS_LEAN_AND_MEAN
 #include <windows.h>
 
-static int win32_file_open(SDL_RWops *context, const char *filename, const char *mode) {
-	
+#ifndef INVALID_SET_FILE_POINTER
+#define INVALID_SET_FILE_POINTER 0xFFFFFFFF
+#endif
+
+static int win32_file_open(SDL_RWops *context, const char *filename, const char *mode)
+{
+#ifndef _WIN32_WCE
 	UINT	old_error_mode;
+#endif
 	HANDLE	h;
 	DWORD	r_right, w_right;
 	DWORD	must_exist, truncate;
@@ -64,15 +73,31 @@
 
 	if (!r_right && !w_right) /* inconsistent mode */
 		return -1; /* failed (invalid call)*/
-	
+
+#ifdef _WIN32_WCE
+	{
+		size_t size = SDL_strlen(filename)+1;
+		wchar_t *filenameW = SDL_stack_alloc(wchar_t, size);
+
+		if ( MultiByteToWideChar(CP_UTF8, 0, filename, -1, filenameW, size) == 0 ) {
+			SDL_SetError("Unable to convert filename to Unicode");
+			SDL_stack_free(filenameW);
+			return -1;
+		}
+		h = CreateFile(filenameW, (w_right|r_right), (w_right)? 0 : FILE_SHARE_READ, 
+					   NULL, (must_exist|truncate|a_mode), FILE_ATTRIBUTE_NORMAL,NULL);
+		SDL_stack_free(filenameW);
+	}
+#else
 	/* Do not open a dialog box if failure */
-	old_error_mode = SetErrorMode(SEM_NOOPENFILEERRORBOX|SEM_FAILCRITICALERRORS);	
-	
+	old_error_mode = SetErrorMode(SEM_NOOPENFILEERRORBOX|SEM_FAILCRITICALERRORS);
+
 	h = CreateFile(filename, (w_right|r_right), (w_right)? 0 : FILE_SHARE_READ, 
 		           NULL, (must_exist|truncate|a_mode), FILE_ATTRIBUTE_NORMAL,NULL);
-	
+
 	/* restore old behaviour */
 	SetErrorMode(old_error_mode);
+#endif /* _WIN32_WCE */
 
 	if (h==INVALID_HANDLE_VALUE) {
 		SDL_SetError("Couldn't open %s",filename);
@@ -83,7 +108,8 @@
 	
 	return 0; /* ok */
 }
-static int win32_file_seek(SDL_RWops *context, int offset, int whence) {
+static int win32_file_seek(SDL_RWops *context, int offset, int whence)
+{
 	DWORD win32whence;
 	int   file_pos;
 	
@@ -112,7 +138,8 @@
 	SDL_Error(SDL_EFSEEK);
 	return -1; /* error */
 }
-static int win32_file_read(SDL_RWops *context, void *ptr, int size, int maxnum) {
+static int win32_file_read(SDL_RWops *context, void *ptr, int size, int maxnum)
+{
 	
 	int		total_bytes; 
 	DWORD	byte_read,nread;
@@ -129,7 +156,8 @@
 	nread = byte_read/size;
 	return nread;
 }
-static int win32_file_write(SDL_RWops *context, const void *ptr, int size, int num) {
+static int win32_file_write(SDL_RWops *context, const void *ptr, int size, int num)
+{
 	
 	int		total_bytes; 
 	DWORD	byte_written,nwritten;
@@ -155,7 +183,8 @@
 	nwritten = byte_written/size;
 	return nwritten;
 }
-static int win32_file_close(SDL_RWops *context) {
+static int win32_file_close(SDL_RWops *context)
+{
 	
 	if ( context ) {								
 		if (context->hidden.win32io.h != INVALID_HANDLE_VALUE) {
@@ -249,7 +278,7 @@
 	size_t mem_available;
 
 	total_bytes = (maxnum * size);
-	if ( (maxnum <= 0) || (size <= 0) || ((total_bytes / maxnum) != size) ) {
+	if ( (maxnum <= 0) || (size <= 0) || ((total_bytes / maxnum) != (size_t) size) ) {
 		return 0;
 	}
 
@@ -335,13 +364,15 @@
 SDL_RWops *SDL_RWFromFile(const char *file, const char *mode)
 {
 	SDL_RWops *rwops = NULL;
-
+#ifdef HAVE_STDIO_H
+	FILE *fp = NULL;
+#endif
 	if ( !file || !*file || !mode || !*mode ) {
 		SDL_SetError("SDL_RWFromFile(): No file or no mode specified");
 		return NULL;
 	}
 
-#ifdef __WIN32__
+#if defined(__WIN32__)
 	rwops = SDL_AllocRW();
 	if (!rwops)
 		return NULL; /* SDL_SetError already setup by SDL_AllocRW() */
@@ -356,7 +387,6 @@
 	rwops->close = win32_file_close;
 
 #elif HAVE_STDIO_H
-	FILE *fp;
 
 #ifdef __MACOS__
 	{
--- a/src/main/win32/SDL_win32_main.c	Sat Mar 04 05:13:03 2006 +0000
+++ b/src/main/win32/SDL_win32_main.c	Sat Mar 04 08:24:35 2006 +0000
@@ -51,27 +51,6 @@
 #if defined(_WIN32_WCE) && _WIN32_WCE < 300
 /* seems to be undefined in Win CE although in online help */
 #define isspace(a) (((CHAR)a == ' ') || ((CHAR)a == '\t'))
-
-/* seems to be undefined in Win CE although in online help */
-char *SDL_strrchr(char *str, int c)
-{
-	char *p;
-
-	/* Skip to the end of the string */
-	p=str;
-	while (*p)
-		p++;
-
-	/* Look for the given character */
-	while ( (p >= str) && (*p != (CHAR)c) )
-		p--;
-
-	/* Return NULL if character not found */
-	if ( p < str ) {
-		p = NULL;
-	}
-	return p;
-}
 #endif /* _WIN32_WCE < 300 */
 
 /* Parse a command line buffer into arguments */
@@ -281,8 +260,13 @@
 	}
 	path[pathlen] = '\0';
 
+#ifdef _WIN32_WCE
+	wcsncpy( stdoutPath, path, SDL_arraysize(stdoutPath) );
+	wcsncat( stdoutPath, DIR_SEPERATOR STDOUT_FILE, SDL_arraysize(stdoutPath) );
+#else
 	SDL_strlcpy( stdoutPath, path, SDL_arraysize(stdoutPath) );
 	SDL_strlcat( stdoutPath, DIR_SEPERATOR STDOUT_FILE, SDL_arraysize(stdoutPath) );
+#endif
     
 	/* Redirect standard input and standard output */
 	newfp = freopen(stdoutPath, TEXT("w"), stdout);
@@ -300,8 +284,13 @@
 	}
 #endif /* _WIN32_WCE */
 
+#ifdef _WIN32_WCE
+	wcsncpy( stderrPath, path, SDL_arraysize(stdoutPath) );
+	wcsncat( stderrPath, DIR_SEPERATOR STDOUT_FILE, SDL_arraysize(stdoutPath) );
+#else
 	SDL_strlcpy( stderrPath, path, SDL_arraysize(stderrPath) );
 	SDL_strlcat( stderrPath, DIR_SEPERATOR STDERR_FILE, SDL_arraysize(stderrPath) );
+#endif
 
 	newfp = freopen(stderrPath, TEXT("w"), stderr);
 #ifndef _WIN32_WCE
@@ -329,7 +318,7 @@
 	wcscpy (bufp+wcslen(bufp), TEXT("\" "));
 	wcsncpy(bufp+wcslen(bufp), szCmdLine,nLen-wcslen(bufp));
 	nLen = wcslen(bufp)+1;
-	cmdline = SDL_stack_alloc(wchar_t, nLen);
+	cmdline = SDL_stack_alloc(char, nLen);
 	if ( cmdline == NULL ) {
 		return OutOfMemory();
 	}
--- a/src/stdlib/SDL_malloc.c	Sat Mar 04 05:13:03 2006 +0000
+++ b/src/stdlib/SDL_malloc.c	Sat Mar 04 08:24:35 2006 +0000
@@ -27,17 +27,12 @@
 
 #ifndef HAVE_MALLOC
 
+#define LACKS_SYS_TYPES_H
 #define LACKS_STDIO_H
 #define LACKS_STRINGS_H
 #define LACKS_STRING_H
 #define LACKS_STDLIB_H
 #define ABORT
-#define memset	SDL_memset
-#define memcpy	SDL_memcpy
-#define malloc	SDL_malloc
-#define calloc	SDL_calloc
-#define realloc	SDL_realloc
-#define free	SDL_free
 
 /*
   This is a version (aka dlmalloc) of malloc/free/realloc written by
@@ -496,6 +491,7 @@
 #define LACKS_STRINGS_H
 #define LACKS_SYS_TYPES_H
 #define LACKS_ERRNO_H
+#define LACKS_FCNTL_H 
 #define MALLOC_FAILURE_ACTION
 #define MMAP_CLEARS 0 /* WINCE and some others apparently don't clear */
 #endif  /* WIN32 */
@@ -613,6 +609,13 @@
 #define MALLINFO_FIELD_TYPE size_t
 #endif  /* MALLINFO_FIELD_TYPE */
 
+#define memset	SDL_memset
+#define memcpy	SDL_memcpy
+#define malloc	SDL_malloc
+#define calloc	SDL_calloc
+#define realloc	SDL_realloc
+#define free	SDL_free
+
 /*
   mallopt tuning options.  SVID/XPG defines four standard parameter
   numbers for mallopt, normally defined in malloc.h.  None of these
--- a/src/video/gapi/SDL_gapivideo.c	Sat Mar 04 05:13:03 2006 +0000
+++ b/src/video/gapi/SDL_gapivideo.c	Sat Mar 04 08:24:35 2006 +0000
@@ -33,15 +33,24 @@
 // TODO: windib on SH3 PPC2000 landscape test
 // TODO: optimize 8bpp landscape mode
 
+// there is some problems in runnings apps from a device landscape mode
+// due to WinCE bugs. Some works and some - does not.
+// TODO: finish Axim Dell X30 and user landscape mode, device landscape mode
+// TODO: finish Axim Dell X30 user portrait, device landscape stylus conversion
+// TODO: fix running GAPI apps from landscape mode - 
+//       wince goes to portrait mode, but does not update video memory
+
+
+#include "SDL.h"
+#include "SDL_error.h"
 #include "SDL_video.h"
 #include "SDL_mouse.h"
 #include "../SDL_sysvideo.h"
 #include "../SDL_pixels_c.h"
 #include "../../events/SDL_events_c.h"
-
-#include "SDL_syswm_c.h"
-#include "SDL_sysmouse_c.h"
-#include "SDL_dibevents_c.h" 
+#include "../wincommon/SDL_syswm_c.h"
+#include "../wincommon/SDL_sysmouse_c.h"
+#include "../windib/SDL_dibevents_c.h" 
 
 #include "SDL_gapivideo.h"
 
@@ -55,6 +64,8 @@
 
 // for testing with GapiEmu
 #define USE_GAPI_EMU 0
+#define EMULATE_AXIM_X30 0
+#define WITHOUT_GAPI 0
 
 #if USE_GAPI_EMU && !REPORT_VIDEO_INFO
 #pragma message("Warning: Using GapiEmu in release build. I assume you'd like to set USE_GAPI_EMU to zero.")
@@ -113,7 +124,25 @@
 
 #define FORMAT_565 1
 #define FORMAT_555 2
-#define FORMAT_OTHER 3 
+#define FORMAT_OTHER 3
+
+/* Dell Axim x30 hangs when we use GAPI from landscape,
+   so lets avoid using GxOpenDisplay there via GETGXINFO trick 
+   It seems that GAPI subsystem use the same ExtEscape code.
+*/
+#define GETGXINFO 0x00020000
+
+typedef struct GXDeviceInfo
+{
+long Version; //00 (should filled with 100 before calling ExtEscape)
+void * pvFrameBuffer; //04
+unsigned long cbStride; //08
+unsigned long cxWidth; //0c
+unsigned long cyHeight; //10
+unsigned long cBPP; //14
+unsigned long ffFormat; //18
+char Unused[0x84-7*4];
+} GXDeviceInfo; 
 
 static int GAPI_Available(void)
 {
@@ -123,6 +152,10 @@
 	ReleaseDC(NULL, hdc);
 	g_bRawBufferAvailable = result > 0;
 
+#if WITHOUT_GAPI
+	return g_bRawBufferAvailable;
+#endif
+
 #if USE_GAPI_EMU
 	g_hGapiLib = LoadLibrary(_T("GAPI_Emu.dll"));
 	if( !g_hGapiLib )
@@ -332,6 +365,8 @@
 		this->hidden->needUpdate = 1;
 		this->hidden->hiresFix = 0;
 		this->hidden->useVga = 0;
+		this->hidden->useGXOpenDisplay = 1;
+
 #ifdef _ARM_
 		/* check some devices and extract addition info */
 		SystemParametersInfo( SPI_GETOEMINFO, sizeof( oemstr ), oemstr, 0 );
@@ -344,6 +379,29 @@
 			this->hidden->gxProperties.cbyPitch = 2;
 			this->hidden->needUpdate = 0;
 		}
+#if (EMULATE_AXIM_X30 == 0)
+		// buggy Dell Axim X30
+		if( _tcsncmp(oemstr, L"Dell Axim X30", 13) == 0 )
+#endif
+		{
+			GXDeviceInfo gxInfo = {0};
+			HDC hdc = GetDC(NULL);
+			int result;
+
+			gxInfo.Version = 100;
+			result = ExtEscape(hdc, GETGXINFO, 0, NULL, sizeof(gxInfo), (char *)&gxInfo);
+			if( result > 0 )
+			{
+				this->hidden->useGXOpenDisplay = 0;
+				this->hidden->videoMem = gxInfo.pvFrameBuffer;
+				this->hidden->needUpdate = 0;
+				this->hidden->gxProperties.cbxPitch = 2;
+				this->hidden->gxProperties.cbyPitch = 480;
+				this->hidden->gxProperties.cxWidth = gxInfo.cxWidth;
+				this->hidden->gxProperties.cyHeight = gxInfo.cyHeight;
+				this->hidden->gxProperties.ffFormat = gxInfo.ffFormat;
+			}
+		}
 #endif
 	} else
 	{
@@ -598,7 +656,7 @@
 		return(NULL);
 	}
 
-	/* detect landscape mode */
+	/* detect user landscape mode */
 	if( (width > height) && (GetSystemMetrics(SM_CXSCREEN) < GetSystemMetrics(SM_CYSCREEN))) 
 		gapi->userOrientation = SDL_ORIENTATION_RIGHT;
 
@@ -610,7 +668,8 @@
 			gapi->hiresFix = 1;
 	} else
 		if( (width > GetSystemMetrics(SM_CXSCREEN)) || (height > GetSystemMetrics(SM_CYSCREEN)))
-			gapi->hiresFix = 1;
+			if( !((width == GetSystemMetrics(SM_CYSCREEN)) && (height == GetSystemMetrics(SM_CXSCREEN)))) // user portrait, device landscape
+				gapi->hiresFix = 1;
 
 	switch( gapi->userOrientation )
 	{
@@ -652,7 +711,7 @@
 
 	if (!SDL_windowid)
 		SetWindowLong(SDL_Window, GWL_STYLE, style);
- 
+
 	/* Allocate bitmap */
 	if(gapiBuffer) 
 	{
@@ -672,6 +731,14 @@
 	ShowWindow(SDL_Window, SW_SHOW);
 	SetForegroundWindow(SDL_Window);
 
+	/* Open GAPI display */
+	if( !gapi->useVga && this->hidden->useGXOpenDisplay )
+		if( !gapi->gxFunc.GXOpenDisplay(SDL_Window, GX_FULLSCREEN) )
+		{
+			SDL_SetError("Couldn't initialize GAPI");
+			return(NULL);
+		}
+
 #if REPORT_VIDEO_INFO
 	printf("Video properties:\n");
 	printf("display bpp: %d\n", gapi->gxProperties.cBPP);
@@ -680,24 +747,24 @@
 	printf("x pitch: %d\n", gapi->gxProperties.cbxPitch);
 	printf("y pitch: %d\n", gapi->gxProperties.cbyPitch);
 	printf("gapi flags: 0x%x\n", gapi->gxProperties.ffFormat);
+
+	if( !gapi->useVga && this->hidden->useGXOpenDisplay && gapi->needUpdate)
+	{
+		gapi->videoMem = gapi->gxFunc.GXBeginDraw(); 
+		gapi->gxFunc.GXEndDraw();
+	}
+
 	printf("video memory: 0x%x\n", gapi->videoMem);
 	printf("need update: %d\n", gapi->needUpdate);
 	printf("hi-res fix: %d\n", gapi->hiresFix);
 	printf("VGA is available on the device: %d\n", g_bRawBufferAvailable);
-	printf("use VGA resolution: %d\n", gapi->useVga);
+	printf("use raw framebuffer: %d\n", gapi->useVga);
 	printf("video surface bpp: %d\n", video->format->BitsPerPixel);
 	printf("video surface width: %d\n", video->w);
 	printf("video surface height: %d\n", video->h);
 #endif
 
-	/* Open GAPI display */
-	if( !gapi->useVga )
-		if( !gapi->gxFunc.GXOpenDisplay(SDL_Window, GX_FULLSCREEN) )
-		{
-			SDL_SetError("Couldn't initialize GAPI");
-			return(NULL);
-		}
- 
+
 	/* Blank screen */
 	allScreen.x = allScreen.y = 0;
 	allScreen.w = video->w - 1;
@@ -790,6 +857,7 @@
 			else
 			{
 				destPointer += gapi->gxProperties.cbyPitch / 2;
+
 				while(width--) // iPaq 3660
 				{
 					*(DWORD*)destPointer =(*line1++ << 16) | *line2++;
--- a/src/video/gapi/SDL_gapivideo.h	Sat Mar 04 05:13:03 2006 +0000
+++ b/src/video/gapi/SDL_gapivideo.h	Sat Mar 04 08:24:35 2006 +0000
@@ -136,6 +136,7 @@
 	int invert;
 	char hiresFix; // using hires mode without defining hires resource
 // --------------
+	int useGXOpenDisplay; /* use GXOpenDispplay */
     int w, h;
 	enum SDL_ScreenOrientation gapiOrientation;
 
--- a/src/video/wincommon/SDL_lowvideo.h	Sat Mar 04 05:13:03 2006 +0000
+++ b/src/video/wincommon/SDL_lowvideo.h	Sat Mar 04 08:24:35 2006 +0000
@@ -27,6 +27,16 @@
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
 
+#ifndef SetClassLongPtr
+#define SetClassLongPtr	SetClassLong
+#endif
+#ifndef GetWindowLongPtr
+#define GetWindowLongPtr	GetWindowLong
+#endif
+#ifndef SetWindowLongPtr
+#define SetWindowLongPtr	SetWindowLong
+#endif
+
 #include "../SDL_sysvideo.h"
 
 /* Hidden "this" pointer for the video functions */
--- a/src/video/wincommon/SDL_sysevents.c	Sat Mar 04 05:13:03 2006 +0000
+++ b/src/video/wincommon/SDL_sysevents.c	Sat Mar 04 08:24:35 2006 +0000
@@ -40,10 +40,14 @@
 #endif
 
 #ifdef _WIN32_WCE
-#include "SDL_gapivideo.h"
+#include "../gapi/SDL_gapivideo.h"
+
+#define IsZoomed(HWND) 1
 #define NO_GETKEYBOARDSTATE
+#if _WIN32_WCE < 420
 #define NO_CHANGEDISPLAYSETTINGS
 #endif
+#endif
 
 /* The window we use for everything... */
 #ifdef _WIN32_WCE
@@ -120,6 +124,29 @@
 
 	switch(rotate) {
 		case SDL_ORIENTATION_UP:
+			{
+/* this code needs testing on a real device!
+   So it will be enabled later */
+/*
+#ifdef _WIN32_WCE
+#if _WIN32_WCE >= 420
+				// test device orientation
+				// FIXME: do not check every mouse message
+				DEVMODE settings;
+				SDL_memset(&settings, 0, sizeof(DEVMODE));
+				settings.dmSize = sizeof(DEVMODE);
+				settings.dmFields = DM_DISPLAYORIENTATION;
+				ChangeDisplaySettingsEx(NULL, &settings, NULL, CDS_TEST, NULL);
+				if( settings.dmOrientation == DMDO_90 )
+				{
+					rotatedX = SDL_VideoSurface->h - *x;
+					rotatedY = *y;
+					*x = rotatedX;
+					*y = rotatedY;
+				}
+#endif
+#endif */
+			}
 			break;
 		case SDL_ORIENTATION_RIGHT:
 			if (!SDL_VideoSurface)
@@ -144,17 +171,21 @@
 
 static void SDL_RestoreGameMode(void)
 {
+	ShowWindow(SDL_Window, SW_RESTORE);
 #ifndef NO_CHANGEDISPLAYSETTINGS
-	ShowWindow(SDL_Window, SW_RESTORE);
+#ifndef _WIN32_WCE
 	ChangeDisplaySettings(&SDL_fullscreen_mode, CDS_FULLSCREEN);
 #endif
+#endif /* NO_CHANGEDISPLAYSETTINGS */
 }
 static void SDL_RestoreDesktopMode(void)
 {
+	ShowWindow(SDL_Window, SW_MINIMIZE);
 #ifndef NO_CHANGEDISPLAYSETTINGS
-	ShowWindow(SDL_Window, SW_MINIMIZE);
+#ifndef _WIN32_WCE
 	ChangeDisplaySettings(NULL, 0);
 #endif
+#endif /* NO_CHANGEDISPLAYSETTINGS */
 }
 
 #ifdef WM_MOUSELEAVE
--- a/src/video/wincommon/SDL_syswm.c	Sat Mar 04 05:13:03 2006 +0000
+++ b/src/video/wincommon/SDL_syswm.c	Sat Mar 04 08:24:35 2006 +0000
@@ -220,9 +220,6 @@
 	if ( screen_icn == NULL ) {
 		SDL_SetError("Couldn't create Win32 icon handle");
 	} else {
-#ifndef SetClassLongPtr
-#define SetClassLongPtr	SetClassLong
-#endif
 		SetClassLongPtr(SDL_Window, GCL_HICON, (LONG_PTR)screen_icn);
 	}
 	SDL_stack_free(icon_win32);
--- a/src/video/windib/SDL_dibvideo.c	Sat Mar 04 05:13:03 2006 +0000
+++ b/src/video/windib/SDL_dibvideo.c	Sat Mar 04 08:24:35 2006 +0000
@@ -24,13 +24,6 @@
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
 
-#if defined(_WIN32_WCE)
-
-// defined and used in SDL_sysevents.c
-extern HINSTANCE aygshell;
-
-#endif
-
 /* Not yet in the mingw32 cross-compile headers */
 #ifndef CDS_FULLSCREEN
 #define CDS_FULLSCREEN	4
@@ -49,8 +42,12 @@
 
 #ifdef _WIN32_WCE
 #define NO_GETDIBITS
-#define NO_CHANGEDISPLAYSETTINGS
 #define NO_GAMMA_SUPPORT
+  #if _WIN32_WCE < 420
+    #define NO_CHANGEDISPLAYSETTINGS
+  #else
+    #define ChangeDisplaySettings(lpDevMode, dwFlags) ChangeDisplaySettingsEx(NULL, (lpDevMode), 0, (dwFlags), 0)
+  #endif
 #endif
 #ifndef WS_MAXIMIZE
 #define WS_MAXIMIZE	0
@@ -65,6 +62,11 @@
 #define PC_NOCOLLAPSE	0
 #endif
 
+#ifdef _WIN32_WCE
+// defined and used in SDL_sysevents.c
+extern HINSTANCE aygshell;
+#endif
+
 /* Initialization/Query functions */
 static int DIB_VideoInit(_THIS, SDL_PixelFormat *vformat);
 static SDL_Rect **DIB_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
@@ -190,8 +192,6 @@
 	DIB_Available, DIB_CreateDevice
 };
 
-#ifndef NO_CHANGEDISPLAYSETTINGS
-
 static int cmpmodes(const void *va, const void *vb)
 {
     SDL_Rect *a = *(SDL_Rect **)va;
@@ -248,8 +248,6 @@
 	return(0);
 }
 
-#endif /* !NO_CHANGEDISPLAYSETTINGS */
-
 static HPALETTE DIB_CreatePalette(int bpp)
 {
 /*	RJR: March 28, 2000
@@ -326,6 +324,13 @@
 	DIB_CheckGamma(this);
 
 #ifndef NO_CHANGEDISPLAYSETTINGS
+
+	settings.dmSize = sizeof(DEVMODE);
+	settings.dmDriverExtra = 0;
+#ifdef _WIN32_WCE
+	settings.dmFields = DM_DISPLAYQUERYORIENTATION;
+	this->hidden->supportRotation = ChangeDisplaySettingsEx(NULL, &settings, NULL, CDS_TEST, NULL) == DISP_CHANGE_SUCCESSFUL;
+#endif
 	/* Query for the desktop resolution */
 	EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &SDL_desktop_mode);
 
@@ -333,13 +338,30 @@
 	for ( i=0; EnumDisplaySettings(NULL, i, &settings); ++i ) {
 		DIB_AddMode(this, settings.dmBitsPerPel,
 			settings.dmPelsWidth, settings.dmPelsHeight);
+#ifdef _WIN32_WCE		
+		if( this->hidden->supportRotation )
+			DIB_AddMode(this, settings.dmBitsPerPel,
+				settings.dmPelsHeight, settings.dmPelsWidth);
+#endif
 	}
 	/* Sort the mode lists */
+	if( i > 1 )
 	for ( i=0; i<NUM_MODELISTS; ++i ) {
 		if ( SDL_nummodes[i] > 0 ) {
 			SDL_qsort(SDL_modelist[i], SDL_nummodes[i], sizeof *SDL_modelist[i], cmpmodes);
 		}
 	}
+#else
+	// WinCE and fullscreen mode:
+	// We use only vformat->BitsPerPixel that allow SDL to
+	// emulate other bpp (8, 32) and use triple buffer, 
+	// because SDL surface conversion is much faster than the WinCE one.
+	// Although it should be tested on devices with graphics accelerator.
+
+    DIB_AddMode(this, vformat->BitsPerPixel,
+			GetDeviceCaps(GetDC(NULL), HORZRES), 
+			GetDeviceCaps(GetDC(NULL), VERTRES));
+
 #endif /* !NO_CHANGEDISPLAYSETTINGS */
 
 	/* Grab an identity palette if we are in a palettized mode */
@@ -352,6 +374,10 @@
 	/* Fill in some window manager capabilities */
 	this->info.wm_available = 1;
 
+#ifdef _WIN32_WCE
+	this->hidden->origRotation = -1;
+#endif
+
 	/* We're done! */
 	return(0);
 }
@@ -359,15 +385,11 @@
 /* We support any format at any dimension */
 SDL_Rect **DIB_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
 {
-#ifdef NO_CHANGEDISPLAYSETTINGS
-	return((SDL_Rect **)-1);
-#else
 	if ( (flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
 		return(SDL_modelist[((format->BitsPerPixel+7)/8)-1]);
 	} else {
 		return((SDL_Rect **)-1);
 	}
-#endif
 }
 
 
@@ -531,6 +553,61 @@
 
 		SDL_memset(&settings, 0, sizeof(DEVMODE));
 		settings.dmSize = sizeof(DEVMODE);
+
+#ifdef _WIN32_WCE
+		// try to rotate screen to fit requested resolution
+		if( this->hidden->supportRotation )
+		{
+			DWORD rotation;
+
+			// ask current mode
+			settings.dmFields = DM_DISPLAYORIENTATION;
+			ChangeDisplaySettingsEx(NULL, &settings, NULL, CDS_TEST, NULL);
+			rotation = settings.dmDisplayOrientation;
+
+			if( (width > GetDeviceCaps(GetDC(NULL), HORZRES))
+				&& (height < GetDeviceCaps(GetDC(NULL), VERTRES)))
+			{
+				switch( rotation )
+				{
+				case DMDO_0:
+					settings.dmDisplayOrientation = DMDO_90;
+					break;
+				case DMDO_270:
+					settings.dmDisplayOrientation = DMDO_180;
+					break;
+				}
+				if( settings.dmDisplayOrientation != rotation )
+				{
+					// go to landscape
+					this->hidden->origRotation = rotation;
+					ChangeDisplaySettingsEx(NULL,&settings,NULL,CDS_RESET,NULL);
+				}
+			}
+			if( (width < GetDeviceCaps(GetDC(NULL), HORZRES))
+				&& (height > GetDeviceCaps(GetDC(NULL), VERTRES)))
+			{
+				switch( rotation )
+				{
+				case DMDO_90:
+					settings.dmDisplayOrientation = DMDO_0;
+					break;
+				case DMDO_180:
+					settings.dmDisplayOrientation = DMDO_270;
+					break;
+				}
+				if( settings.dmDisplayOrientation != rotation )
+				{
+					// go to portrait
+					this->hidden->origRotation = rotation;
+					ChangeDisplaySettingsEx(NULL,&settings,NULL,CDS_RESET,NULL);
+				}
+			}
+
+		}
+#endif
+
+#ifndef _WIN32_WCE
 		settings.dmBitsPerPel = video->format->BitsPerPixel;
 		settings.dmPelsWidth = width;
 		settings.dmPelsHeight = height;
@@ -545,10 +622,14 @@
 			settings.dmFields &= ~DM_DISPLAYFREQUENCY;
 			changed = (ChangeDisplaySettings(&settings, CDS_FULLSCREEN) == DISP_CHANGE_SUCCESSFUL);
 		}
+#else
+		changed = 1;
+#endif
 		if ( changed ) {
 			video->flags |= SDL_FULLSCREEN;
 			SDL_fullscreen_mode = settings;
 		}
+
 	}
 #endif /* !NO_CHANGEDISPLAYSETTINGS */
 
@@ -669,9 +750,12 @@
 			video->flags |= SDL_HWPALETTE;
 		}
 	}
-
+#ifndef _WIN32_WCE
 	/* Resize the window */
 	if ( !SDL_windowid && !IsZoomed(SDL_Window) ) {
+#else
+	if ( !SDL_windowid ) {
+#endif
 		HWND top;
 		UINT swp_flags;
 		const char *window = NULL;
--- a/src/video/windib/SDL_dibvideo.h	Sat Mar 04 05:13:03 2006 +0000
+++ b/src/video/windib/SDL_dibvideo.h	Sat Mar 04 08:24:35 2006 +0000
@@ -46,8 +46,12 @@
     SDL_Rect **SDL_modelist[NUM_MODELISTS];
 
 	SDL_ScreenOrientation orientation;
-	int invert;
-	char hiresFix; // using hires mode without defining hires resource
+#ifdef _WIN32_WCE
+	int invert; /* do to remove, used by GAPI driver! */
+	char hiresFix; /* using hires mode without defining hires resource */
+	int supportRotation; /* for Pocket PC devices */
+	DWORD origRotation; /* for Pocket PC devices */
+#endif
 };
 /* Old variable names */
 #define screen_bmp		(this->hidden->screen_bmp)
--- a/test/testalpha.c	Sat Mar 04 05:13:03 2006 +0000
+++ b/test/testalpha.c	Sat Mar 04 08:24:35 2006 +0000
@@ -45,7 +45,7 @@
         {
 		for ( i=0; i<screen->h; ++i ) {
 			gradient=((i*255)/screen->h);
-                        color = SDL_MapRGB(screen->format, gradient, gradient, gradient);
+                        color = (Uint16)SDL_MapRGB(screen->format, gradient, gradient, gradient);
                         buffer16=(Uint16*)buffer;
                         for (k=0; k<screen->w; k++)
                         {
@@ -340,8 +340,14 @@
 	}
 
 	/* Alpha blending doesn't work well at 8-bit color */
+#ifdef _WIN32_WCE
+	/* Pocket PC */
+	w = 240;
+	h = 320;
+#else
 	w = 640;
 	h = 480;
+#endif
 	info = SDL_GetVideoInfo();
 	if ( info->vfmt->BitsPerPixel > 8 ) {
 		video_bpp = info->vfmt->BitsPerPixel;
@@ -386,21 +392,12 @@
 		}
 	}
 
-	/* Set 640x480 video mode */
-#ifndef _WIN32_WCE
+	/* Set video mode */
 	if ( (screen=SDL_SetVideoMode(w,h,video_bpp,videoflags)) == NULL ) {
-		fprintf(stderr, "Couldn't set 640x480x%d video mode: %s\n",
-						video_bpp, SDL_GetError());
+		fprintf(stderr, "Couldn't set %dx%dx%d video mode: %s\n",
+						w, h, video_bpp, SDL_GetError());
 		quit(2);
 	}
-#else
-	/* Pocket PC */
-	if ( (screen=SDL_SetVideoMode(240,320,video_bpp,SDL_FULLSCREEN)) == NULL ) {
-		fprintf(stderr, "Couldn't set 240x320x%d video mode: %s\n",
-						video_bpp, SDL_GetError());
-		quit(2);
-	}
-#endif
 	FillBackground(screen);
 
 	/* Create the light */