Windows CE patches contributed by Rainer Loritz
authorSam Lantinga <slouken@lokigames.com>
Wed, 23 May 2001 23:35:10 +0000
changeset 36 13ee9f4834ea
parent 35 d3bc792e136d
child 37 3ad7157c6cfa
Windows CE patches contributed by Rainer Loritz
src/SDL.c
src/audio/windib/SDL_dibaudio.c
src/file/SDL_rwops.c
src/main/win32/SDL_main.c
src/thread/win32/SDL_syssem.c
src/thread/win32/win_ce_semaphore.c
src/thread/win32/win_ce_semaphore.h
src/video/wincommon/SDL_sysevents.c
src/video/wincommon/SDL_syswm.c
src/video/windib/SDL_dibevents.c
src/video/windib/SDL_dibvideo.c
--- a/src/SDL.c	Wed May 23 00:36:17 2001 +0000
+++ b/src/SDL.c	Wed May 23 23:35:10 2001 +0000
@@ -231,3 +231,21 @@
 	return(&version);
 }
 
+#if defined(_WIN32_WCE)
+/* Need to include DllMain() on Windows CE for some reason.. */
+#include <windows.h>
+
+BOOL APIENTRY DllMain( HANDLE hModule, 
+                       DWORD  ul_reason_for_call, 
+                       LPVOID lpReserved )
+{
+	switch (ul_reason_for_call) {
+		case DLL_PROCESS_ATTACH:
+		case DLL_THREAD_ATTACH:
+		case DLL_THREAD_DETACH:
+		case DLL_PROCESS_DETACH:
+			break;
+	}
+	return TRUE;
+}
+#endif /* _WIN32_WCE */
--- a/src/audio/windib/SDL_dibaudio.c	Wed May 23 00:36:17 2001 +0000
+++ b/src/audio/windib/SDL_dibaudio.c	Wed May 23 23:35:10 2001 +0000
@@ -37,6 +37,9 @@
 #include "SDL_timer.h"
 #include "SDL_audio_c.h"
 #include "SDL_dibaudio.h"
+#if defined(_WIN32_WCE) && (_WIN32_WCE < 300)
+#include "win_ce_semaphore.h"
+#endif
 
 
 /* Audio driver functions */
@@ -112,18 +115,33 @@
 		return;
 
 	/* Signal that we are done playing a buffer */
+#if defined(_WIN32_WCE) && (_WIN32_WCE < 300)
+	ReleaseSemaphoreCE(audio_sem, 1, NULL);
+#else
 	ReleaseSemaphore(audio_sem, 1, NULL);
+#endif
 }
 
 static void SetMMerror(char *function, MMRESULT code)
 {
 	int len;
 	char errbuf[MAXERRORLENGTH];
+#ifdef _WIN32_WCE
+	wchar_t werrbuf[MAXERRORLENGTH];
+#endif
 
 	sprintf(errbuf, "%s: ", function);
 	len = strlen(errbuf);
+
+#ifdef _WIN32_WCE
+	/* UNICODE version */
+	waveOutGetErrorText(code, werrbuf, MAXERRORLENGTH-len);
+	WideCharToMultiByte(CP_ACP,0,werrbuf,-1,errbuf+len,MAXERRORLENGTH-len,NULL,NULL);
+#else
 	waveOutGetErrorText(code, errbuf+len, MAXERRORLENGTH-len);
-	SDL_SetError("%s", errbuf);
+#endif
+
+	SDL_SetError("%s",errbuf);
 }
 
 /* Set high priority for the audio thread */
@@ -135,7 +153,11 @@
 void DIB_WaitAudio(_THIS)
 {
 	/* Wait for an audio chunk to finish */
+#if defined(_WIN32_WCE) && (_WIN32_WCE < 300)
+	WaitForSemaphoreCE(audio_sem, INFINITE);
+#else
 	WaitForSingleObject(audio_sem, INFINITE);
+#endif
 }
 
 Uint8 *DIB_GetAudioBuf(_THIS)
