21 #include "../../SDL_internal.h" 23 #if SDL_JOYSTICK_DINPUT || SDL_JOYSTICK_XINPUT 44 #include "../SDL_sysjoystick.h" 45 #if !SDL_EVENTS_DISABLED 46 #include "../../events/SDL_events_c.h" 48 #include "../../core/windows/SDL_windows.h" 49 #if !defined(__WINRT__) 58 #include "../../haptic/windows/SDL_dinputhaptic_c.h" 59 #include "../../haptic/windows/SDL_xinputhaptic_c.h" 62 #ifndef DEVICE_NOTIFY_WINDOW_HANDLE 63 #define DEVICE_NOTIFY_WINDOW_HANDLE 0x00000000 84 } SDL_DeviceNotificationData;
87 SDL_CleanupDeviceNotification(SDL_DeviceNotificationData *
data)
92 SDL_CreateDeviceNotification(SDL_DeviceNotificationData *
data)
98 SDL_CheckDeviceNotification(SDL_DeviceNotificationData *
data)
106 HRESULT coinitialized;
110 } SDL_DeviceNotificationData;
114 static LRESULT CALLBACK
115 SDL_PrivateJoystickDetectProc(HWND hwnd, UINT
message, WPARAM wParam, LPARAM lParam)
118 case WM_DEVICECHANGE:
120 case DBT_DEVICEARRIVAL:
121 if (((DEV_BROADCAST_HDR*)lParam)->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) {
125 case DBT_DEVICEREMOVECOMPLETE:
126 if (((DEV_BROADCAST_HDR*)lParam)->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) {
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_CheckDeviceNotification(SDL_DeviceNotificationData *data)
200 if (!data->messageWindow) {
204 while (PeekMessage(&msg, data->messageWindow, 0, 0, PM_NOREMOVE)) {
205 if (GetMessage(&msg, data->messageWindow, 0, 0) != 0) {
206 TranslateMessage(&msg);
207 DispatchMessage(&msg);
216 SDL_JoystickThread(
void *_data)
218 SDL_DeviceNotificationData notification_data;
220 #if SDL_JOYSTICK_XINPUT 221 SDL_bool bOpenedXInputDevices[XUSER_MAX_COUNT];
225 if (SDL_CreateDeviceNotification(¬ification_data) < 0) {
230 while (s_bJoystickThreadQuit ==
SDL_FALSE) {
235 SDL_CheckDeviceNotification(¬ification_data);
237 #if SDL_JOYSTICK_XINPUT 241 for (userId = 0; userId < XUSER_MAX_COUNT; userId++) {
242 XINPUT_CAPABILITIES capabilities;
243 const DWORD
result = XINPUTGETCAPABILITIES(userId, XINPUT_FLAG_GAMEPAD, &capabilities);
244 const SDL_bool available = (result == ERROR_SUCCESS);
245 if (bOpenedXInputDevices[userId] != available) {
247 bOpenedXInputDevices[userId] = available;
253 if (s_bWindowsDeviceChanged || bXInputChanged) {
265 SDL_CleanupDeviceNotification(¬ification_data);
275 SYS_Joystick = device;
303 if (!s_threadJoystick) {
306 #if defined(__WIN32__) && !defined(HAVE_LIBC) 307 #undef SDL_CreateThread 309 s_threadJoystick= SDL_CreateThread_REAL(SDL_JoystickThread,
"SDL_joystick",
NULL,
NULL,
NULL);
328 device = device->
pNext;
339 #if !SDL_EVENTS_DISABLED 344 if (!s_bDeviceAdded && !s_bDeviceRemoved) {
373 #if !SDL_EVENTS_DISABLED 385 pListNext = pCurList->
pNext;
388 pCurList = pListNext;
391 if (s_bDeviceAdded) {
393 int device_index = 0;
396 while (pNewJoystick) {
404 #if !SDL_EVENTS_DISABLED 409 event.jdevice.which = device_index;
418 pNewJoystick = pNewJoystick->
pNext;
429 for (; device_index > 0; device_index--)
430 device = device->
pNext;
442 for (index = device_index; index > 0; index--)
443 device = device->
pNext;
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;
482 return joystick->hwdata && !joystick->hwdata->removed;
488 if (!joystick->hwdata || joystick->hwdata->removed) {
492 if (joystick->hwdata->bXInputDevice) {
498 if (joystick->hwdata->removed) {
499 joystick->force_recentering =
SDL_TRUE;
507 if (joystick->hwdata->bXInputDevice) {
526 device = device_next;
530 if (s_threadJoystick) {
539 s_condJoystickThread=
NULL;
540 s_mutexJoyStickEnum =
NULL;
541 s_threadJoystick =
NULL;
555 for (index = device_index; index > 0; index--)
556 device = device->
pNext;
564 return joystick->hwdata->guid;
JoyStick_DeviceData * SYS_Joystick
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
#define SDL_CondWaitTimeout
#define SDL_GetEventState(type)
HRESULT WIN_CoInitialize(void)
uint8_t Uint8
An unsigned 8-bit integer type.
SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
SDL_EventFilter SDL_EventOK
void SDL_SYS_JoystickDetect()
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)