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 78 } SDL_DeviceNotificationData;
81 SDL_CleanupDeviceNotification(SDL_DeviceNotificationData *
data)
86 SDL_CreateDeviceNotification(SDL_DeviceNotificationData *
data)
101 HRESULT coinitialized;
105 } SDL_DeviceNotificationData;
107 #define IDT_SDL_DEVICE_CHANGE_TIMER_1 1200 108 #define IDT_SDL_DEVICE_CHANGE_TIMER_2 1201 111 static LRESULT CALLBACK
112 SDL_PrivateJoystickDetectProc(HWND hwnd, UINT
message, WPARAM wParam, LPARAM lParam)
115 case WM_DEVICECHANGE:
117 case DBT_DEVICEARRIVAL:
118 case DBT_DEVICEREMOVECOMPLETE:
119 if (((DEV_BROADCAST_HDR*)lParam)->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) {
121 SetTimer(hwnd, IDT_SDL_DEVICE_CHANGE_TIMER_1, 300,
NULL);
122 SetTimer(hwnd, IDT_SDL_DEVICE_CHANGE_TIMER_2, 2000,
NULL);
128 KillTimer(hwnd, wParam);
133 return DefWindowProc (hwnd, message, wParam, lParam);
137 SDL_CleanupDeviceNotification(SDL_DeviceNotificationData *
data)
140 UnregisterDeviceNotification(data->hNotify);
142 if (data->messageWindow)
143 DestroyWindow(data->messageWindow);
145 UnregisterClass(data->wincl.lpszClassName, data->wincl.hInstance);
147 if (data->coinitialized ==
S_OK) {
153 SDL_CreateDeviceNotification(SDL_DeviceNotificationData *data)
155 DEV_BROADCAST_DEVICEINTERFACE dbh;
156 GUID GUID_DEVINTERFACE_HID = { 0x4D1E55B2L, 0xF16F, 0x11CF, { 0x88, 0xCB, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30 } };
162 data->wincl.hInstance = GetModuleHandle(
NULL);
163 data->wincl.lpszClassName = L
"Message";
164 data->wincl.lpfnWndProc = SDL_PrivateJoystickDetectProc;
165 data->wincl.cbSize =
sizeof (WNDCLASSEX);
167 if (!RegisterClassEx(&data->wincl)) {
168 WIN_SetError(
"Failed to create register class for joystick autodetect");
169 SDL_CleanupDeviceNotification(data);
173 data->messageWindow = (HWND)CreateWindowEx(0, L
"Message",
NULL, 0, 0, 0, 0, 0, HWND_MESSAGE,
NULL,
NULL,
NULL);
174 if (!data->messageWindow) {
175 WIN_SetError(
"Failed to create message window for joystick autodetect");
176 SDL_CleanupDeviceNotification(data);
181 dbh.dbcc_size =
sizeof(dbh);
182 dbh.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
183 dbh.dbcc_classguid = GUID_DEVINTERFACE_HID;
185 data->hNotify = RegisterDeviceNotification(data->messageWindow, &dbh, DEVICE_NOTIFY_WINDOW_HANDLE);
186 if (!data->hNotify) {
187 WIN_SetError(
"Failed to create notify device for joystick autodetect");
188 SDL_CleanupDeviceNotification(data);
195 SDL_WaitForDeviceNotification(SDL_DeviceNotificationData *data,
SDL_mutex *
mutex)
200 if (!data->messageWindow) {
205 while (lastret > 0 && s_bWindowsDeviceChanged ==
SDL_FALSE) {
206 lastret = GetMessage(&msg,
NULL, 0, 0);
208 TranslateMessage(&msg);
209 DispatchMessage(&msg);
220 SDL_JoystickThread(
void *_data)
222 SDL_DeviceNotificationData notification_data;
224 #if SDL_JOYSTICK_XINPUT 225 SDL_bool bOpenedXInputDevices[XUSER_MAX_COUNT];
229 if (SDL_CreateDeviceNotification(¬ification_data) < 0) {
234 while (s_bJoystickThreadQuit ==
SDL_FALSE) {
237 if (SDL_WaitForDeviceNotification(¬ification_data, s_mutexJoyStickEnum) ==
SDL_FALSE) {
238 #if SDL_JOYSTICK_XINPUT 244 for (userId = 0; userId < XUSER_MAX_COUNT; userId++) {
245 XINPUT_CAPABILITIES capabilities;
246 const DWORD
result = XINPUTGETCAPABILITIES(userId, XINPUT_FLAG_GAMEPAD, &capabilities);
248 if (bOpenedXInputDevices[userId] != available) {
250 bOpenedXInputDevices[userId] =
available;
260 if (s_bWindowsDeviceChanged || bXInputChanged) {
268 SDL_CleanupDeviceNotification(¬ification_data);
283 static void WINDOWS_JoystickDetect(
void);
284 static void WINDOWS_JoystickQuit(
void);
291 WINDOWS_JoystickInit(
void)
294 WINDOWS_JoystickQuit();
299 WINDOWS_JoystickQuit();
307 WINDOWS_JoystickDetect();
309 if (!s_threadJoystick) {
319 WINDOWS_JoystickGetCount(
void)
325 device = device->
pNext;
333 WINDOWS_JoystickDetect(
void)
338 if (!s_bDeviceAdded && !s_bDeviceRemoved) {
369 pListNext = pCurList->
pNext;
372 pCurList = pListNext;
375 if (s_bDeviceAdded) {
377 int device_index = 0;
380 while (pNewJoystick) {
393 pNewJoystick = pNewJoystick->
pNext;
400 WINDOWS_JoystickGetDeviceName(
int device_index)
404 for (; device_index > 0; device_index--)
405 device = device->
pNext;
411 WINDOWS_JoystickGetDevicePlayerIndex(
int device_index)
416 for (index = device_index; index > 0; index--)
417 device = device->
pNext;
424 WINDOWS_JoystickGetDeviceGUID(
int device_index)
429 for (index = device_index; index > 0; index--)
430 device = device->
pNext;
437 WINDOWS_JoystickGetDeviceInstanceID(
int device_index)
442 for (index = device_index; index > 0; index--)
443 device = device->
pNext;
454 WINDOWS_JoystickOpen(SDL_Joystick * joystick,
int device_index)
458 for (; device_index > 0; device_index--)
459 joystickdevice = joystickdevice->
pNext;
462 joystick->instance_id = joystickdevice->
nInstanceID;
465 if (joystick->hwdata ==
NULL) {
469 joystick->hwdata->guid = joystickdevice->
guid;
479 WINDOWS_JoystickRumble(SDL_Joystick * joystick,
Uint16 low_frequency_rumble,
Uint16 high_frequency_rumble,
Uint32 duration_ms)
481 if (joystick->hwdata->bXInputDevice) {
489 WINDOWS_JoystickUpdate(SDL_Joystick * joystick)
491 if (!joystick->hwdata) {
495 if (joystick->hwdata->bXInputDevice) {
504 WINDOWS_JoystickClose(SDL_Joystick * joystick)
506 if (joystick->hwdata->bXInputDevice) {
517 WINDOWS_JoystickQuit(
void)
525 device = device_next;
529 if (s_threadJoystick) {
541 s_condJoystickThread=
NULL;
542 s_mutexJoyStickEnum =
NULL;
543 s_threadJoystick =
NULL;
555 WINDOWS_JoystickInit,
556 WINDOWS_JoystickGetCount,
557 WINDOWS_JoystickDetect,
558 WINDOWS_JoystickGetDeviceName,
559 WINDOWS_JoystickGetDevicePlayerIndex,
560 WINDOWS_JoystickGetDeviceGUID,
561 WINDOWS_JoystickGetDeviceInstanceID,
562 WINDOWS_JoystickOpen,
563 WINDOWS_JoystickRumble,
564 WINDOWS_JoystickUpdate,
565 WINDOWS_JoystickClose,
566 WINDOWS_JoystickQuit,
JoyStick_DeviceData * SYS_Joystick
void SDL_PrivateJoystickRemoved(SDL_JoystickID device_instance)
GLuint GLsizei const GLchar * message
struct JoyStick_DeviceData * pNext
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
SDL_JoystickID nInstanceID
SDL_JoystickDriver SDL_WINDOWS_JoystickDriver
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)
#define SDL_CondBroadcast
void WINDOWS_AddJoystickDevice(JoyStick_DeviceData *device)
void SDL_PrivateJoystickAdded(SDL_JoystickID device_instance)
#define SDL_OutOfMemory()
void WIN_CoUninitialize(void)
int WIN_SetError(const char *prefix)
SDL_JoystickID SDL_GetNextJoystickInstanceID()
DIDEVICEINSTANCE dxdevice