Updates to PocketPC (WinCE) support, thanks to Dmitry Yakimov at
authorRyan C. Gordon <icculus@icculus.org>
Thu, 29 Sep 2005 09:43:00 +0000
changeset 1152 51a8702d8ecd
parent 1151 be9c9c8f6d53
child 1153 5bc98ce985c2
Updates to PocketPC (WinCE) support, thanks to Dmitry Yakimov at activekitten.com.
VisualCE.zip
src/SDL_fatal.c
src/SDL_loadso.c
src/cdrom/dummy/SDL_syscdrom.c
src/cpuinfo/SDL_cpuinfo.c
src/events/SDL_quit.c
src/joystick/dummy/SDL_sysjoystick.c
src/video/wincommon/SDL_sysevents.c
src/video/wincommon/SDL_syswm.c
src/video/windib/SDL_dibevents.c
src/video/windib/SDL_dibvideo.c
test/testalpha.c
test/testwin.c
Binary file VisualCE.zip has changed
--- a/src/SDL_fatal.c	Wed Sep 28 11:36:20 2005 +0000
+++ b/src/SDL_fatal.c	Thu Sep 29 09:43:00 2005 +0000
@@ -25,6 +25,10 @@
  "@(#) $Id$";
 #endif
 
+#ifdef _WIN32_WCE
+#define NO_SIGNAL_H
+#endif
+ 
 /* General fatal signal handling code for SDL */
 
 #ifdef NO_SIGNAL_H
--- a/src/SDL_loadso.c	Wed Sep 28 11:36:20 2005 +0000
+++ b/src/SDL_loadso.c	Thu Sep 29 09:43:00 2005 +0000
@@ -31,7 +31,7 @@
 #include <stdio.h>
 #if defined(USE_DLOPEN)
 # include <dlfcn.h>
-#elif defined(WIN32)
+#elif defined(WIN32) || defined(_WIN32_WCE)
 # include <windows.h>
 #elif defined(__BEOS__)
 # include <be/kernel/image.h>
@@ -60,6 +60,30 @@
 /* * */
 	handle = dlopen(sofile, RTLD_NOW);
 	loaderror = (char *)dlerror();
+#elif defined(_WIN32_WCE)
+/* * */
+	char errbuf[512];
+
+	wchar_t *errbuf_t = malloc(512 * sizeof(wchar_t));
+	wchar_t *sofile_t = malloc((MAX_PATH+1) * sizeof(wchar_t));
+
+	MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, sofile, -1, sofile_t, MAX_PATH);
+	handle = (void *)LoadLibrary(sofile_t);
+
+	/* Generate an error message if all loads failed */
+	if ( handle == NULL ) {
+		FormatMessage((FORMAT_MESSAGE_IGNORE_INSERTS |
+					FORMAT_MESSAGE_FROM_SYSTEM),
+				NULL, GetLastError(), 
+				MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+				errbuf_t, SDL_TABLESIZE(errbuf), NULL);
+		WideCharToMultiByte(CP_ACP, 0, errbuf_t, -1, errbuf, 511, NULL, NULL);
+		loaderror = errbuf;
+	}
+
+	free(sofile_t);
+	free(errbuf_t);
+
 #elif defined(WIN32)
 /* * */
 	char errbuf[512];
@@ -139,6 +163,30 @@
 	if ( symbol == NULL ) {
 		loaderror = (char *)dlerror();
 	}
+#elif defined(_WIN32_WCE)
+/* * */
+	char errbuf[512];
+	int length = strlen(name);
+
+	wchar_t *name_t = malloc((length + 1) * sizeof(wchar_t));
+	wchar_t *errbuf_t = malloc(512 * sizeof(wchar_t));
+
+	MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, name, -1, name_t, length);
+
+	symbol = (void *)GetProcAddress((HMODULE)handle, name_t);
+	if ( symbol == NULL ) {
+		FormatMessage((FORMAT_MESSAGE_IGNORE_INSERTS |
+					FORMAT_MESSAGE_FROM_SYSTEM),
+				NULL, GetLastError(), 
+				MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+				errbuf_t, SDL_TABLESIZE(errbuf), NULL);
+		WideCharToMultiByte(CP_ACP, 0, errbuf_t, -1, errbuf, 511, NULL, NULL);
+		loaderror = errbuf;
+	}
+
+	free(name_t);
+	free(errbuf_t);
+
 #elif defined(WIN32)
 /* * */
 	char errbuf[512];
--- a/src/cdrom/dummy/SDL_syscdrom.c	Wed Sep 28 11:36:20 2005 +0000
+++ b/src/cdrom/dummy/SDL_syscdrom.c	Thu Sep 29 09:43:00 2005 +0000
@@ -40,3 +40,7 @@
 	return;
 }
 
+int SDL_CDROMInit(void)
+{
+	return 0;
+}
\ No newline at end of file
--- a/src/cpuinfo/SDL_cpuinfo.c	Wed Sep 28 11:36:20 2005 +0000
+++ b/src/cpuinfo/SDL_cpuinfo.c	Thu Sep 29 09:43:00 2005 +0000
@@ -101,7 +101,7 @@
 	:
 	: "%rax", "%rcx"
 	);
-#elif defined(_MSC_VER)
+#elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_X86_))
 	__asm {
         pushfd                      ; Get original EFLAGS
         pop     eax
@@ -140,7 +140,7 @@
 	:
 	: "%eax", "%ecx", "%edx", "%edi"
 	);
-#elif defined(_MSC_VER)
+#elif defined(_MSC_VER)  && (defined(_M_IX86) || defined(_X86_))
 	__asm {
         xor     eax, eax            ; Set up for CPUID instruction
         cpuid                       ; Get and save vendor ID
@@ -175,7 +175,7 @@
 	:
 	: "%eax", "%ecx", "%edx", "%edi"
 	);
-#elif defined(_MSC_VER)
+#elif defined(_MSC_VER)  && (defined(_M_IX86) || defined(_X86_))
 	__asm {
         mov     eax,80000000h       ; Query for extended functions
         cpuid                       ; Get extended function limit
--- a/src/events/SDL_quit.c	Wed Sep 28 11:36:20 2005 +0000
+++ b/src/events/SDL_quit.c	Thu Sep 29 09:43:00 2005 +0000
@@ -27,6 +27,10 @@
 
 /* General quit handling code for SDL */
 
+#if defined (_WIN32_WCE)
+#define NO_SIGNAL_H
+#endif
+
 #include <stdio.h>
 #ifndef NO_SIGNAL_H
 #include <signal.h>
--- a/src/joystick/dummy/SDL_sysjoystick.c	Wed Sep 28 11:36:20 2005 +0000
+++ b/src/joystick/dummy/SDL_sysjoystick.c	Thu Sep 29 09:43:00 2005 +0000
@@ -34,6 +34,8 @@
 #include "SDL_sysjoystick.h"
 #include "SDL_joystick_c.h"
 
+Uint8 SDL_numjoysticks = 0;
+
 /* Function to scan the system for joysticks.
  * This function should set SDL_numjoysticks to the number of available
  * joysticks.  Joystick 0 should be the system default joystick.
--- a/src/video/wincommon/SDL_sysevents.c	Wed Sep 28 11:36:20 2005 +0000
+++ b/src/video/wincommon/SDL_sysevents.c	Thu Sep 29 09:43:00 2005 +0000
@@ -40,6 +40,7 @@
 #include "SDL_lowvideo.h"
 #include "SDL_syswm_c.h"
 #include "SDL_main.h"
+#include "SDL_loadso.h"
 
 #ifdef WMMSG_DEBUG
 #include "wmmsg.h"
@@ -71,13 +72,37 @@
 
 
 /* Functions called by the message processing function */
-LONG
-(*HandleMessage)(_THIS, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)=NULL;
+LONG (*HandleMessage)(_THIS, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)=NULL;
 void (*WIN_RealizePalette)(_THIS);
 void (*WIN_PaletteChanged)(_THIS, HWND window);
 void (*WIN_WinPAINT)(_THIS, HDC hdc);
 extern void DIB_SwapGamma(_THIS);
 
+#if defined(_WIN32_WCE)
+
+// dynamically load aygshell dll because we want SDL to work on HPC and be300
+HINSTANCE aygshell = NULL;
+BOOL (WINAPI *SHFullScreen)(HWND hwndRequester, DWORD dwState) = 0;
+
+#define SHFS_SHOWTASKBAR            0x0001
+#define SHFS_HIDETASKBAR            0x0002
+#define SHFS_SHOWSIPBUTTON          0x0004
+#define SHFS_HIDESIPBUTTON          0x0008
+#define SHFS_SHOWSTARTICON          0x0010
+#define SHFS_HIDESTARTICON          0x0020
+
+static void LoadAygshell(void)
+{
+	if( !aygshell )
+		 aygshell = SDL_LoadObject("aygshell.dll");
+	if( aygshell )
+	{
+		SHFullScreen = (int (WINAPI *)(struct HWND__ *,unsigned long)) SDL_LoadFunction(aygshell, "SHFullScreen");
+	}
+}
+
+#endif
+
 static void SDL_RestoreGameMode(void)
 {
 #ifndef NO_CHANGEDISPLAYSETTINGS
@@ -213,6 +238,18 @@
 						SDL_RestoreGameMode();
 					}
 				}
