From 80d11f278fbd50040ff18ef80a0c9a62a29b3b8e Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Wed, 23 May 2001 23:35:10 +0000 Subject: [PATCH] Windows CE patches contributed by Rainer Loritz --- src/SDL.c | 18 +++ src/audio/windib/SDL_dibaudio.c | 32 ++++- src/file/SDL_rwops.c | 1 + src/main/win32/SDL_main.c | 68 ++++++++- src/thread/win32/SDL_syssem.c | 69 +++------ src/thread/win32/win_ce_semaphore.c | 214 ++++++++++++++++++++++++++++ src/thread/win32/win_ce_semaphore.h | 22 +++ src/video/wincommon/SDL_sysevents.c | 6 +- src/video/wincommon/SDL_syswm.c | 4 +- src/video/windib/SDL_dibevents.c | 9 +- src/video/windib/SDL_dibvideo.c | 33 +++++ 11 files changed, 413 insertions(+), 63 deletions(-) create mode 100644 src/thread/win32/win_ce_semaphore.c create mode 100644 src/thread/win32/win_ce_semaphore.h diff --git a/src/SDL.c b/src/SDL.c index 5fc235d88..632779621 100644 --- a/src/SDL.c +++ b/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 + +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 */ diff --git a/src/audio/windib/SDL_dibaudio.c b/src/audio/windib/SDL_dibaudio.c index 41747fcf2..7ab1f00bc 100644 --- a/src/audio/windib/SDL_dibaudio.c +++ b/src/audio/windib/SDL_dibaudio.c @@ -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,18 +115,33 @@ 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); - SDL_SetError("%s", errbuf); +#endif + + SDL_SetError("%s",errbuf); } /* Set high priority for the audio thread */ @@ -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); diff --git a/src/file/SDL_rwops.c b/src/file/SDL_rwops.c index 9cf9da368..81f090604 100644 --- a/src/file/SDL_rwops.c +++ b/src/file/SDL_rwops.c @@ -30,6 +30,7 @@ static char rcsid = */ #include +#include #include #include "SDL_error.h" diff --git a/src/main/win32/SDL_main.c b/src/main/win32/SDL_main.c index 2ce84eb76..7f5a5cf5a 100644 --- a/src/main/win32/SDL_main.c +++ b/src/main/win32/SDL_main.c @@ -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); diff --git a/src/thread/win32/SDL_syssem.c b/src/thread/win32/SDL_syssem.c index 097ce5a17..c38e22ed7 100644 --- a/src/thread/win32/SDL_syssem.c +++ b/src/thread/win32/SDL_syssem.c @@ -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 */ \ No newline at end of file diff --git a/src/thread/win32/win_ce_semaphore.c b/src/thread/win32/win_ce_semaphore.c new file mode 100644 index 000000000..cde391118 --- /dev/null +++ b/src/thread/win32/win_ce_semaphore.c @@ -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 +#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; +} diff --git a/src/thread/win32/win_ce_semaphore.h b/src/thread/win32/win_ce_semaphore.h new file mode 100644 index 000000000..af2d7b613 --- /dev/null +++ b/src/thread/win32/win_ce_semaphore.h @@ -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); diff --git a/src/video/wincommon/SDL_sysevents.c b/src/video/wincommon/SDL_sysevents.c index d4a8a6274..ec46bbfa8 100644 --- a/src/video/wincommon/SDL_sysevents.c +++ b/src/video/wincommon/SDL_sysevents.c @@ -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 diff --git a/src/video/wincommon/SDL_syswm.c b/src/video/wincommon/SDL_syswm.c index d650af524..0cbad42be 100644 --- a/src/video/wincommon/SDL_syswm.c +++ b/src/video/wincommon/SDL_syswm.c @@ -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 diff --git a/src/video/windib/SDL_dibevents.c b/src/video/windib/SDL_dibevents.c index b239aedb3..f7d362a86 100644 --- a/src/video/windib/SDL_dibevents.c +++ b/src/video/windib/SDL_dibevents.c @@ -303,14 +303,13 @@ 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), - 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); diff --git a/src/video/windib/SDL_dibvideo.c b/src/video/windib/SDL_dibvideo.c index 8420b9d1b..5edfc1661 100644 --- a/src/video/windib/SDL_dibvideo.c +++ b/src/video/windib/SDL_dibvideo.c @@ -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 ) {