21 #include "../../SDL_internal.h" 23 #if SDL_JOYSTICK_DINPUT || SDL_JOYSTICK_XINPUT 41 #include "../SDL_sysjoystick.h" 42 #include "../../thread/SDL_systhread.h" 43 #include "../../core/windows/SDL_windows.h" 44 #if !defined(__WINRT__) 53 #include "../../haptic/windows/SDL_dinputhaptic_c.h" 54 #include "../../haptic/windows/SDL_xinputhaptic_c.h" 57 #ifndef DEVICE_NOTIFY_WINDOW_HANDLE 58 #define DEVICE_NOTIFY_WINDOW_HANDLE 0x00000000 79 } SDL_DeviceNotificationData;
82 SDL_CleanupDeviceNotification(SDL_DeviceNotificationData *
data)
87 SDL_CreateDeviceNotification(SDL_DeviceNotificationData *
data)
102 HRESULT coinitialized;
106 } SDL_DeviceNotificationData;
108 #define IDT_SDL_DEVICE_CHANGE_TIMER_1 1200 109 #define IDT_SDL_DEVICE_CHANGE_TIMER_2 1201 112 static LRESULT CALLBACK
113 SDL_PrivateJoystickDetectProc(HWND hwnd, UINT
message, WPARAM wParam, LPARAM lParam)
116 case WM_DEVICECHANGE:
118 case DBT_DEVICEARRIVAL:
119 case DBT_DEVICEREMOVECOMPLETE:
120 if (((DEV_BROADCAST_HDR*)lParam)->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) {
122 SetTimer(hwnd, IDT_SDL_DEVICE_CHANGE_TIMER_1, 300,
NULL);
123 SetTimer(hwnd, IDT_SDL_DEVICE_CHANGE_TIMER_2, 2000,
NULL);
129 KillTimer(hwnd, wParam);
134 return DefWindowProc (hwnd, message, wParam, lParam);
138 SDL_CleanupDeviceNotification(SDL_DeviceNotificationData *
data)
141 UnregisterDeviceNotification(data->hNotify);
143 if (data->messageWindow)
144 DestroyWindow(data->messageWindow);
146 UnregisterClass(data->wincl.lpszClassName, data->wincl.hInstance);
148 if (data->coinitialized ==
S_OK) {
154 SDL_CreateDeviceNotification(SDL_DeviceNotificationData *data)
156 DEV_BROADCAST_DEVICEINTERFACE dbh;
157 GUID GUID_DEVINTERFACE_HID = { 0x4D1E55B2L, 0xF16F, 0x11CF, { 0x88, 0xCB, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30 } };
163 data->wincl.hInstance = GetModuleHandle(
NULL);
164 data->wincl.lpszClassName = L
"Message";
165 data->wincl.lpfnWndProc = SDL_PrivateJoystickDetectProc;
166 data->wincl.cbSize =
sizeof (WNDCLASSEX);
168 if (!RegisterClassEx(&data->wincl)) {
169 WIN_SetError(
"Failed to create register class for joystick autodetect");
170 SDL_CleanupDeviceNotification(data);
174 data->messageWindow = (HWND)CreateWindowEx(0, L
"Message",
NULL, 0, 0, 0, 0, 0, HWND_MESSAGE,
NULL,
NULL,
NULL);
175 if (!data->messageWindow) {
176 WIN_SetError(
"Failed to create message window for joystick autodetect");
177 SDL_CleanupDeviceNotification(data);
182 dbh.dbcc_size =
sizeof(dbh);
183 dbh.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
184 dbh.dbcc_classguid = GUID_DEVINTERFACE_HID;
186 data->hNotify = RegisterDeviceNotification(data->messageWindow, &dbh, DEVICE_NOTIFY_WINDOW_HANDLE);
187 if (!data->hNotify) {
188 WIN_SetError(
"Failed to create notify device for joystick autodetect");
189 SDL_CleanupDeviceNotification(data);
196 SDL_WaitForDeviceNotification(SDL_DeviceNotificationData *data,
SDL_mutex *
mutex)
201 if (!data->messageWindow) {
206 while (lastret > 0 && s_bWindowsDeviceChanged ==
SDL_FALSE) {
207 lastret = GetMessage(&msg,
NULL, 0, 0);
209 TranslateMessage(&msg);
210 DispatchMessage(&msg);
221 SDL_JoystickThread(
void *_data)
223 SDL_DeviceNotificationData notification_data;
225 #if SDL_JOYSTICK_XINPUT 226 SDL_bool bOpenedXInputDevices[XUSER_MAX_COUNT];
230 if (SDL_CreateDeviceNotification(¬ification_data) < 0) {
235 while (s_bJoystickThreadQuit ==
SDL_FALSE) {
238 if (SDL_WaitForDeviceNotification(¬ification_data, s_mutexJoyStickEnum) ==
SDL_FALSE) {
239 #if SDL_JOYSTICK_XINPUT 245 for (userId = 0; userId < XUSER_MAX_COUNT; userId++) {
246 XINPUT_CAPABILITIES capabilities;
247 const DWORD
result = XINPUTGETCAPABILITIES(userId, XINPUT_FLAG_GAMEPAD, &capabilities);
249 if (bOpenedXInputDevices[userId] != available) {
251 bOpenedXInputDevices[userId] =
available;
261 if (s_bWindowsDeviceChanged || bXInputChanged) {
269 SDL_CleanupDeviceNotification(¬ification_data);
307 if (!s_threadJoystick) {
323 device = device->
pNext;
336 if (!s_bDeviceAdded && !s_bDeviceRemoved) {
367 pListNext = pCurList->
pNext;
370 pCurList = pListNext;
373 if (s_bDeviceAdded) {
375 int device_index = 0;
378 while (pNewJoystick) {
391 pNewJoystick = pNewJoystick->
pNext;
402 for (; device_index > 0; device_index--)
403 device = device->
pNext;
415 for (index = device_index; index > 0; index--)
416 device = device->
pNext;
431 for (; device_index > 0; device_index--)
432 joystickdevice = joystickdevice->
pNext;
435 joystick->instance_id = joystickdevice->
nInstanceID;
438 if (joystick->hwdata ==
NULL) {
442 joystick->hwdata->guid = joystickdevice->
guid;
455 return joystick->hwdata && !joystick->hwdata->removed;
461 if (!joystick->hwdata || joystick->hwdata->removed) {
465 if (joystick->hwdata->bXInputDevice) {
471 if (joystick->hwdata->removed) {
472 joystick->force_recentering =
SDL_TRUE;
480 if (joystick->hwdata->bXInputDevice) {
499 device = device_next;
503 if (s_threadJoystick) {
515 s_condJoystickThread=
NULL;
516 s_mutexJoyStickEnum =
NULL;
517 s_threadJoystick =
NULL;
534 for (index = device_index; index > 0; index--)
535 device = device->
pNext;
543 return joystick->hwdata->guid;
JoyStick_DeviceData * SYS_Joystick
void SDL_PrivateJoystickRemoved(SDL_JoystickID device_instance)
GLuint GLsizei const GLchar * message
struct JoyStick_DeviceData * pNext
void SDL_SYS_AddJoystickDevice(JoyStick_DeviceData *device)
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
void SDL_SYS_JoystickQuit(void)
SDL_JoystickID nInstanceID
static SDL_AudioDeviceID device
SDL_Thread * SDL_CreateThreadInternal(int(*fn)(void *), const char *name, const size_t stacksize, void *data)
#define SDL_CondWaitTimeout
HRESULT WIN_CoInitialize(void)
SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
void SDL_PrivateJoystickAdded(int device_index)
const char * SDL_SYS_JoystickNameForDeviceIndex(int device_index)
#define SDL_CondBroadcast
void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick)
SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick *joystick)
int SDL_SYS_JoystickInit(void)
#define SDL_OutOfMemory()
void WIN_CoUninitialize(void)
int SDL_SYS_NumJoysticks(void)
int WIN_SetError(const char *prefix)
SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index)
int SDL_SYS_JoystickOpen(SDL_Joystick *joystick, int device_index)
DIDEVICEINSTANCE dxdevice
void SDL_SYS_JoystickClose(SDL_Joystick *joystick)
SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID(int device_index)
void SDL_SYS_JoystickDetect(void)