@@ -176,7 +198,11 @@
 
 	/* Close up audio */
 	if ( audio_sem ) {
+#if defined(_WIN32_WCE) && (_WIN32_WCE < 300)
+		CloseSynchHandle(audio_sem);
+#else
 		CloseHandle(audio_sem);
+#endif
 	}
 	if ( sound ) {
 		waveOutClose(sound);
@@ -267,7 +293,11 @@
 #endif
 
 	/* Create the audio buffer semaphore */
+#if defined(_WIN32_WCE) && (_WIN32_WCE < 300)
+	audio_sem = CreateSemaphoreCE(NULL, NUM_BUFFERS-1, NUM_BUFFERS, NULL);
+#else
 	audio_sem = CreateSemaphore(NULL, NUM_BUFFERS-1, NUM_BUFFERS, NULL);
+#endif
 	if ( audio_sem == NULL ) {
 		SDL_SetError("Couldn't create semaphore");
 		return(-1);
--- a/src/file/SDL_rwops.c	Wed May 23 00:36:17 2001 +0000
+++ b/src/file/SDL_rwops.c	Wed May 23 23:35:10 2001 +0000
@@ -30,6 +30,7 @@
 */
 
 #include <stdlib.h>
+#include <stdio.h>
 #include <string.h>
 
 #include "SDL_error.h"
--- a/src/main/win32/SDL_main.c	Wed May 23 00:36:17 2001 +0000
+++ b/src/main/win32/SDL_main.c	Wed May 23 23:35:10 2001 +0000
@@ -19,9 +19,40 @@
 #undef main
 #endif
 
+/* Do we really not want stdio redirection with Windows CE? */
+#ifdef _WIN32_WCE
+#define NO_STDIO_REDIRECT
+#endif
+
 /* The standard output files */
-#define STDOUT_FILE	"stdout.txt"
-#define STDERR_FILE	"stderr.txt"
+#define STDOUT_FILE	TEXT("stdout.txt")
+#define STDERR_FILE	TEXT("stderr.txt")
+
+#ifdef _WIN32_WCE
+/* 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 *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 */
 
 /* Parse a command line buffer into arguments */
 static int ParseCommandLine(char *cmdline, char **argv)
@@ -92,15 +123,18 @@
 }
 
 /* Remove the output files if there was no output written */
-static void cleanup_output(void)
+static void __cdecl cleanup_output(void)
 {
+#ifndef NO_STDIO_REDIRECT
 	FILE *file;
 	int empty;
+#endif
 
 	/* Flush the output in case anything is queued */
 	fclose(stdout);
 	fclose(stderr);
 
+#ifndef NO_STDIO_REDIRECT
 	/* See if the files have any output in them */
 	file = fopen(STDOUT_FILE, "rb");
 	if ( file ) {
@@ -118,9 +152,11 @@
 			remove(STDERR_FILE);
 		}
 	}
+#endif
 }
 
-#ifdef _MSC_VER /* The VC++ compiler needs main defined */
+#if defined(_MSC_VER) && !defined(_WIN32_WCE)
+/* The VC++ compiler needs main defined */
 #define console_main main
 #endif
 
@@ -177,13 +213,22 @@
 }
 
 /* This is where execution begins [windowed apps] */
+#ifdef _WIN32_WCE
+int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPWSTR szCmdLine, int sw)
+#else
 int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw)
