Windows CE patches contributed by Rainer Loritz
--HG-- extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%4037
This commit is contained in:
parent
09112109c3
commit
a95fb10027
11 changed files with 413 additions and 63 deletions
18
src/SDL.c
18
src/SDL.c
|
@ -231,3 +231,21 @@ const SDL_version * SDL_Linked_Version(void)
|
|||
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 */
|
||||
|
|
|
@ -37,6 +37,9 @@ static char rcsid =
|
|||
#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,17 +115,32 @@ static void CALLBACK FillSound(HWAVEOUT hwo, UINT uMsg, DWORD dwInstance,
|
|||
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);
|
||||
#endif
|
||||
|
||||
SDL_SetError("%s",errbuf);
|
||||
}
|
||||
|
||||
|
@ -135,7 +153,11 @@ static void DIB_ThreadInit(_THIS)
|
|||
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 @@ void DIB_CloseAudio(_THIS)
|
|||
|
||||
/* 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 @@ int DIB_OpenAudio(_THIS, SDL_AudioSpec *spec)
|
|||
#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);
|
||||
|
|
|
@ -30,6 +30,7 @@ static char rcsid =
|
|||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "SDL_error.h"
|
||||
|
|
|
@ -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 @@ static BOOL OutOfMemory(void)
|
|||
}
|
||||
|
||||
/* 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 @@ static void cleanup_output(void)
|
|||
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 @@ int console_main(int argc, char *argv[])
|
|||
}
|
||||
|
||||
/* 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 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw)
|
|||
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 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw)
|
|||
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 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw)
|
|||
return OutOfMemory();
|
||||
}
|
||||
strcpy(cmdline, bufp);
|
||||
#endif
|
||||
|
||||
/* Parse it into argv and argc */
|
||||
argc = ParseCommandLine(cmdline, NULL);
|
||||
|
|
|
@ -33,56 +33,17 @@ static char rcsid =
|
|||
|
||||
#include "SDL_error.h"
|
||||
#include "SDL_thread.h"
|
||||
|
||||
#if defined(_WIN32_WCE) && (_WIN32_WCE < 300)
|
||||
#include "win_ce_semaphore.h"
|
||||
#endif
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
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 @@ SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
|
|||
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 @@ void SDL_DestroySemaphore(SDL_sem *sem)
|
|||
{
|
||||
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 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
|
|||
} 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 @@ int SDL_SemPost(SDL_sem *sem)
|
|||
* 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 */
|
214
src/thread/win32/win_ce_semaphore.c
Normal file
214
src/thread/win32/win_ce_semaphore.c
Normal file
|
@ -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;
|
||||
}
|
22
src/thread/win32/win_ce_semaphore.h
Normal file
22
src/thread/win32/win_ce_semaphore.h
Normal file
|
@ -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);
|
|
@ -496,12 +496,12 @@ int SDL_RegisterApp(char *name, Uint32 style, void *hInst)
|
|||
#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
|
||||
|
|
|
@ -213,8 +213,8 @@ void WIN_SetWMCaption(_THIS, const char *title, const char *icon)
|
|||
{
|
||||
#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
|
||||
|
|
|
@ -303,13 +303,12 @@ int DIB_CreateWindow(_THIS)
|
|||
{
|
||||
#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),
|
||||
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");
|
||||
|
|
|
@ -440,8 +440,10 @@ SDL_Surface *DIB_SetVideoMode(_THIS, SDL_Surface *current,
|
|||
(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 @@ SDL_Surface *DIB_SetVideoMode(_THIS, SDL_Surface *current,
|
|||
/* 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 @@ SDL_Surface *DIB_SetVideoMode(_THIS, SDL_Surface *current,
|
|||
#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 @@ SDL_Surface *DIB_SetVideoMode(_THIS, SDL_Surface *current,
|
|||
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 @@ SDL_Surface *DIB_SetVideoMode(_THIS, SDL_Surface *current,
|
|||
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 @@ SDL_Surface *DIB_SetVideoMode(_THIS, SDL_Surface *current,
|
|||
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 @@ SDL_Surface *DIB_SetVideoMode(_THIS, SDL_Surface *current,
|
|||
SetForegroundWindow(SDL_Window);
|
||||
}
|
||||
|
||||
#ifdef HAVE_OPENGL
|
||||
/* Set up for OpenGL */
|
||||
if ( flags & SDL_OPENGL ) {
|
||||
if ( WIN_GL_SetupWindow(this) < 0 ) {
|
||||
|
@ -666,6 +685,8 @@ SDL_Surface *DIB_SetVideoMode(_THIS, SDL_Surface *current,
|
|||
}
|
||||
video->flags |= SDL_OPENGL;
|
||||
}
|
||||
#endif /* HAVE_OPENGL */
|
||||
|
||||
/* We're live! */
|
||||
return(video);
|
||||
}
|
||||
|
@ -711,7 +732,11 @@ int DIB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
|
|||
{
|
||||
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 @@ int DIB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
|
|||
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 @@ int DIB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
|
|||
}
|
||||
|
||||
/* 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 @@ void DIB_VideoQuit(_THIS)
|
|||
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 ) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue