Cleaned up CoInitialize() politics on Windows.
1.1 --- a/src/core/windows/SDL_windows.c Thu Aug 04 01:07:13 2011 -0400
1.2 +++ b/src/core/windows/SDL_windows.c Wed Aug 03 04:22:47 2011 -0400
1.3 @@ -23,6 +23,8 @@
1.4 #include "SDL_error.h"
1.5 #include "SDL_windows.h"
1.6
1.7 +#include <objbase.h> /* for CoInitialize/CoUninitialize */
1.8 +
1.9
1.10 /* Sets an error message based on GetLastError() */
1.11 void
1.12 @@ -37,4 +39,23 @@
1.13 SDL_free(message);
1.14 }
1.15
1.16 +HRESULT
1.17 +WIN_CoInitialize(void)
1.18 +{
1.19 + /* S_FALSE means success, but someone else already initialized. */
1.20 + /* You still need to call CoUninitialize in this case! */
1.21 + const HRESULT hr = CoInitialize(NULL);
1.22 + if ((hr == S_OK) || (hr == S_FALSE)) {
1.23 + return S_OK;
1.24 + }
1.25 +
1.26 + return hr;
1.27 +}
1.28 +
1.29 +void
1.30 +WIN_CoUninitialize(void)
1.31 +{
1.32 + CoUninitialize();
1.33 +}
1.34 +
1.35 /* vi: set ts=4 sw=4 expandtab: */
2.1 --- a/src/core/windows/SDL_windows.h Thu Aug 04 01:07:13 2011 -0400
2.2 +++ b/src/core/windows/SDL_windows.h Wed Aug 03 04:22:47 2011 -0400
2.3 @@ -47,6 +47,10 @@
2.4 /* Sets an error message based on GetLastError() */
2.5 extern void WIN_SetError(const char *prefix);
2.6
2.7 +/* Wrap up the oddities of CoInitialize() into a common function. */
2.8 +extern HRESULT WIN_CoInitialize(void);
2.9 +extern void WIN_CoUninitialize(void);
2.10 +
2.11 #endif /* _INCLUDED_WINDOWS_H */
2.12
2.13 /* vi: set ts=4 sw=4 expandtab: */
3.1 --- a/src/haptic/windows/SDL_syshaptic.c Thu Aug 04 01:07:13 2011 -0400
3.2 +++ b/src/haptic/windows/SDL_syshaptic.c Wed Aug 03 04:22:47 2011 -0400
3.3 @@ -68,6 +68,7 @@
3.4 /*
3.5 * Internal stuff.
3.6 */
3.7 +static SDL_bool coinitialized = SDL_FALSE;
3.8 static LPDIRECTINPUT dinput = NULL;
3.9
3.10
3.11 @@ -147,15 +148,18 @@
3.12
3.13 SDL_numhaptics = 0;
3.14
3.15 - ret = CoInitialize(NULL);
3.16 + ret = WIN_CoInitialize();
3.17 if (FAILED(ret)) {
3.18 DI_SetError("Coinitialize", ret);
3.19 return -1;
3.20 }
3.21
3.22 + coinitialized = SDL_TRUE;
3.23 +
3.24 ret = CoCreateInstance(&CLSID_DirectInput, NULL, CLSCTX_INPROC_SERVER,
3.25 &IID_IDirectInput, (LPVOID) & dinput);
3.26 if (FAILED(ret)) {
3.27 + SDL_SYS_HapticQuit();
3.28 DI_SetError("CoCreateInstance", ret);
3.29 return -1;
3.30 }
3.31 @@ -163,12 +167,14 @@
3.32 /* Because we used CoCreateInstance, we need to Initialize it, first. */
3.33 instance = GetModuleHandle(NULL);
3.34 if (instance == NULL) {
3.35 + SDL_SYS_HapticQuit();
3.36 SDL_SetError("GetModuleHandle() failed with error code %d.",
3.37 GetLastError());
3.38 return -1;
3.39 }
3.40 ret = IDirectInput_Initialize(dinput, instance, DIRECTINPUT_VERSION);
3.41 if (FAILED(ret)) {
3.42 + SDL_SYS_HapticQuit();
3.43 DI_SetError("Initializing DirectInput device", ret);
3.44 return -1;
3.45 }
3.46 @@ -181,6 +187,7 @@
3.47 DIEDFL_FORCEFEEDBACK |
3.48 DIEDFL_ATTACHEDONLY);
3.49 if (FAILED(ret)) {
3.50 + SDL_SYS_HapticQuit();
3.51 DI_SetError("Enumerating DirectInput devices", ret);
3.52 return -1;
3.53 }
3.54 @@ -664,8 +671,15 @@
3.55 }
3.56 }
3.57
3.58 - IDirectInput_Release(dinput);
3.59 - dinput = NULL;
3.60 + if (dinput != NULL) {
3.61 + IDirectInput_Release(dinput);
3.62 + dinput = NULL;
3.63 + }
3.64 +
3.65 + if (coinitialized) {
3.66 + WIN_CoUninitialize();
3.67 + coinitialized = SDL_FALSE;
3.68 + }
3.69 }
3.70
3.71
4.1 --- a/src/joystick/windows/SDL_dxjoystick.c Thu Aug 04 01:07:13 2011 -0400
4.2 +++ b/src/joystick/windows/SDL_dxjoystick.c Wed Aug 03 04:22:47 2011 -0400
4.3 @@ -57,6 +57,7 @@
4.4
4.5
4.6 /* local variables */
4.7 +static SDL_bool coinitialized = SDL_FALSE;
4.8 static LPDIRECTINPUT dinput = NULL;
4.9 extern HRESULT(WINAPI * DInputCreate) (HINSTANCE hinst, DWORD dwVersion,
4.10 LPDIRECTINPUT * ppDI,
4.11 @@ -284,16 +285,19 @@
4.12
4.13 SYS_NumJoysticks = 0;
4.14
4.15 - result = CoInitialize(NULL);
4.16 + result = WIN_CoInitialize();
4.17 if (FAILED(result)) {
4.18 SetDIerror("CoInitialize", result);
4.19 return (-1);
4.20 }
4.21
4.22 + coinitialized = SDL_TRUE;
4.23 +
4.24 result = CoCreateInstance(&CLSID_DirectInput, NULL, CLSCTX_INPROC_SERVER,
4.25 &IID_IDirectInput, (LPVOID)&dinput);
4.26
4.27 if (FAILED(result)) {
4.28 + SDL_SYS_JoystickQuit();
4.29 SetDIerror("CoCreateInstance", result);
4.30 return (-1);
4.31 }
4.32 @@ -301,6 +305,7 @@
4.33 /* Because we used CoCreateInstance, we need to Initialize it, first. */
4.34 instance = GetModuleHandle(NULL);
4.35 if (instance == NULL) {
4.36 + SDL_SYS_JoystickQuit();
4.37 SDL_SetError("GetModuleHandle() failed with error code %d.",
4.38 GetLastError());
4.39 return (-1);
4.40 @@ -308,6 +313,7 @@
4.41 result = IDirectInput_Initialize(dinput, instance, DIRECTINPUT_VERSION);
4.42
4.43 if (FAILED(result)) {
4.44 + SDL_SYS_JoystickQuit();
4.45 SetDIerror("IDirectInput::Initialize", result);
4.46 return (-1);
4.47 }
4.48 @@ -802,8 +808,15 @@
4.49 }
4.50 }
4.51
4.52 - IDirectInput_Release(dinput);
4.53 - dinput = NULL;
4.54 + if (dinput != NULL) {
4.55 + IDirectInput_Release(dinput);
4.56 + dinput = NULL;
4.57 + }
4.58 +
4.59 + if (coinitialized) {
4.60 + WIN_CoUninitialize();
4.61 + coinitialized = SDL_FALSE;
4.62 + }
4.63 }
4.64
4.65 #endif /* SDL_JOYSTICK_DINPUT */
5.1 --- a/src/video/windows/SDL_windowskeyboard.c Thu Aug 04 01:07:13 2011 -0400
5.2 +++ b/src/video/windows/SDL_windowskeyboard.c Wed Aug 03 04:22:47 2011 -0400
5.3 @@ -305,7 +305,7 @@
5.4 return;
5.5
5.6 videodata->ime_hwnd_main = hwnd;
5.7 - if (SUCCEEDED(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED))) {
5.8 + if (SUCCEEDED(WIN_CoInitialize())) {
5.9 videodata->ime_com_initialized = SDL_TRUE;
5.10 CoCreateInstance(&CLSID_TF_ThreadMgr, NULL, CLSCTX_INPROC_SERVER, &IID_ITfThreadMgr, (LPVOID *)&videodata->ime_threadmgr);
5.11 }
5.12 @@ -389,7 +389,7 @@
5.13 videodata->ime_threadmgr = 0;
5.14 }
5.15 if (videodata->ime_com_initialized) {
5.16 - CoUninitialize();
5.17 + WIN_CoUninitialize();
5.18 videodata->ime_com_initialized = SDL_FALSE;
5.19 }
5.20 IME_DestroyTextures(videodata);