+#endif
 {
 	HINSTANCE handle;
 	char **argv;
 	int argc;
 	char *cmdline;
+#ifdef _WIN32_WCE
+	wchar_t *bufp;
+	int nLen;
+#else
 	char *bufp;
+#endif
 #ifndef NO_STDIO_REDIRECT
 	FILE *newfp;
 #endif
@@ -192,7 +237,7 @@
 	   keep them open.  This is a hack.. hopefully it will be fixed 
 	   someday.  DDHELP.EXE starts up the first time DDRAW.DLL is loaded.
 	 */
-	handle = LoadLibrary("DDRAW.DLL");
+	handle = LoadLibrary(TEXT("DDRAW.DLL"));
 	if ( handle != NULL ) {
 		FreeLibrary(handle);
 	}
@@ -225,6 +270,18 @@
 	setbuf(stderr, NULL);			/* No buffering */
 #endif /* !NO_STDIO_REDIRECT */
 
+#ifdef _WIN32_WCE
+	nLen = wcslen(szCmdLine)+128+1;
+	bufp = (wchar_t *)alloca(nLen*2);
+	GetModuleFileName(NULL, bufp, 128);
+	wcsncpy(bufp+wcslen(bufp), szCmdLine,nLen);
+	nLen = wcslen(bufp)+1;
+	cmdline = (char *)alloca(nLen);
+	if ( cmdline == NULL ) {
+		return OutOfMemory();
+	}
+	WideCharToMultiByte(CP_ACP, 0, bufp, -1, cmdline, nLen, NULL, NULL);
+#else
 	/* Grab the command line (use alloca() on Windows) */
 	bufp = GetCommandLine();
 	cmdline = (char *)alloca(strlen(bufp)+1);
@@ -232,6 +289,7 @@
 		return OutOfMemory();
 	}
 	strcpy(cmdline, bufp);
+#endif
 
 	/* Parse it into argv and argc */
 	argc = ParseCommandLine(cmdline, NULL);
--- a/src/thread/win32/SDL_syssem.c	Wed May 23 00:36:17 2001 +0000
+++ b/src/thread/win32/SDL_syssem.c	Wed May 23 23:35:10 2001 +0000
@@ -33,56 +33,17 @@
 
 #include "SDL_error.h"
 #include "SDL_thread.h"
-
 #if defined(_WIN32_WCE) && (_WIN32_WCE < 300)
-
-/* No semaphores on Windows CE earlier than 3.0, hmm... */
-
-/* Create a semaphore */
-SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
-{
-	SDL_SetError("Semaphores not supported on WinCE");
-	return(NULL);
-}
-
-/* Free the semaphore */
-void SDL_DestroySemaphore(SDL_sem *sem)
-{
-	return;
-}
-
-int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
-{
-	SDL_SetError("Semaphores not supported on WinCE");
-	return(-1);
-}
+#include "win_ce_semaphore.h"
+#endif
 
-int SDL_SemTryWait(SDL_sem *sem)
-{
-	return SDL_SemWaitTimeout(sem, 0);
-}
-
-int SDL_SemWait(SDL_sem *sem)
-{
-	return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
-}
-
-/* Returns the current count of the semaphore */
-Uint32 SDL_SemValue(SDL_sem *sem)
-{
-	return(0);
-}
-
-int SDL_SemPost(SDL_sem *sem)
-{
-	SDL_SetError("Semaphores not supported on WinCE");
-	return(-1);
-}
-
-#else
 
 struct SDL_semaphore {
+#if defined(_WIN32_WCE) && (_WIN32_WCE < 300)
+	SYNCHHANDLE id;
+#else
 	HANDLE id;
+#endif
 	Uint32 volatile count;
 };
 