+#if defined(_WIN32_WCE)
+			if ( WINDIB_FULLSCREEN() )
+			{
+						LoadAygshell();
+						if( aygshell ) 
+							SHFullScreen(SDL_Window, SHFS_HIDESTARTICON|SHFS_HIDETASKBAR|SHFS_HIDESIPBUTTON);
+						else
+							ShowWindow(FindWindow(TEXT("HHTaskBar"),NULL),SW_HIDE);
+
+			}
+#endif
+
 				posted = SDL_PrivateAppActive(1, appstate);
 				WIN_GetKeyboardState();
 			} else {
@@ -230,6 +267,14 @@
 					}
 					if ( WINDIB_FULLSCREEN() ) {
 						SDL_RestoreDesktopMode();
+#if defined(_WIN32_WCE)
+						LoadAygshell();
+						if( aygshell ) 
+							SHFullScreen(SDL_Window, SHFS_SHOWSTARTICON|SHFS_SHOWTASKBAR|SHFS_SHOWSIPBUTTON);
+						else
+							ShowWindow(FindWindow(TEXT("HHTaskBar"),NULL),SW_SHOW);
+
+#endif
 					}
 				}
 				posted = SDL_PrivateAppActive(0, appstate);
--- a/src/video/wincommon/SDL_syswm.c	Wed Sep 28 11:36:20 2005 +0000
+++ b/src/video/wincommon/SDL_syswm.c	Thu Sep 29 09:43:00 2005 +0000
@@ -36,6 +36,8 @@
 #include "SDL_syswm_c.h"
 #include "SDL_wingl_c.h"
 #include "SDL_pixels_c.h"
+#include "SDL_loadso.h"
+
 
 #ifdef _WIN32_WCE
 #define DISABLE_ICON_SUPPORT
@@ -48,6 +50,25 @@
 /* The screen icon -- needs to be freed on SDL_VideoQuit() */
 HICON   screen_icn = NULL;
 
+#ifdef _WIN32_WCE
+
+BOOL (WINAPI *CoreCatchInput)(int flag) = NULL;
+int input_catched = 0;
+HINSTANCE coredll = NULL;
+
+// the same API call that gx.dll does to catch the input
+void LoadInputCatchFunc()
+{
+	coredll = SDL_LoadObject("coredll.dll");
+	if( coredll )
+	{
+		CoreCatchInput = (int (WINAPI *)(int)) GetProcAddress(coredll, (const unsigned short *) 1453);
+	}
+}
+
+#endif
+
+
 /* Win32 icon mask semantics are different from those of SDL:
      SDL applies the mask to the icon and copies result to desktop.
      Win32 applies the mask to the desktop and XORs the icon on.
@@ -245,6 +266,15 @@
 			ClientToScreen(SDL_Window, &pt);
 			SetCursorPos(pt.x,pt.y);
 		}
+#ifdef _WIN32_WCE
+		if( input_catched )
+		{
+			if( !CoreCatchInput ) LoadInputCatchFunc();
+
+			if( CoreCatchInput )
+				CoreCatchInput(0);
+		}
+#endif
 	} else {
 		ClipCursor(&SDL_bounds);
 		if ( !(SDL_cursorstate & CURSOR_VISIBLE) ) {
@@ -257,6 +287,15 @@
 			ClientToScreen(SDL_Window, &pt);
 			SetCursorPos(pt.x, pt.y);
 		}
+#ifdef _WIN32_WCE
+		if( !input_catched )
+		{
+			if( !CoreCatchInput ) LoadInputCatchFunc();
+
+			if( CoreCatchInput )
+				CoreCatchInput(1);
+		}
+#endif
 	}
 	return(mode);
 }
--- a/src/video/windib/SDL_dibevents.c	Wed Sep 28 11:36:20 2005 +0000
+++ b/src/video/windib/SDL_dibevents.c	Thu Sep 29 09:43:00 2005 +0000
@@ -360,12 +360,25 @@
 
 int DIB_CreateWindow(_THIS)
 {
+#if defined(_WIN32_WCE) && (_WIN32_WCE < 300)
+	wchar_t *SDL_windowid_t;
+#endif
+
 #ifndef CS_BYTEALIGNCLIENT
 #define CS_BYTEALIGNCLIENT	0
 #endif
 	SDL_RegisterApp("SDL_app", CS_BYTEALIGNCLIENT, 0);
 	if ( SDL_windowid ) {
+
+// wince 2.1 does not have strtol
+#if defined(_WIN32_WCE) && (_WIN32_WCE < 300)
+		SDL_windowid_t = malloc((strlen(SDL_windowid) + 1) * sizeof(wchar_t));
+		MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, SDL_windowid, -1, SDL_windowid_t, strlen(SDL_windowid) + 1);
+		SDL_Window = (HWND)wcstol(SDL_windowid_t, NULL, 0);
+		free(SDL_windowid_t);
+#else
 		SDL_Window = (HWND)strtol(SDL_windowid, NULL, 0);
+#endif
 		if ( SDL_Window == NULL ) {
 			SDL_SetError("Couldn't get user specified window");
 			return(-1);
--- a/src/video/windib/SDL_dibvideo.c	Wed Sep 28 11:36:20 2005 +0000
+++ b/src/video/windib/SDL_dibvideo.c	Thu Sep 29 09:43:00 2005 +0000
@@ -29,9 +29,13 @@
 #include <stdlib.h>
 #include <malloc.h>
 #include <windows.h>
-#if defined(WIN32_PLATFORM_PSPC)
-#include <aygshell.h>                      // Add Pocket PC includes
-#pragma comment( lib, "aygshell" )         // Link Pocket PC library
+
+
+#if defined(_WIN32_WCE)
+
+// defined and used in SDL_sysevents.c
+extern HINSTANCE aygshell;
+
 #endif
 
 /* Not yet in the mingw32 cross-compile headers */
