Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Cleaned up CoInitialize() politics on Windows.
- Loading branch information
|
@@ -23,6 +23,8 @@ |
|
|
#include "SDL_error.h" |
|
|
#include "SDL_windows.h" |
|
|
|
|
|
#include <objbase.h> /* for CoInitialize/CoUninitialize */ |
|
|
|
|
|
|
|
|
/* Sets an error message based on GetLastError() */ |
|
|
void |
|
@@ -37,4 +39,23 @@ WIN_SetError(const char *prefix) |
|
|
SDL_free(message); |
|
|
} |
|
|
|
|
|
HRESULT |
|
|
WIN_CoInitialize(void) |
|
|
{ |
|
|
/* S_FALSE means success, but someone else already initialized. */ |
|
|
/* You still need to call CoUninitialize in this case! */ |
|
|
const HRESULT hr = CoInitialize(NULL); |
|
|
if ((hr == S_OK) || (hr == S_FALSE)) { |
|
|
return S_OK; |
|
|
} |
|
|
|
|
|
return hr; |
|
|
} |
|
|
|
|
|
void |
|
|
WIN_CoUninitialize(void) |
|
|
{ |
|
|
CoUninitialize(); |
|
|
} |
|
|
|
|
|
/* vi: set ts=4 sw=4 expandtab: */ |
|
@@ -47,6 +47,10 @@ |
|
|
/* Sets an error message based on GetLastError() */ |
|
|
extern void WIN_SetError(const char *prefix); |
|
|
|
|
|
/* Wrap up the oddities of CoInitialize() into a common function. */ |
|
|
extern HRESULT WIN_CoInitialize(void); |
|
|
extern void WIN_CoUninitialize(void); |
|
|
|
|
|
#endif /* _INCLUDED_WINDOWS_H */ |
|
|
|
|
|
/* vi: set ts=4 sw=4 expandtab: */ |
|
@@ -68,6 +68,7 @@ struct haptic_hweffect |
|
|
/* |
|
|
* Internal stuff. |
|
|
*/ |
|
|
static SDL_bool coinitialized = SDL_FALSE; |
|
|
static LPDIRECTINPUT dinput = NULL; |
|
|
|
|
|
|
|
@@ -147,28 +148,33 @@ SDL_SYS_HapticInit(void) |
|
|
|
|
|
SDL_numhaptics = 0; |
|
|
|
|
|
ret = CoInitialize(NULL); |
|
|
ret = WIN_CoInitialize(); |
|
|
if (FAILED(ret)) { |
|
|
DI_SetError("Coinitialize", ret); |
|
|
return -1; |
|
|
} |
|
|
|
|
|
coinitialized = SDL_TRUE; |
|
|
|
|
|
ret = CoCreateInstance(&CLSID_DirectInput, NULL, CLSCTX_INPROC_SERVER, |
|
|
&IID_IDirectInput, (LPVOID) & dinput); |
|
|
if (FAILED(ret)) { |
|
|
SDL_SYS_HapticQuit(); |
|
|
DI_SetError("CoCreateInstance", ret); |
|
|
return -1; |
|
|
} |
|
|
|
|
|
/* Because we used CoCreateInstance, we need to Initialize it, first. */ |
|
|
instance = GetModuleHandle(NULL); |
|
|
if (instance == NULL) { |
|
|
SDL_SYS_HapticQuit(); |
|
|
SDL_SetError("GetModuleHandle() failed with error code %d.", |
|
|
GetLastError()); |
|
|
return -1; |
|
|
} |
|
|
ret = IDirectInput_Initialize(dinput, instance, DIRECTINPUT_VERSION); |
|
|
if (FAILED(ret)) { |
|
|
SDL_SYS_HapticQuit(); |
|
|
DI_SetError("Initializing DirectInput device", ret); |
|
|
return -1; |
|
|
} |
|
@@ -181,6 +187,7 @@ SDL_SYS_HapticInit(void) |
|
|
DIEDFL_FORCEFEEDBACK | |
|
|
DIEDFL_ATTACHEDONLY); |
|
|
if (FAILED(ret)) { |
|
|
SDL_SYS_HapticQuit(); |
|
|
DI_SetError("Enumerating DirectInput devices", ret); |
|
|
return -1; |
|
|
} |
|
@@ -664,8 +671,15 @@ SDL_SYS_HapticQuit(void) |
|
|
} |
|
|
} |
|
|
|
|
|
IDirectInput_Release(dinput); |
|
|
dinput = NULL; |
|
|
if (dinput != NULL) { |
|
|
IDirectInput_Release(dinput); |
|
|
dinput = NULL; |
|
|
} |
|
|
|
|
|
if (coinitialized) { |
|
|
WIN_CoUninitialize(); |
|
|
coinitialized = SDL_FALSE; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
@@ -57,6 +57,7 @@ extern HWND SDL_HelperWindow; |
|
|
|
|
|
|
|
|
/* local variables */ |
|
|
static SDL_bool coinitialized = SDL_FALSE; |
|
|
static LPDIRECTINPUT dinput = NULL; |
|
|
extern HRESULT(WINAPI * DInputCreate) (HINSTANCE hinst, DWORD dwVersion, |
|
|
LPDIRECTINPUT * ppDI, |
|
@@ -284,30 +285,35 @@ SDL_SYS_JoystickInit(void) |
|
|
|
|
|
SYS_NumJoysticks = 0; |
|
|
|
|
|
result = CoInitialize(NULL); |
|
|
result = WIN_CoInitialize(); |
|
|
if (FAILED(result)) { |
|
|
SetDIerror("CoInitialize", result); |
|
|
return (-1); |
|
|
} |
|
|
|
|
|
coinitialized = SDL_TRUE; |
|
|
|
|
|
result = CoCreateInstance(&CLSID_DirectInput, NULL, CLSCTX_INPROC_SERVER, |
|
|
&IID_IDirectInput, (LPVOID)&dinput); |
|
|
|
|
|
if (FAILED(result)) { |
|
|
SDL_SYS_JoystickQuit(); |
|
|
SetDIerror("CoCreateInstance", result); |
|
|
return (-1); |
|
|
} |
|
|
|
|
|
/* Because we used CoCreateInstance, we need to Initialize it, first. */ |
|
|
instance = GetModuleHandle(NULL); |
|
|
if (instance == NULL) { |
|
|
SDL_SYS_JoystickQuit(); |
|
|
SDL_SetError("GetModuleHandle() failed with error code %d.", |
|
|
GetLastError()); |
|
|
return (-1); |
|
|
} |
|
|
result = IDirectInput_Initialize(dinput, instance, DIRECTINPUT_VERSION); |
|
|
|
|
|
if (FAILED(result)) { |
|
|
SDL_SYS_JoystickQuit(); |
|
|
SetDIerror("IDirectInput::Initialize", result); |
|
|
return (-1); |
|
|
} |
|
@@ -802,8 +808,15 @@ SDL_SYS_JoystickQuit(void) |
|
|
} |
|
|
} |
|
|
|
|
|
IDirectInput_Release(dinput); |
|
|
dinput = NULL; |
|
|
if (dinput != NULL) { |
|
|
IDirectInput_Release(dinput); |
|
|
dinput = NULL; |
|
|
} |
|
|
|
|
|
if (coinitialized) { |
|
|
WIN_CoUninitialize(); |
|
|
coinitialized = SDL_FALSE; |
|
|
} |
|
|
} |
|
|
|
|
|
#endif /* SDL_JOYSTICK_DINPUT */ |
|
|
|
@@ -305,7 +305,7 @@ IME_Init(SDL_VideoData *videodata, HWND hwnd) |
|
|
return; |
|
|
|
|
|
videodata->ime_hwnd_main = hwnd; |
|
|
if (SUCCEEDED(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED))) { |
|
|
if (SUCCEEDED(WIN_CoInitialize())) { |
|
|
videodata->ime_com_initialized = SDL_TRUE; |
|
|
CoCreateInstance(&CLSID_TF_ThreadMgr, NULL, CLSCTX_INPROC_SERVER, &IID_ITfThreadMgr, (LPVOID *)&videodata->ime_threadmgr); |
|
|
} |
|
@@ -389,7 +389,7 @@ IME_Quit(SDL_VideoData *videodata) |
|
|
videodata->ime_threadmgr = 0; |
|
|
} |
|
|
if (videodata->ime_com_initialized) { |
|
|
CoUninitialize(); |
|
|
WIN_CoUninitialize(); |
|
|
videodata->ime_com_initialized = SDL_FALSE; |
|
|
} |
|
|
IME_DestroyTextures(videodata); |
|
|