21 #include "../../SDL_internal.h" 23 #if SDL_JOYSTICK_DINPUT || SDL_JOYSTICK_XINPUT 43 #include "../SDL_sysjoystick.h" 44 #include "../../thread/SDL_systhread.h" 45 #include "../../core/windows/SDL_windows.h" 46 #if !defined(__WINRT__) 55 #include "../../haptic/windows/SDL_dinputhaptic_c.h" 56 #include "../../haptic/windows/SDL_xinputhaptic_c.h" 59 #ifndef DEVICE_NOTIFY_WINDOW_HANDLE 60 #define DEVICE_NOTIFY_WINDOW_HANDLE 0x00000000 81 } SDL_DeviceNotificationData;
84 SDL_CleanupDeviceNotification(SDL_DeviceNotificationData *
data)
89 SDL_CreateDeviceNotification(SDL_DeviceNotificationData *
data)
95 SDL_CheckDeviceNotification(SDL_DeviceNotificationData *
data)
103 HRESULT coinitialized;
107 } SDL_DeviceNotificationData;
111 static LRESULT CALLBACK
112 SDL_PrivateJoystickDetectProc(HWND hwnd, UINT
message, WPARAM wParam, LPARAM lParam)
115 case WM_DEVICECHANGE:
117 case DBT_DEVICEARRIVAL:
118 if (((DEV_BROADCAST_HDR*)lParam)->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) {
122 case DBT_DEVICEREMOVECOMPLETE:
123 if (((DEV_BROADCAST_HDR*)lParam)->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) {
131 return DefWindowProc (hwnd, message, wParam, lParam);
135 SDL_CleanupDeviceNotification(SDL_DeviceNotificationData *
data)
138 UnregisterDeviceNotification(data->hNotify);
140 if (data->messageWindow)
141 DestroyWindow(data->messageWindow);
143 UnregisterClass(data->wincl.lpszClassName, data->wincl.hInstance);
145 if (data->coinitialized ==
S_OK) {
151 SDL_CreateDeviceNotification(SDL_DeviceNotificationData *data)
153 DEV_BROADCAST_DEVICEINTERFACE dbh;
154 GUID GUID_DEVINTERFACE_HID = { 0x4D1E55B2L, 0xF16F, 0x11CF, { 0x88, 0xCB, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30 } };
160 data->wincl.hInstance = GetModuleHandle(
NULL);
161 data->wincl.lpszClassName = L
"Message";
162 data->wincl.lpfnWndProc = SDL_PrivateJoystickDetectProc;
163 data->wincl.cbSize =
sizeof (WNDCLASSEX);
165 if (!RegisterClassEx(&data->wincl)) {
166 WIN_SetError(
"Failed to create register class for joystick autodetect");
167 SDL_CleanupDeviceNotification(data);
171 data->messageWindow = (HWND)CreateWindowEx(0, L
"Message",
NULL, 0, 0, 0, 0, 0, HWND_MESSAGE,
NULL,
NULL,
NULL);
172 if (!data->messageWindow) {
173 WIN_SetError(
"Failed to create message window for joystick autodetect");
174 SDL_CleanupDeviceNotification(data);
179 dbh.dbcc_size =
sizeof(dbh);
180 dbh.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
181 dbh.dbcc_classguid = GUID_DEVINTERFACE_HID;
183 data->hNotify = RegisterDeviceNotification(data->messageWindow, &dbh, DEVICE_NOTIFY_WINDOW_HANDLE);
184 if (!data->hNotify) {
185 WIN_SetError(
"Failed to create notify device for joystick autodetect");
186 SDL_CleanupDeviceNotification(data);
193 SDL_CheckDeviceNotification(SDL_DeviceNotificationData *data)
197 if (!data->messageWindow) {
201 while (PeekMessage(&msg, data->messageWindow, 0, 0, PM_NOREMOVE)) {
202 if (GetMessage(&msg, data->messageWindow, 0, 0) != 0) {
203 TranslateMessage(&msg);
204 DispatchMessage(&msg);
213 SDL_JoystickThread(
void *_data)
215 SDL_DeviceNotificationData notification_data;
217 #if SDL_JOYSTICK_XINPUT 218 SDL_bool bOpenedXInputDevices[XUSER_MAX_COUNT];
222 if (SDL_CreateDeviceNotification(¬ification_data) < 0) {
227 while (s_bJoystickThreadQuit ==
SDL_FALSE) {
232 SDL_CheckDeviceNotification(¬ification_data);
234 #if SDL_JOYSTICK_XINPUT 238 for (userId = 0; userId < XUSER_MAX_COUNT; userId++) {
239 XINPUT_CAPABILITIES capabilities;
240 const DWORD
result = XINPUTGETCAPABILITIES(userId, XINPUT_FLAG_GAMEPAD, &capabilities);
241 const SDL_bool available = (result == ERROR_SUCCESS);
242 if (bOpenedXInputDevices[userId] != available) {
244 bOpenedXInputDevices[userId] = available;
250 if (s_bWindowsDeviceChanged || bXInputChanged) {
262 SDL_CleanupDeviceNotification(¬ification_data);
272 SYS_Joystick = device;
300 if (!s_threadJoystick) {
316 device = device->
pNext;
329 if (!s_bDeviceAdded && !s_bDeviceRemoved) {
360 pListNext = pCurList->
pNext;
363 pCurList = pListNext;
366 if (s_bDeviceAdded) {
368 int device_index = 0;
371 while (pNewJoystick) {
384 pNewJoystick = pNewJoystick->
pNext;
395 for (; device_index > 0; device_index--)
396 device = device->
pNext;
408 for (index = device_index; index > 0; index--)
409 device = device->
pNext;
424 for (; device_index > 0; device_index--)
425 joystickdevice = joystickdevice->
pNext;
428 joystick->instance_id = joystickdevice->
nInstanceID;
431 if (joystick->hwdata ==
NULL) {
435 joystick->hwdata->guid = joystickdevice->
guid;
448 return joystick->hwdata && !joystick->hwdata->removed;
454 if (!joystick->hwdata || joystick->hwdata->removed) {
458 if (joystick->hwdata->bXInputDevice) {
464 if (joystick->hwdata->removed) {
465 joystick->force_recentering =
SDL_TRUE;
473 if (joystick->hwdata->bXInputDevice) {
492 device = device_next;
496 if (s_threadJoystick) {
505 s_condJoystickThread=
NULL;
506 s_mutexJoyStickEnum =
NULL;
507 s_threadJoystick =
NULL;
524 for (index = device_index; index > 0; index--)
525 device = device->
pNext;
533 return joystick->hwdata->guid;
JoyStick_DeviceData * SYS_Joystick
void SDL_PrivateJoystickRemoved(SDL_JoystickID device_instance)
int SDL_SYS_NumJoysticks()
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
SDL_Thread * SDL_CreateThreadInternal(int(*fn)(void *), const char *name, const size_t stacksize, void *data)
#define SDL_CondWaitTimeout
HRESULT WIN_CoInitialize(void)
uint8_t Uint8
An unsigned 8-bit integer type.
SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
void SDL_SYS_JoystickDetect()
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 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)