@@ -191,7 +195,7 @@
 }
 
 VideoBootStrap WINDIB_bootstrap = {
-	"windib", "Win95/98/NT/2000 GDI",
+	"windib", "Win95/98/NT/2000/CE GDI",
 	DIB_Available, DIB_CreateDevice
 };
 
@@ -389,12 +393,6 @@
 	hdc = GetDC(SDL_Window);
 	depth = GetDeviceCaps(hdc, PLANES) * GetDeviceCaps(hdc, BITSPIXEL);
 	ReleaseDC(SDL_Window, hdc);
-#ifndef _WIN32_WCE
-	// AFAIK 16 bit CE devices have indeed RGB 565
-	if ( depth == 16 ) {
-		depth = 15;	/* GDI defined as RGB 555 */
-	}
-#endif
 	return(depth);
 #else
     int dib_size;
@@ -518,23 +516,18 @@
 	video->h = height;
 	video->pitch = SDL_CalculatePitch(video);
 
-#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);
-		}
+	/* Small fix for WinCE/Win32 - when activating window
+	   SDL_VideoSurface is equal to zero, so activating code
+	   is not called properly for fullscreen windows because
+	   macros WINDIB_FULLSCREEN uses SDL_VideoSurface
+	*/
+	SDL_VideoSurface = video;
+
+#if defined(_WIN32_WCE)
+	if ( flags & SDL_FULLSCREEN )
 		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);
-		}
-	}
 #endif
+
 #ifndef NO_CHANGEDISPLAYSETTINGS
 	/* Set fullscreen mode if appropriate */
 	if ( (flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
@@ -942,14 +935,6 @@
 	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);
-				SHFullScreen(SDL_Window, SHFS_SHOWSIPBUTTON);
-				ShowWindow(FindWindow(TEXT("HHTaskBar"),NULL),SW_SHOWNORMAL);
-			}
-#endif
 #ifndef NO_CHANGEDISPLAYSETTINGS
 			if ( this->screen->flags & SDL_FULLSCREEN ) {
 				ChangeDisplaySettings(NULL, 0);
@@ -975,6 +960,17 @@
 		FlushMessageQueue();
 
 		SDL_Window = NULL;
+
+#if defined(_WIN32_WCE)
+
+// Unload wince aygshell library to prevent leak
+		if( aygshell ) 
+		{
+			FreeLibrary(aygshell);
+			aygshell = NULL;
+		}
+#endif
+
 	}
 }
 
--- a/test/testalpha.c	Wed Sep 28 11:36:20 2005 +0000
+++ b/test/testalpha.c	Thu Sep 29 09:43:00 2005 +0000
@@ -339,12 +339,20 @@
 	}
 
 	/* Set 640x480 video mode */
+#ifndef _WIN32_WCE
 	if ( (screen=SDL_SetVideoMode(640,480,video_bpp,videoflags)) == NULL ) {
 		fprintf(stderr, "Couldn't set 640x480x%d video mode: %s\n",
 						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
 	/* Set the surface pixels and refresh! */
 	if ( SDL_LockSurface(screen) < 0 ) {
 		fprintf(stderr, "Couldn't lock the display surface: %s\n",
--- a/test/testwin.c	Wed Sep 28 11:36:20 2005 +0000
+++ b/test/testwin.c	Thu Sep 29 09:43:00 2005 +0000
@@ -248,11 +248,18 @@
 	flip = 0;
 	nofade = 0;
 	delay = 1;
+
+#ifdef _WIN32_WCE
+	w = 640;
+	h = 320;
+	desired_bpp = 0;
+	video_flags = SDL_FULLSCREEN;
+#else
 	w = 640;
 	h = 480;
 	desired_bpp = 0;
 	video_flags = 0;
-
+#endif
 	if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
 		fprintf(stderr,
 			"Couldn't initialize SDL: %s\n", SDL_GetError());