@@ -96,7 +57,11 @@
 	sem = (SDL_sem *)malloc(sizeof(*sem));
 	if ( sem ) {
 		/* Create the semaphore, with max value 32K */
+#if defined(_WIN32_WCE) && (_WIN32_WCE < 300)
+		sem->id = CreateSemaphoreCE(NULL, initial_value, 32*1024, NULL);
+#else
 		sem->id = CreateSemaphore(NULL, initial_value, 32*1024, NULL);
+#endif
 		sem->count = initial_value;
 		if ( ! sem->id ) {
 			SDL_SetError("Couldn't create semaphore");
@@ -114,7 +79,11 @@
 {
 	if ( sem ) {
 		if ( sem->id ) {
+#if defined(_WIN32_WCE) && (_WIN32_WCE < 300)
+			CloseSynchHandle(sem->id);
+#else
 			CloseHandle(sem->id);
+#endif
 			sem->id = 0;
 		}
 		free(sem);
@@ -136,7 +105,11 @@
 	} else {
 		dwMilliseconds = (DWORD)timeout;
 	}
+#if defined(_WIN32_WCE) && (_WIN32_WCE < 300)
+	switch (WaitForSemaphoreCE(sem->id, dwMilliseconds)) {
+#else
 	switch (WaitForSingleObject(sem->id, dwMilliseconds)) {
+#endif
 	    case WAIT_OBJECT_0:
 		--sem->count;
 		retval = 0;
@@ -184,12 +157,14 @@
 	 * is waiting for this semaphore.
 	 */
 	++sem->count;
+#if defined(_WIN32_WCE) && (_WIN32_WCE < 300)
+	if ( ReleaseSemaphoreCE(sem->id, 1, NULL) == FALSE ) {
+#else
 	if ( ReleaseSemaphore(sem->id, 1, NULL) == FALSE ) {
+#endif
 		--sem->count;	/* restore */
 		SDL_SetError("ReleaseSemaphore() failed");
 		return -1;
 	}
 	return 0;
 }
-
-#endif /* _WIN32_WCE */
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/thread/win32/win_ce_semaphore.c	Wed May 23 23:35:10 2001 +0000
@@ -0,0 +1,214 @@
+/* win_ce_semaphore.c
+
+   Copyright (c) 1998, Johnson M. Hart
+   (with corrections 2001 by Rainer Loritz)
+   Permission is granted for any and all use providing that this
+   copyright is properly acknowledged.
+   There are no assurances of suitability for any use whatsoever.
+
+   WINDOWS CE: There is a collection of Windows CE functions to simulate
+   semaphores using only a mutex and an event. As Windows CE events cannot
+   be named, these simulated semaphores cannot be named either.
+
+   Implementation notes:
+   1. All required internal data structures are allocated on the process's heap.
+   2. Where appropriate, a new error code is returned (see the header
+      file), or, if the error is a Win32 error, that code is unchanged.
+   3. Notice the new handle type "SYNCHHANDLE" that has handles, counters,
+      and other information. This structure will grow as new objects are added
+      to this set; some members are specific to only one or two of the objects.
+   4. Mutexes are used for critical sections. These could be replaced with
+      CRITICAL_SECTION objects but then this would give up the time out
+      capability.
+   5. The implementation shows several interesting aspects of synchronization, some
+      of which are specific to Win32 and some of which are general. These are pointed
+      out in the comments as appropriate.
+   6. The wait function emulates WaitForSingleObject only. An emulation of
+      WaitForMultipleObjects is much harder to implement outside the kernel,
+      and it is not clear how to handle a mixture of WCE semaphores and normal
+      events and mutexes. */
+
+#include <windows.h>
+#include "win_ce_semaphore.h"
+
+static SYNCHHANDLE CleanUp (SYNCHHANDLE hSynch, DWORD Flags);
+
+SYNCHHANDLE CreateSemaphoreCE (
+
+   LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,  /* pointer to security attributes */
+      LONG lInitialCount,   /* initial count */
+      LONG lMaximumCount,   /* maximum count */
+      LPCTSTR lpName )
+
+/* Semaphore for use with Windows CE that does not support them directly.
+   Requires a counter, a mutex to protect the counter, and an
+   autoreset event.
+
+   Here are the rules that must always hold between the autoreset event
+   and the mutex (any violation of these rules by the CE semaphore functions
+   will, in all likelihood, result in a defect):
+    1. No thread can set, pulse, or reset the event,
+       nor can it access any part of the SYNCHHANDLE structure,
+       without first gaining ownership of the mutex.
+       BUT, a thread can wait on the event without owning the mutex
+       (this is clearly necessary or else the event could never be set).
+    2. The event is in a signaled state if and only if the current semaphore
+       count ("CurCount") is greater than zero.
+    3. The semaphore count is always >= 0 and <= the maximum count */
+
+{
+   SYNCHHANDLE hSynch = NULL, result = NULL;
+
+   __try
+	{
+      if (lInitialCount > lMaximumCount || lMaximumCount < 0 || lInitialCount < 0) 
+	  {
+              /* Bad parameters */
+         SetLastError (SYNCH_ERROR);
+         __leave;
+      }
+
+      hSynch = HeapAlloc (GetProcessHeap(), HEAP_ZERO_MEMORY, SYNCH_HANDLE_SIZE);
+      if (hSynch == NULL) __leave;
+
+      hSynch->MaxCount = lMaximumCount;
+      hSynch->CurCount = lInitialCount;
+      hSynch->lpName = lpName;
+
+      hSynch->hMutex = CreateMutex (lpSemaphoreAttributes, FALSE, NULL);
+
+      WaitForSingleObject (hSynch->hMutex, INFINITE);
+      /*  Create the event. It is initially signaled if and only if the
+          initial count is > 0 */
+      hSynch->hEvent = CreateEvent (lpSemaphoreAttributes, FALSE, 
+              lInitialCount > 0, NULL);
+      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. */
+      result=CleanUp(hSynch, 6 /* An event and a mutex, but no semaphore. */);
+   }
+
+   return result;
+}
+
+BOOL ReleaseSemaphoreCE (SYNCHHANDLE hSemCE, LONG cReleaseCount, LPLONG lpPreviousCount)
+/* Windows CE equivalent to ReleaseSemaphore. */
+{
+   BOOL Result = TRUE;
+
+   /* Gain access to the object to assure that the release count
+      would not cause the total count to exceed the maximum. */
+
+   __try 
+   {
+      WaitForSingleObject (hSemCE->hMutex, INFINITE);
+	  /* reply only if asked to */	
+	  if (lpPreviousCount!=NULL)
+		 *lpPreviousCount = hSemCE->CurCount;
+      if (hSemCE->CurCount + cReleaseCount > hSemCE->MaxCount || cReleaseCount <= 0)
+	  {
+         SetLastError (SYNCH_ERROR);
+         Result = FALSE;
+         __leave;
+      }
+      hSemCE->CurCount += cReleaseCount;
+
+      /*  Set the autoreset event, releasing exactly one waiting thread, now or
+          in the future.  */
+
+      SetEvent (hSemCE->hEvent);
+   }
+   __finally
+   {
+      ReleaseMutex (hSemCE->hMutex);
+   }
+
+   return Result;
+}
+
+DWORD WaitForSemaphoreCE (SYNCHHANDLE hSemCE, DWORD dwMilliseconds)
+   /* Windows CE semaphore equivalent of WaitForSingleObject. */
+{
+   DWORD WaitResult;
+
+   WaitResult = WaitForSingleObject (hSemCE->hMutex, dwMilliseconds);
+   if (WaitResult != WAIT_OBJECT_0 && WaitResult != WAIT_ABANDONED_0) return WaitResult;
+   while (hSemCE->CurCount <= 0) 
+   { 
+
+      /* The count is 0, and the thread must wait on the event (which, by
+         the rules, is currently reset) for semaphore resources to become
+         available. First, of course, the mutex must be released so that another
+         thread will be capable of setting the event. */
+
+      ReleaseMutex (hSemCE->hMutex);
+
+      /*  Wait for the event to be signaled, indicating a semaphore state change.
+          The event is autoreset and signaled with a SetEvent (not PulseEvent)
+          so exactly one waiting thread (whether or not there is currently
+          a waiting thread) is released as a result of the SetEvent. */
+
+      WaitResult = WaitForSingleObject (hSemCE->hEvent, dwMilliseconds);
+      if (WaitResult != WAIT_OBJECT_0) return WaitResult;
+
+      /*  This is where the properties of setting of an autoreset event is critical
+          to assure that, even if the semaphore state changes between the
+          preceding Wait and the next, and even if NO threads are waiting
+          on the event at the time of the SetEvent, at least one thread
+          will be released. 
+          Pulsing a manual reset event would appear to work, but it would have
+          a defect which could appear if the semaphore state changed between
+          the two waits. */
+
+      WaitResult = WaitForSingleObject (hSemCE->hMutex, dwMilliseconds);
+      if (WaitResult != WAIT_OBJECT_0 && WaitResult != WAIT_ABANDONED_0) return WaitResult;
+
+   }
+   /* The count is not zero and this thread owns the mutex.  */
+
+   hSemCE->CurCount--;
+   /* The event is now unsignaled, BUT, the semaphore count may not be
+      zero, in which case the event should be signaled again
+      before releasing the mutex. */
+
+   if (hSemCE->CurCount > 0) SetEvent (hSemCE->hEvent);
+   ReleaseMutex (hSemCE->hMutex);
+   return WaitResult;
+}
+
+BOOL CloseSynchHandle (SYNCHHANDLE hSynch)
+/* Close a synchronization handle. 
+   Improvement: Test for a valid handle before dereferencing the handle. */
+{
+   BOOL Result = TRUE;
+   if (hSynch->hEvent != NULL) Result = Result && CloseHandle (hSynch->hEvent);
+   if (hSynch->hMutex != NULL) Result = Result && CloseHandle (hSynch->hMutex);
+   if (hSynch->hSemph != NULL) Result = Result && CloseHandle (hSynch->hSemph);
+   HeapFree (GetProcessHeap (), 0, hSynch);
+   return (Result);
+}
+
+static SYNCHHANDLE CleanUp (SYNCHHANDLE hSynch, DWORD Flags)
+{ /* Prepare to return from a create of a synchronization handle.
+     If there was any failure, free any allocated resources.
+     "Flags" indicates which Win32 objects are required in the 
+     synchronization handle. */
+
+   BOOL ok = TRUE;
+
+   if (hSynch == NULL) return NULL;
+   if (Flags & 4 == 1 && hSynch->hEvent == NULL) ok = FALSE;
+   if (Flags & 2 == 1 && hSynch->hMutex == NULL) ok = FALSE;
+   if (Flags & 1 == 1 && hSynch->hEvent == NULL) ok = FALSE;
+   if (!ok) 
+   {
+      CloseSynchHandle (hSynch);
+      return NULL;
+   }
+   /* Everything worked */
+   return hSynch;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/thread/win32/win_ce_semaphore.h	Wed May 23 23:35:10 2001 +0000
@@ -0,0 +1,22 @@
+/* win_ce_semaphore.h - header file to go with win_ce_semaphore.c */
+
+typedef struct _SYNCH_HANDLE_STRUCTURE {
+   HANDLE hEvent;
+   HANDLE hMutex;
+   HANDLE hSemph;
+   LONG MaxCount;
+   volatile LONG CurCount;
+   LPCTSTR lpName;
+} SYNCH_HANDLE_STRUCTURE, *SYNCHHANDLE;
+
+#define SYNCH_HANDLE_SIZE sizeof (SYNCH_HANDLE_STRUCTURE)
+
+        /* Error codes - all must have bit 29 set */
+#define SYNCH_ERROR 0X20000000   /* EXERCISE - REFINE THE ERROR NUMBERS */
+
+extern SYNCHHANDLE CreateSemaphoreCE (LPSECURITY_ATTRIBUTES, LONG, LONG, LPCTSTR);
+
+extern BOOL ReleaseSemaphoreCE (SYNCHHANDLE, LONG, LPLONG);
+extern DWORD WaitForSemaphoreCE (SYNCHHANDLE, DWORD);
+
+extern BOOL CloseSynchHandle (SYNCHHANDLE);
--- a/src/video/wincommon/SDL_sysevents.c	Wed May 23 00:36:17 2001 +0000
+++ b/src/video/wincommon/SDL_sysevents.c	Wed May 23 23:35:10 2001 +0000
@@ -496,12 +496,12 @@
 #ifdef _WIN32_WCE
     {
 	/* WinCE uses the UNICODE version */
-	int nLen = strlen(name);
-	LPWSTR lpszW = alloca((nLen+1)*2);
+	int nLen = strlen(name)+1;
+	LPWSTR lpszW = alloca(nLen*2);
 	MultiByteToWideChar(CP_ACP, 0, name, -1, lpszW, nLen);
 	class.hIcon		= LoadImage(hInst, lpszW, IMAGE_ICON,
 	                                    0, 0, LR_DEFAULTCOLOR);
-	class.lpszMenuName	= lpszW;
+	class.lpszMenuName	= NULL;
 	class.lpszClassName	= lpszW;
     }
 #else
--- a/src/video/wincommon/SDL_syswm.c	Wed May 23 00:36:17 2001 +0000
+++ b/src/video/wincommon/SDL_syswm.c	Wed May 23 23:35:10 2001 +0000
@@ -213,8 +213,8 @@
 {
 #ifdef _WIN32_WCE
 	/* WinCE uses the UNICODE version */
-	int nLen = strlen(title);
-	LPWSTR lpszW = alloca((nLen+1)*2);
+	int nLen = strlen(title)+1;
+	LPWSTR lpszW = alloca(nLen*2);
 	MultiByteToWideChar(CP_ACP, 0, title, -1, lpszW, nLen);
 	SetWindowText(SDL_Window, lpszW);
 #else
--- a/src/video/windib/SDL_dibevents.c	Wed May 23 00:36:17 2001 +0000
+++ b/src/video/windib/SDL_dibevents.c	Wed May 23 23:35:10 2001 +0000
@@ -303,14 +303,13 @@
 {
 #ifdef _WIN32_WCE
 	/* WinCE uses the UNICODE version */
-	int nLen = strlen(SDL_Appname);
-	LPWSTR lpszW = alloca((nLen+1)*2);
+	int nLen = strlen(SDL_Appname)+1;
+	LPWSTR lpszW = alloca(nLen*2);
 	MultiByteToWideChar(CP_ACP, 0, SDL_Appname, -1, lpszW, nLen);
 
 	SDL_RegisterApp("SDL_app", 0, 0);
-	SDL_Window = CreateWindow(lpszW, lpszW,
-                        (WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX),
-                                 0, 0, 0, 0, NULL, NULL, SDL_Instance, NULL);
+	SDL_Window = CreateWindow(lpszW, lpszW, WS_VISIBLE,
+                                  0, 0, 0, 0, NULL, NULL, SDL_Instance, NULL);
 	if ( SDL_Window == NULL ) {
 		SDL_SetError("Couldn't create window");
 		return(-1);
--- a/src/video/windib/SDL_dibvideo.c	Wed May 23 00:36:17 2001 +0000
+++ b/src/video/windib/SDL_dibvideo.c	Wed May 23 23:35:10 2001 +0000
@@ -440,8 +440,10 @@
 			(WS_POPUP);
 	const DWORD windowstyle = 
 			(WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX);
+#ifndef _WIN32_WCE
 	const DWORD resizestyle =
 			(WS_THICKFRAME|WS_MAXIMIZEBOX);
+#endif
 	int binfo_size;
 	BITMAPINFO *binfo;
 	HDC hdc;
@@ -453,10 +455,12 @@
 	/* 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 /* HAVE_OPENGL */
 
 	/* Recalculate the bitmasks if necessary */
 	if ( bpp == current->format->BitsPerPixel ) {
@@ -535,7 +539,9 @@
 #endif /* !NO_CHANGEDISPLAYSETTINGS */
 
 	style = GetWindowLong(SDL_Window, GWL_STYLE);
+#ifndef _WIN32_WCE
 	style &= ~(resizestyle|WS_MAXIMIZE);
+#endif
 	if ( (video->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
 		style &= ~windowstyle;
 		style |= directstyle;
@@ -553,11 +559,15 @@
 			style &= ~directstyle;
 			style |= windowstyle;
 			if ( flags & SDL_RESIZABLE ) {
+#ifndef _WIN32_WCE
 				style |= resizestyle;
+#endif
 				video->flags |= SDL_RESIZABLE;
 			}
 		}
+#ifndef _WIN32_WCE
 		if (IsZoomed(SDL_Window)) style |= WS_MAXIMIZE;
+#endif
 	}
 	SetWindowLong(SDL_Window, GWL_STYLE, style);
 
@@ -642,7 +652,11 @@
 		bounds.top = 0;
 		bounds.right = video->w;
 		bounds.bottom = video->h;
+#ifndef _WIN32_WCE
 		AdjustWindowRect(&bounds, GetWindowLong(SDL_Window, GWL_STYLE), FALSE);
+#else
+		AdjustWindowRectEx(&bounds, GetWindowLong(SDL_Window, GWL_STYLE), FALSE,0);
+#endif
 		width = bounds.right-bounds.left;
 		height = bounds.bottom-bounds.top;
 		x = (GetSystemMetrics(SM_CXSCREEN)-width)/2;
@@ -650,7 +664,11 @@
 		if ( y < 0 ) { /* Cover up title bar for more client area */
 			y -= GetSystemMetrics(SM_CYCAPTION)/2;
 		}
+#ifndef _WIN32_WCE
 		swp_flags = (SWP_NOCOPYBITS | SWP_NOZORDER | SWP_SHOWWINDOW);
+#else
+		swp_flags = (SWP_NOZORDER | SWP_SHOWWINDOW);
+#endif
 		if ( was_visible && !(flags & SDL_FULLSCREEN) ) {
 			swp_flags |= SWP_NOMOVE;
 		}
@@ -659,6 +677,7 @@
 		SetForegroundWindow(SDL_Window);
 	}
 
+#ifdef HAVE_OPENGL
 	/* Set up for OpenGL */
 	if ( flags & SDL_OPENGL ) {
 		if ( WIN_GL_SetupWindow(this) < 0 ) {
@@ -666,6 +685,8 @@
 		}
 		video->flags |= SDL_OPENGL;
 	}
+#endif /* HAVE_OPENGL */
+
 	/* We're live! */
 	return(video);
 }
@@ -711,7 +732,11 @@
 {
 	RGBQUAD *pal;
 	int i;
+#ifndef _WIN32_WCE
 	HDC hdc, mdc;
+#else
+	HDC hdc;
+#endif
 
 	/* Update the display palette */
 	hdc = GetDC(SDL_Window);
@@ -723,7 +748,11 @@
 			entries[i].peRed   = colors[i].r;
 			entries[i].peGreen = colors[i].g;
 			entries[i].peBlue  = colors[i].b;
+#ifndef _WIN32_WCE
 			entries[i].peFlags = PC_NOCOLLAPSE;
+else
+			entries[i].peFlags = 0;
+#endif
 		}
 		SetPaletteEntries(screen_pal, firstcolor, ncolors, entries);
 		SelectPalette(hdc, screen_pal, FALSE);
@@ -740,12 +769,14 @@
 	}
 
 	/* Set the DIB palette and update the display */
+#ifndef _WIN32_WCE
 	mdc = CreateCompatibleDC(hdc);
 	SelectObject(mdc, screen_bmp);
 	SetDIBColorTable(mdc, firstcolor, ncolors, pal);
 	BitBlt(hdc, 0, 0, this->screen->w, this->screen->h,
 	       mdc, 0, 0, SRCCOPY);
 	DeleteDC(mdc);
+#endif
 	ReleaseDC(SDL_Window, hdc);
 	return(1);
 }
@@ -857,9 +888,11 @@
 				ChangeDisplaySettings(NULL, 0);
 			}
 #endif
+#ifdef HAVE_OPENGL
 			if ( this->screen->flags & SDL_OPENGL ) {
 				WIN_GL_ShutDown(this);
 			}
+#endif /* HAVE_OPENGL */
 			this->screen->pixels = NULL;
 		}
 		if ( screen_bmp ) {