Windows CE patches contributed by Rainer Loritz
authorSam Lantinga <slouken@lokigames.com>
Wed, 23 May 2001 23:35:10 +0000
changeset 3613ee9f4834ea
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
     1.1 --- a/src/SDL.c	Wed May 23 00:36:17 2001 +0000
     1.2 +++ b/src/SDL.c	Wed May 23 23:35:10 2001 +0000
     1.3 @@ -231,3 +231,21 @@
     1.4  	return(&version);
     1.5  }
     1.6  
     1.7 +#if defined(_WIN32_WCE)
     1.8 +/* Need to include DllMain() on Windows CE for some reason.. */
     1.9 +#include <windows.h>
    1.10 +
    1.11 +BOOL APIENTRY DllMain( HANDLE hModule, 
    1.12 +                       DWORD  ul_reason_for_call, 
    1.13 +                       LPVOID lpReserved )
    1.14 +{
    1.15 +	switch (ul_reason_for_call) {
    1.16 +		case DLL_PROCESS_ATTACH:
    1.17 +		case DLL_THREAD_ATTACH:
    1.18 +		case DLL_THREAD_DETACH:
    1.19 +		case DLL_PROCESS_DETACH:
    1.20 +			break;
    1.21 +	}
    1.22 +	return TRUE;
    1.23 +}
    1.24 +#endif /* _WIN32_WCE */
     2.1 --- a/src/audio/windib/SDL_dibaudio.c	Wed May 23 00:36:17 2001 +0000
     2.2 +++ b/src/audio/windib/SDL_dibaudio.c	Wed May 23 23:35:10 2001 +0000
     2.3 @@ -37,6 +37,9 @@
     2.4  #include "SDL_timer.h"
     2.5  #include "SDL_audio_c.h"
     2.6  #include "SDL_dibaudio.h"
     2.7 +#if defined(_WIN32_WCE) && (_WIN32_WCE < 300)
     2.8 +#include "win_ce_semaphore.h"
     2.9 +#endif
    2.10  
    2.11  
    2.12  /* Audio driver functions */
    2.13 @@ -112,18 +115,33 @@
    2.14  		return;
    2.15  
    2.16  	/* Signal that we are done playing a buffer */
    2.17 +#if defined(_WIN32_WCE) && (_WIN32_WCE < 300)
    2.18 +	ReleaseSemaphoreCE(audio_sem, 1, NULL);
    2.19 +#else
    2.20  	ReleaseSemaphore(audio_sem, 1, NULL);
    2.21 +#endif
    2.22  }
    2.23  
    2.24  static void SetMMerror(char *function, MMRESULT code)
    2.25  {
    2.26  	int len;
    2.27  	char errbuf[MAXERRORLENGTH];
    2.28 +#ifdef _WIN32_WCE
    2.29 +	wchar_t werrbuf[MAXERRORLENGTH];
    2.30 +#endif
    2.31  
    2.32  	sprintf(errbuf, "%s: ", function);
    2.33  	len = strlen(errbuf);
    2.34 +
    2.35 +#ifdef _WIN32_WCE
    2.36 +	/* UNICODE version */
    2.37 +	waveOutGetErrorText(code, werrbuf, MAXERRORLENGTH-len);
    2.38 +	WideCharToMultiByte(CP_ACP,0,werrbuf,-1,errbuf+len,MAXERRORLENGTH-len,NULL,NULL);
    2.39 +#else
    2.40  	waveOutGetErrorText(code, errbuf+len, MAXERRORLENGTH-len);
    2.41 -	SDL_SetError("%s", errbuf);
    2.42 +#endif
    2.43 +
    2.44 +	SDL_SetError("%s",errbuf);
    2.45  }
    2.46  
    2.47  /* Set high priority for the audio thread */
    2.48 @@ -135,7 +153,11 @@
    2.49  void DIB_WaitAudio(_THIS)
    2.50  {
    2.51  	/* Wait for an audio chunk to finish */
    2.52 +#if defined(_WIN32_WCE) && (_WIN32_WCE < 300)
    2.53 +	WaitForSemaphoreCE(audio_sem, INFINITE);
    2.54 +#else
    2.55  	WaitForSingleObject(audio_sem, INFINITE);
    2.56 +#endif
    2.57  }
    2.58  
    2.59  Uint8 *DIB_GetAudioBuf(_THIS)
    2.60 @@ -176,7 +198,11 @@
    2.61  
    2.62  	/* Close up audio */
    2.63  	if ( audio_sem ) {
    2.64 +#if defined(_WIN32_WCE) && (_WIN32_WCE < 300)
    2.65 +		CloseSynchHandle(audio_sem);
    2.66 +#else
    2.67  		CloseHandle(audio_sem);
    2.68 +#endif
    2.69  	}
    2.70  	if ( sound ) {
    2.71  		waveOutClose(sound);
    2.72 @@ -267,7 +293,11 @@
    2.73  #endif
    2.74  
    2.75  	/* Create the audio buffer semaphore */
    2.76 +#if defined(_WIN32_WCE) && (_WIN32_WCE < 300)
    2.77 +	audio_sem = CreateSemaphoreCE(NULL, NUM_BUFFERS-1, NUM_BUFFERS, NULL);
    2.78 +#else
    2.79  	audio_sem = CreateSemaphore(NULL, NUM_BUFFERS-1, NUM_BUFFERS, NULL);
    2.80 +#endif
    2.81  	if ( audio_sem == NULL ) {
    2.82  		SDL_SetError("Couldn't create semaphore");
    2.83  		return(-1);
     3.1 --- a/src/file/SDL_rwops.c	Wed May 23 00:36:17 2001 +0000
     3.2 +++ b/src/file/SDL_rwops.c	Wed May 23 23:35:10 2001 +0000
     3.3 @@ -30,6 +30,7 @@
     3.4  */
     3.5  
     3.6  #include <stdlib.h>
     3.7 +#include <stdio.h>
     3.8  #include <string.h>
     3.9  
    3.10  #include "SDL_error.h"
     4.1 --- a/src/main/win32/SDL_main.c	Wed May 23 00:36:17 2001 +0000
     4.2 +++ b/src/main/win32/SDL_main.c	Wed May 23 23:35:10 2001 +0000
     4.3 @@ -19,9 +19,40 @@
     4.4  #undef main
     4.5  #endif
     4.6  
     4.7 +/* Do we really not want stdio redirection with Windows CE? */
     4.8 +#ifdef _WIN32_WCE
     4.9 +#define NO_STDIO_REDIRECT
    4.10 +#endif
    4.11 +
    4.12  /* The standard output files */
    4.13 -#define STDOUT_FILE	"stdout.txt"
    4.14 -#define STDERR_FILE	"stderr.txt"
    4.15 +#define STDOUT_FILE	TEXT("stdout.txt")
    4.16 +#define STDERR_FILE	TEXT("stderr.txt")
    4.17 +
    4.18 +#ifdef _WIN32_WCE
    4.19 +/* seems to be undefined in Win CE although in online help */
    4.20 +#define isspace(a) (((CHAR)a == ' ') || ((CHAR)a == '\t'))
    4.21 +
    4.22 +/* seems to be undefined in Win CE although in online help */
    4.23 +char *strrchr(char *str, int c)
    4.24 +{
    4.25 +	char *p;
    4.26 +
    4.27 +	/* Skip to the end of the string */
    4.28 +	p=str;
    4.29 +	while (*p)
    4.30 +		p++;
    4.31 +
    4.32 +	/* Look for the given character */
    4.33 +	while ( (p >= str) && (*p != (CHAR)c) )
    4.34 +		p--;
    4.35 +
    4.36 +	/* Return NULL if character not found */
    4.37 +	if ( p < str ) {
    4.38 +		p = NULL;
    4.39 +	}
    4.40 +	return p;
    4.41 +}
    4.42 +#endif /* _WIN32_WCE */
    4.43  
    4.44  /* Parse a command line buffer into arguments */
    4.45  static int ParseCommandLine(char *cmdline, char **argv)
    4.46 @@ -92,15 +123,18 @@
    4.47  }
    4.48  
    4.49  /* Remove the output files if there was no output written */
    4.50 -static void cleanup_output(void)
    4.51 +static void __cdecl cleanup_output(void)
    4.52  {
    4.53 +#ifndef NO_STDIO_REDIRECT
    4.54  	FILE *file;
    4.55  	int empty;
    4.56 +#endif
    4.57  
    4.58  	/* Flush the output in case anything is queued */
    4.59  	fclose(stdout);
    4.60  	fclose(stderr);
    4.61  
    4.62 +#ifndef NO_STDIO_REDIRECT
    4.63  	/* See if the files have any output in them */
    4.64  	file = fopen(STDOUT_FILE, "rb");
    4.65  	if ( file ) {
    4.66 @@ -118,9 +152,11 @@
    4.67  			remove(STDERR_FILE);
    4.68  		}
    4.69  	}
    4.70 +#endif
    4.71  }
    4.72  
    4.73 -#ifdef _MSC_VER /* The VC++ compiler needs main defined */
    4.74 +#if defined(_MSC_VER) && !defined(_WIN32_WCE)
    4.75 +/* The VC++ compiler needs main defined */
    4.76  #define console_main main
    4.77  #endif
    4.78  
    4.79 @@ -177,13 +213,22 @@
    4.80  }
    4.81  
    4.82  /* This is where execution begins [windowed apps] */
    4.83 +#ifdef _WIN32_WCE
    4.84 +int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPWSTR szCmdLine, int sw)
    4.85 +#else
    4.86  int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw)
    4.87 +#endif
    4.88  {
    4.89  	HINSTANCE handle;
    4.90  	char **argv;
    4.91  	int argc;
    4.92  	char *cmdline;
    4.93 +#ifdef _WIN32_WCE
    4.94 +	wchar_t *bufp;
    4.95 +	int nLen;
    4.96 +#else
    4.97  	char *bufp;
    4.98 +#endif
    4.99  #ifndef NO_STDIO_REDIRECT
   4.100  	FILE *newfp;
   4.101  #endif
   4.102 @@ -192,7 +237,7 @@
   4.103  	   keep them open.  This is a hack.. hopefully it will be fixed 
   4.104  	   someday.  DDHELP.EXE starts up the first time DDRAW.DLL is loaded.
   4.105  	 */
   4.106 -	handle = LoadLibrary("DDRAW.DLL");
   4.107 +	handle = LoadLibrary(TEXT("DDRAW.DLL"));
   4.108  	if ( handle != NULL ) {
   4.109  		FreeLibrary(handle);
   4.110  	}
   4.111 @@ -225,6 +270,18 @@
   4.112  	setbuf(stderr, NULL);			/* No buffering */
   4.113  #endif /* !NO_STDIO_REDIRECT */
   4.114  
   4.115 +#ifdef _WIN32_WCE
   4.116 +	nLen = wcslen(szCmdLine)+128+1;
   4.117 +	bufp = (wchar_t *)alloca(nLen*2);
   4.118 +	GetModuleFileName(NULL, bufp, 128);
   4.119 +	wcsncpy(bufp+wcslen(bufp), szCmdLine,nLen);
   4.120 +	nLen = wcslen(bufp)+1;
   4.121 +	cmdline = (char *)alloca(nLen);
   4.122 +	if ( cmdline == NULL ) {
   4.123 +		return OutOfMemory();
   4.124 +	}
   4.125 +	WideCharToMultiByte(CP_ACP, 0, bufp, -1, cmdline, nLen, NULL, NULL);
   4.126 +#else
   4.127  	/* Grab the command line (use alloca() on Windows) */
   4.128  	bufp = GetCommandLine();
   4.129  	cmdline = (char *)alloca(strlen(bufp)+1);
   4.130 @@ -232,6 +289,7 @@
   4.131  		return OutOfMemory();
   4.132  	}
   4.133  	strcpy(cmdline, bufp);
   4.134 +#endif
   4.135  
   4.136  	/* Parse it into argv and argc */
   4.137  	argc = ParseCommandLine(cmdline, NULL);
     5.1 --- a/src/thread/win32/SDL_syssem.c	Wed May 23 00:36:17 2001 +0000
     5.2 +++ b/src/thread/win32/SDL_syssem.c	Wed May 23 23:35:10 2001 +0000
     5.3 @@ -33,56 +33,17 @@
     5.4  
     5.5  #include "SDL_error.h"
     5.6  #include "SDL_thread.h"
     5.7 +#if defined(_WIN32_WCE) && (_WIN32_WCE < 300)
     5.8 +#include "win_ce_semaphore.h"
     5.9 +#endif
    5.10  
    5.11 -#if defined(_WIN32_WCE) && (_WIN32_WCE < 300)
    5.12 -
    5.13 -/* No semaphores on Windows CE earlier than 3.0, hmm... */
    5.14 -
    5.15 -/* Create a semaphore */
    5.16 -SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
    5.17 -{
    5.18 -	SDL_SetError("Semaphores not supported on WinCE");
    5.19 -	return(NULL);
    5.20 -}
    5.21 -
    5.22 -/* Free the semaphore */
    5.23 -void SDL_DestroySemaphore(SDL_sem *sem)
    5.24 -{
    5.25 -	return;
    5.26 -}
    5.27 -
    5.28 -int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
    5.29 -{
    5.30 -	SDL_SetError("Semaphores not supported on WinCE");
    5.31 -	return(-1);
    5.32 -}
    5.33 -
    5.34 -int SDL_SemTryWait(SDL_sem *sem)
    5.35 -{
    5.36 -	return SDL_SemWaitTimeout(sem, 0);
    5.37 -}
    5.38 -
    5.39 -int SDL_SemWait(SDL_sem *sem)
    5.40 -{
    5.41 -	return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
    5.42 -}
    5.43 -
    5.44 -/* Returns the current count of the semaphore */
    5.45 -Uint32 SDL_SemValue(SDL_sem *sem)
    5.46 -{
    5.47 -	return(0);
    5.48 -}
    5.49 -
    5.50 -int SDL_SemPost(SDL_sem *sem)
    5.51 -{
    5.52 -	SDL_SetError("Semaphores not supported on WinCE");
    5.53 -	return(-1);
    5.54 -}
    5.55 -
    5.56 -#else
    5.57  
    5.58  struct SDL_semaphore {
    5.59 +#if defined(_WIN32_WCE) && (_WIN32_WCE < 300)
    5.60 +	SYNCHHANDLE id;
    5.61 +#else
    5.62  	HANDLE id;
    5.63 +#endif
    5.64  	Uint32 volatile count;
    5.65  };
    5.66  
    5.67 @@ -96,7 +57,11 @@
    5.68  	sem = (SDL_sem *)malloc(sizeof(*sem));
    5.69  	if ( sem ) {
    5.70  		/* Create the semaphore, with max value 32K */
    5.71 +#if defined(_WIN32_WCE) && (_WIN32_WCE < 300)
    5.72 +		sem->id = CreateSemaphoreCE(NULL, initial_value, 32*1024, NULL);
    5.73 +#else
    5.74  		sem->id = CreateSemaphore(NULL, initial_value, 32*1024, NULL);
    5.75 +#endif
    5.76  		sem->count = initial_value;
    5.77  		if ( ! sem->id ) {
    5.78  			SDL_SetError("Couldn't create semaphore");
    5.79 @@ -114,7 +79,11 @@
    5.80  {
    5.81  	if ( sem ) {
    5.82  		if ( sem->id ) {
    5.83 +#if defined(_WIN32_WCE) && (_WIN32_WCE < 300)
    5.84 +			CloseSynchHandle(sem->id);
    5.85 +#else
    5.86  			CloseHandle(sem->id);
    5.87 +#endif
    5.88  			sem->id = 0;
    5.89  		}
    5.90  		free(sem);
    5.91 @@ -136,7 +105,11 @@
    5.92  	} else {
    5.93  		dwMilliseconds = (DWORD)timeout;
    5.94  	}
    5.95 +#if defined(_WIN32_WCE) && (_WIN32_WCE < 300)
    5.96 +	switch (WaitForSemaphoreCE(sem->id, dwMilliseconds)) {
    5.97 +#else
    5.98  	switch (WaitForSingleObject(sem->id, dwMilliseconds)) {
    5.99 +#endif
   5.100  	    case WAIT_OBJECT_0:
   5.101  		--sem->count;
   5.102  		retval = 0;
   5.103 @@ -184,12 +157,14 @@
   5.104  	 * is waiting for this semaphore.
   5.105  	 */
   5.106  	++sem->count;
   5.107 +#if defined(_WIN32_WCE) && (_WIN32_WCE < 300)
   5.108 +	if ( ReleaseSemaphoreCE(sem->id, 1, NULL) == FALSE ) {
   5.109 +#else
   5.110  	if ( ReleaseSemaphore(sem->id, 1, NULL) == FALSE ) {
   5.111 +#endif
   5.112  		--sem->count;	/* restore */
   5.113  		SDL_SetError("ReleaseSemaphore() failed");
   5.114  		return -1;
   5.115  	}
   5.116  	return 0;
   5.117  }
   5.118 -
   5.119 -#endif /* _WIN32_WCE */
   5.120 \ No newline at end of file
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/src/thread/win32/win_ce_semaphore.c	Wed May 23 23:35:10 2001 +0000
     6.3 @@ -0,0 +1,214 @@
     6.4 +/* win_ce_semaphore.c
     6.5 +
     6.6 +   Copyright (c) 1998, Johnson M. Hart
     6.7 +   (with corrections 2001 by Rainer Loritz)
     6.8 +   Permission is granted for any and all use providing that this
     6.9 +   copyright is properly acknowledged.
    6.10 +   There are no assurances of suitability for any use whatsoever.
    6.11 +
    6.12 +   WINDOWS CE: There is a collection of Windows CE functions to simulate
    6.13 +   semaphores using only a mutex and an event. As Windows CE events cannot
    6.14 +   be named, these simulated semaphores cannot be named either.
    6.15 +
    6.16 +   Implementation notes:
    6.17 +   1. All required internal data structures are allocated on the process's heap.
    6.18 +   2. Where appropriate, a new error code is returned (see the header
    6.19 +      file), or, if the error is a Win32 error, that code is unchanged.
    6.20 +   3. Notice the new handle type "SYNCHHANDLE" that has handles, counters,
    6.21 +      and other information. This structure will grow as new objects are added
    6.22 +      to this set; some members are specific to only one or two of the objects.
    6.23 +   4. Mutexes are used for critical sections. These could be replaced with
    6.24 +      CRITICAL_SECTION objects but then this would give up the time out
    6.25 +      capability.
    6.26 +   5. The implementation shows several interesting aspects of synchronization, some
    6.27 +      of which are specific to Win32 and some of which are general. These are pointed
    6.28 +      out in the comments as appropriate.
    6.29 +   6. The wait function emulates WaitForSingleObject only. An emulation of
    6.30 +      WaitForMultipleObjects is much harder to implement outside the kernel,
    6.31 +      and it is not clear how to handle a mixture of WCE semaphores and normal
    6.32 +      events and mutexes. */
    6.33 +
    6.34 +#include <windows.h>
    6.35 +#include "win_ce_semaphore.h"
    6.36 +
    6.37 +static SYNCHHANDLE CleanUp (SYNCHHANDLE hSynch, DWORD Flags);
    6.38 +
    6.39 +SYNCHHANDLE CreateSemaphoreCE (
    6.40 +
    6.41 +   LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,  /* pointer to security attributes */
    6.42 +      LONG lInitialCount,   /* initial count */
    6.43 +      LONG lMaximumCount,   /* maximum count */
    6.44 +      LPCTSTR lpName )
    6.45 +
    6.46 +/* Semaphore for use with Windows CE that does not support them directly.
    6.47 +   Requires a counter, a mutex to protect the counter, and an
    6.48 +   autoreset event.
    6.49 +
    6.50 +   Here are the rules that must always hold between the autoreset event
    6.51 +   and the mutex (any violation of these rules by the CE semaphore functions
    6.52 +   will, in all likelihood, result in a defect):
    6.53 +    1. No thread can set, pulse, or reset the event,
    6.54 +       nor can it access any part of the SYNCHHANDLE structure,
    6.55 +       without first gaining ownership of the mutex.
    6.56 +       BUT, a thread can wait on the event without owning the mutex
    6.57 +       (this is clearly necessary or else the event could never be set).
    6.58 +    2. The event is in a signaled state if and only if the current semaphore
    6.59 +       count ("CurCount") is greater than zero.
    6.60 +    3. The semaphore count is always >= 0 and <= the maximum count */
    6.61 +
    6.62 +{
    6.63 +   SYNCHHANDLE hSynch = NULL, result = NULL;
    6.64 +
    6.65 +   __try
    6.66 +	{
    6.67 +      if (lInitialCount > lMaximumCount || lMaximumCount < 0 || lInitialCount < 0) 
    6.68 +	  {
    6.69 +              /* Bad parameters */
    6.70 +         SetLastError (SYNCH_ERROR);
    6.71 +         __leave;
    6.72 +      }
    6.73 +
    6.74 +      hSynch = HeapAlloc (GetProcessHeap(), HEAP_ZERO_MEMORY, SYNCH_HANDLE_SIZE);
    6.75 +      if (hSynch == NULL) __leave;
    6.76 +
    6.77 +      hSynch->MaxCount = lMaximumCount;
    6.78 +      hSynch->CurCount = lInitialCount;
    6.79 +      hSynch->lpName = lpName;
    6.80 +
    6.81 +      hSynch->hMutex = CreateMutex (lpSemaphoreAttributes, FALSE, NULL);
    6.82 +
    6.83 +      WaitForSingleObject (hSynch->hMutex, INFINITE);
    6.84 +      /*  Create the event. It is initially signaled if and only if the
    6.85 +          initial count is > 0 */
    6.86 +      hSynch->hEvent = CreateEvent (lpSemaphoreAttributes, FALSE, 
    6.87 +              lInitialCount > 0, NULL);
    6.88 +      ReleaseMutex (hSynch->hMutex);
    6.89 +      hSynch->hSemph = NULL;
    6.90 +   }
    6.91 +   __finally
    6.92 +   {
    6.93 +       /* Return with the handle, or, if there was any error, return
    6.94 +        a null after closing any open handles and freeing any allocated memory. */
    6.95 +      result=CleanUp(hSynch, 6 /* An event and a mutex, but no semaphore. */);
    6.96 +   }
    6.97 +
    6.98 +   return result;
    6.99 +}
   6.100 +
   6.101 +BOOL ReleaseSemaphoreCE (SYNCHHANDLE hSemCE, LONG cReleaseCount, LPLONG lpPreviousCount)
   6.102 +/* Windows CE equivalent to ReleaseSemaphore. */
   6.103 +{
   6.104 +   BOOL Result = TRUE;
   6.105 +
   6.106 +   /* Gain access to the object to assure that the release count
   6.107 +      would not cause the total count to exceed the maximum. */
   6.108 +
   6.109 +   __try 
   6.110 +   {
   6.111 +      WaitForSingleObject (hSemCE->hMutex, INFINITE);
   6.112 +	  /* reply only if asked to */	
   6.113 +	  if (lpPreviousCount!=NULL)
   6.114 +		 *lpPreviousCount = hSemCE->CurCount;
   6.115 +      if (hSemCE->CurCount + cReleaseCount > hSemCE->MaxCount || cReleaseCount <= 0)
   6.116 +	  {
   6.117 +         SetLastError (SYNCH_ERROR);
   6.118 +         Result = FALSE;
   6.119 +         __leave;
   6.120 +      }
   6.121 +      hSemCE->CurCount += cReleaseCount;
   6.122 +
   6.123 +      /*  Set the autoreset event, releasing exactly one waiting thread, now or
   6.124 +          in the future.  */
   6.125 +
   6.126 +      SetEvent (hSemCE->hEvent);
   6.127 +   }
   6.128 +   __finally
   6.129 +   {
   6.130 +      ReleaseMutex (hSemCE->hMutex);
   6.131 +   }
   6.132 +
   6.133 +   return Result;
   6.134 +}
   6.135 +
   6.136 +DWORD WaitForSemaphoreCE (SYNCHHANDLE hSemCE, DWORD dwMilliseconds)
   6.137 +   /* Windows CE semaphore equivalent of WaitForSingleObject. */
   6.138 +{
   6.139 +   DWORD WaitResult;
   6.140 +
   6.141 +   WaitResult = WaitForSingleObject (hSemCE->hMutex, dwMilliseconds);
   6.142 +   if (WaitResult != WAIT_OBJECT_0 && WaitResult != WAIT_ABANDONED_0) return WaitResult;
   6.143 +   while (hSemCE->CurCount <= 0) 
   6.144 +   { 
   6.145 +
   6.146 +      /* The count is 0, and the thread must wait on the event (which, by
   6.147 +         the rules, is currently reset) for semaphore resources to become
   6.148 +         available. First, of course, the mutex must be released so that another
   6.149 +         thread will be capable of setting the event. */
   6.150 +
   6.151 +      ReleaseMutex (hSemCE->hMutex);
   6.152 +
   6.153 +      /*  Wait for the event to be signaled, indicating a semaphore state change.
   6.154 +          The event is autoreset and signaled with a SetEvent (not PulseEvent)
   6.155 +          so exactly one waiting thread (whether or not there is currently
   6.156 +          a waiting thread) is released as a result of the SetEvent. */
   6.157 +
   6.158 +      WaitResult = WaitForSingleObject (hSemCE->hEvent, dwMilliseconds);
   6.159 +      if (WaitResult != WAIT_OBJECT_0) return WaitResult;
   6.160 +
   6.161 +      /*  This is where the properties of setting of an autoreset event is critical
   6.162 +          to assure that, even if the semaphore state changes between the
   6.163 +          preceding Wait and the next, and even if NO threads are waiting
   6.164 +          on the event at the time of the SetEvent, at least one thread
   6.165 +          will be released. 
   6.166 +          Pulsing a manual reset event would appear to work, but it would have
   6.167 +          a defect which could appear if the semaphore state changed between
   6.168 +          the two waits. */
   6.169 +
   6.170 +      WaitResult = WaitForSingleObject (hSemCE->hMutex, dwMilliseconds);
   6.171 +      if (WaitResult != WAIT_OBJECT_0 && WaitResult != WAIT_ABANDONED_0) return WaitResult;
   6.172 +
   6.173 +   }
   6.174 +   /* The count is not zero and this thread owns the mutex.  */
   6.175 +
   6.176 +   hSemCE->CurCount--;
   6.177 +   /* The event is now unsignaled, BUT, the semaphore count may not be
   6.178 +      zero, in which case the event should be signaled again
   6.179 +      before releasing the mutex. */
   6.180 +
   6.181 +   if (hSemCE->CurCount > 0) SetEvent (hSemCE->hEvent);
   6.182 +   ReleaseMutex (hSemCE->hMutex);
   6.183 +   return WaitResult;
   6.184 +}
   6.185 +
   6.186 +BOOL CloseSynchHandle (SYNCHHANDLE hSynch)
   6.187 +/* Close a synchronization handle. 
   6.188 +   Improvement: Test for a valid handle before dereferencing the handle. */
   6.189 +{
   6.190 +   BOOL Result = TRUE;
   6.191 +   if (hSynch->hEvent != NULL) Result = Result && CloseHandle (hSynch->hEvent);
   6.192 +   if (hSynch->hMutex != NULL) Result = Result && CloseHandle (hSynch->hMutex);
   6.193 +   if (hSynch->hSemph != NULL) Result = Result && CloseHandle (hSynch->hSemph);
   6.194 +   HeapFree (GetProcessHeap (), 0, hSynch);
   6.195 +   return (Result);
   6.196 +}
   6.197 +
   6.198 +static SYNCHHANDLE CleanUp (SYNCHHANDLE hSynch, DWORD Flags)
   6.199 +{ /* Prepare to return from a create of a synchronization handle.
   6.200 +     If there was any failure, free any allocated resources.
   6.201 +     "Flags" indicates which Win32 objects are required in the 
   6.202 +     synchronization handle. */
   6.203 +
   6.204 +   BOOL ok = TRUE;
   6.205 +
   6.206 +   if (hSynch == NULL) return NULL;
   6.207 +   if (Flags & 4 == 1 && hSynch->hEvent == NULL) ok = FALSE;
   6.208 +   if (Flags & 2 == 1 && hSynch->hMutex == NULL) ok = FALSE;
   6.209 +   if (Flags & 1 == 1 && hSynch->hEvent == NULL) ok = FALSE;
   6.210 +   if (!ok) 
   6.211 +   {
   6.212 +      CloseSynchHandle (hSynch);
   6.213 +      return NULL;
   6.214 +   }
   6.215 +   /* Everything worked */
   6.216 +   return hSynch;
   6.217 +}
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/src/thread/win32/win_ce_semaphore.h	Wed May 23 23:35:10 2001 +0000
     7.3 @@ -0,0 +1,22 @@
     7.4 +/* win_ce_semaphore.h - header file to go with win_ce_semaphore.c */
     7.5 +
     7.6 +typedef struct _SYNCH_HANDLE_STRUCTURE {
     7.7 +   HANDLE hEvent;
     7.8 +   HANDLE hMutex;
     7.9 +   HANDLE hSemph;
    7.10 +   LONG MaxCount;
    7.11 +   volatile LONG CurCount;
    7.12 +   LPCTSTR lpName;
    7.13 +} SYNCH_HANDLE_STRUCTURE, *SYNCHHANDLE;
    7.14 +
    7.15 +#define SYNCH_HANDLE_SIZE sizeof (SYNCH_HANDLE_STRUCTURE)
    7.16 +
    7.17 +        /* Error codes - all must have bit 29 set */
    7.18 +#define SYNCH_ERROR 0X20000000   /* EXERCISE - REFINE THE ERROR NUMBERS */
    7.19 +
    7.20 +extern SYNCHHANDLE CreateSemaphoreCE (LPSECURITY_ATTRIBUTES, LONG, LONG, LPCTSTR);
    7.21 +
    7.22 +extern BOOL ReleaseSemaphoreCE (SYNCHHANDLE, LONG, LPLONG);
    7.23 +extern DWORD WaitForSemaphoreCE (SYNCHHANDLE, DWORD);
    7.24 +
    7.25 +extern BOOL CloseSynchHandle (SYNCHHANDLE);
     8.1 --- a/src/video/wincommon/SDL_sysevents.c	Wed May 23 00:36:17 2001 +0000
     8.2 +++ b/src/video/wincommon/SDL_sysevents.c	Wed May 23 23:35:10 2001 +0000
     8.3 @@ -496,12 +496,12 @@
     8.4  #ifdef _WIN32_WCE
     8.5      {
     8.6  	/* WinCE uses the UNICODE version */
     8.7 -	int nLen = strlen(name);
     8.8 -	LPWSTR lpszW = alloca((nLen+1)*2);
     8.9 +	int nLen = strlen(name)+1;
    8.10 +	LPWSTR lpszW = alloca(nLen*2);
    8.11  	MultiByteToWideChar(CP_ACP, 0, name, -1, lpszW, nLen);
    8.12  	class.hIcon		= LoadImage(hInst, lpszW, IMAGE_ICON,
    8.13  	                                    0, 0, LR_DEFAULTCOLOR);
    8.14 -	class.lpszMenuName	= lpszW;
    8.15 +	class.lpszMenuName	= NULL;
    8.16  	class.lpszClassName	= lpszW;
    8.17      }
    8.18  #else
     9.1 --- a/src/video/wincommon/SDL_syswm.c	Wed May 23 00:36:17 2001 +0000
     9.2 +++ b/src/video/wincommon/SDL_syswm.c	Wed May 23 23:35:10 2001 +0000
     9.3 @@ -213,8 +213,8 @@
     9.4  {
     9.5  #ifdef _WIN32_WCE
     9.6  	/* WinCE uses the UNICODE version */
     9.7 -	int nLen = strlen(title);
     9.8 -	LPWSTR lpszW = alloca((nLen+1)*2);
     9.9 +	int nLen = strlen(title)+1;
    9.10 +	LPWSTR lpszW = alloca(nLen*2);
    9.11  	MultiByteToWideChar(CP_ACP, 0, title, -1, lpszW, nLen);
    9.12  	SetWindowText(SDL_Window, lpszW);
    9.13  #else
    10.1 --- a/src/video/windib/SDL_dibevents.c	Wed May 23 00:36:17 2001 +0000
    10.2 +++ b/src/video/windib/SDL_dibevents.c	Wed May 23 23:35:10 2001 +0000
    10.3 @@ -303,14 +303,13 @@
    10.4  {
    10.5  #ifdef _WIN32_WCE
    10.6  	/* WinCE uses the UNICODE version */
    10.7 -	int nLen = strlen(SDL_Appname);
    10.8 -	LPWSTR lpszW = alloca((nLen+1)*2);
    10.9 +	int nLen = strlen(SDL_Appname)+1;
   10.10 +	LPWSTR lpszW = alloca(nLen*2);
   10.11  	MultiByteToWideChar(CP_ACP, 0, SDL_Appname, -1, lpszW, nLen);
   10.12  
   10.13  	SDL_RegisterApp("SDL_app", 0, 0);
   10.14 -	SDL_Window = CreateWindow(lpszW, lpszW,
   10.15 -                        (WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX),
   10.16 -                                 0, 0, 0, 0, NULL, NULL, SDL_Instance, NULL);
   10.17 +	SDL_Window = CreateWindow(lpszW, lpszW, WS_VISIBLE,
   10.18 +                                  0, 0, 0, 0, NULL, NULL, SDL_Instance, NULL);
   10.19  	if ( SDL_Window == NULL ) {
   10.20  		SDL_SetError("Couldn't create window");
   10.21  		return(-1);
    11.1 --- a/src/video/windib/SDL_dibvideo.c	Wed May 23 00:36:17 2001 +0000
    11.2 +++ b/src/video/windib/SDL_dibvideo.c	Wed May 23 23:35:10 2001 +0000
    11.3 @@ -440,8 +440,10 @@
    11.4  			(WS_POPUP);
    11.5  	const DWORD windowstyle = 
    11.6  			(WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX);
    11.7 +#ifndef _WIN32_WCE
    11.8  	const DWORD resizestyle =
    11.9  			(WS_THICKFRAME|WS_MAXIMIZEBOX);
   11.10 +#endif
   11.11  	int binfo_size;
   11.12  	BITMAPINFO *binfo;
   11.13  	HDC hdc;
   11.14 @@ -453,10 +455,12 @@
   11.15  	/* See whether or not we should center the window */
   11.16  	was_visible = IsWindowVisible(SDL_Window);
   11.17  
   11.18 +#ifdef HAVE_OPENGL
   11.19  	/* Clean up any GL context that may be hanging around */
   11.20  	if ( current->flags & SDL_OPENGL ) {
   11.21  		WIN_GL_ShutDown(this);
   11.22  	}
   11.23 +#endif /* HAVE_OPENGL */
   11.24  
   11.25  	/* Recalculate the bitmasks if necessary */
   11.26  	if ( bpp == current->format->BitsPerPixel ) {
   11.27 @@ -535,7 +539,9 @@
   11.28  #endif /* !NO_CHANGEDISPLAYSETTINGS */
   11.29  
   11.30  	style = GetWindowLong(SDL_Window, GWL_STYLE);
   11.31 +#ifndef _WIN32_WCE
   11.32  	style &= ~(resizestyle|WS_MAXIMIZE);
   11.33 +#endif
   11.34  	if ( (video->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
   11.35  		style &= ~windowstyle;
   11.36  		style |= directstyle;
   11.37 @@ -553,11 +559,15 @@
   11.38  			style &= ~directstyle;
   11.39  			style |= windowstyle;
   11.40  			if ( flags & SDL_RESIZABLE ) {
   11.41 +#ifndef _WIN32_WCE
   11.42  				style |= resizestyle;
   11.43 +#endif
   11.44  				video->flags |= SDL_RESIZABLE;
   11.45  			}
   11.46  		}
   11.47 +#ifndef _WIN32_WCE
   11.48  		if (IsZoomed(SDL_Window)) style |= WS_MAXIMIZE;
   11.49 +#endif
   11.50  	}
   11.51  	SetWindowLong(SDL_Window, GWL_STYLE, style);
   11.52  
   11.53 @@ -642,7 +652,11 @@
   11.54  		bounds.top = 0;
   11.55  		bounds.right = video->w;
   11.56  		bounds.bottom = video->h;
   11.57 +#ifndef _WIN32_WCE
   11.58  		AdjustWindowRect(&bounds, GetWindowLong(SDL_Window, GWL_STYLE), FALSE);
   11.59 +#else
   11.60 +		AdjustWindowRectEx(&bounds, GetWindowLong(SDL_Window, GWL_STYLE), FALSE,0);
   11.61 +#endif
   11.62  		width = bounds.right-bounds.left;
   11.63  		height = bounds.bottom-bounds.top;
   11.64  		x = (GetSystemMetrics(SM_CXSCREEN)-width)/2;
   11.65 @@ -650,7 +664,11 @@
   11.66  		if ( y < 0 ) { /* Cover up title bar for more client area */
   11.67  			y -= GetSystemMetrics(SM_CYCAPTION)/2;
   11.68  		}
   11.69 +#ifndef _WIN32_WCE
   11.70  		swp_flags = (SWP_NOCOPYBITS | SWP_NOZORDER | SWP_SHOWWINDOW);
   11.71 +#else
   11.72 +		swp_flags = (SWP_NOZORDER | SWP_SHOWWINDOW);
   11.73 +#endif
   11.74  		if ( was_visible && !(flags & SDL_FULLSCREEN) ) {
   11.75  			swp_flags |= SWP_NOMOVE;
   11.76  		}
   11.77 @@ -659,6 +677,7 @@
   11.78  		SetForegroundWindow(SDL_Window);
   11.79  	}
   11.80  
   11.81 +#ifdef HAVE_OPENGL
   11.82  	/* Set up for OpenGL */
   11.83  	if ( flags & SDL_OPENGL ) {
   11.84  		if ( WIN_GL_SetupWindow(this) < 0 ) {
   11.85 @@ -666,6 +685,8 @@
   11.86  		}
   11.87  		video->flags |= SDL_OPENGL;
   11.88  	}
   11.89 +#endif /* HAVE_OPENGL */
   11.90 +
   11.91  	/* We're live! */
   11.92  	return(video);
   11.93  }
   11.94 @@ -711,7 +732,11 @@
   11.95  {
   11.96  	RGBQUAD *pal;
   11.97  	int i;
   11.98 +#ifndef _WIN32_WCE
   11.99  	HDC hdc, mdc;
  11.100 +#else
  11.101 +	HDC hdc;
  11.102 +#endif
  11.103  
  11.104  	/* Update the display palette */
  11.105  	hdc = GetDC(SDL_Window);
  11.106 @@ -723,7 +748,11 @@
  11.107  			entries[i].peRed   = colors[i].r;
  11.108  			entries[i].peGreen = colors[i].g;
  11.109  			entries[i].peBlue  = colors[i].b;
  11.110 +#ifndef _WIN32_WCE
  11.111  			entries[i].peFlags = PC_NOCOLLAPSE;
  11.112 +else
  11.113 +			entries[i].peFlags = 0;
  11.114 +#endif
  11.115  		}
  11.116  		SetPaletteEntries(screen_pal, firstcolor, ncolors, entries);
  11.117  		SelectPalette(hdc, screen_pal, FALSE);
  11.118 @@ -740,12 +769,14 @@
  11.119  	}
  11.120  
  11.121  	/* Set the DIB palette and update the display */
  11.122 +#ifndef _WIN32_WCE
  11.123  	mdc = CreateCompatibleDC(hdc);
  11.124  	SelectObject(mdc, screen_bmp);
  11.125  	SetDIBColorTable(mdc, firstcolor, ncolors, pal);
  11.126  	BitBlt(hdc, 0, 0, this->screen->w, this->screen->h,
  11.127  	       mdc, 0, 0, SRCCOPY);
  11.128  	DeleteDC(mdc);
  11.129 +#endif
  11.130  	ReleaseDC(SDL_Window, hdc);
  11.131  	return(1);
  11.132  }
  11.133 @@ -857,9 +888,11 @@
  11.134  				ChangeDisplaySettings(NULL, 0);
  11.135  			}
  11.136  #endif
  11.137 +#ifdef HAVE_OPENGL
  11.138  			if ( this->screen->flags & SDL_OPENGL ) {
  11.139  				WIN_GL_ShutDown(this);
  11.140  			}
  11.141 +#endif /* HAVE_OPENGL */
  11.142  			this->screen->pixels = NULL;
  11.143  		}
  11.144  		if ( screen_bmp ) {