|
@@ -37,6 +37,7 @@ |
|
|
#include "SDL_endian.h" |
|
|
#include "SDL_events.h" |
|
|
#include "SDL_hints.h" |
|
|
#include "SDL_mutex.h" |
|
|
#include "SDL_timer.h" |
|
|
#include "../usb_ids.h" |
|
|
#include "../SDL_sysjoystick.h" |
|
@@ -84,12 +85,10 @@ typedef struct WindowsGamingInputGamepadState WindowsGamingInputGamepadState; |
|
|
#define GIDC_REMOVAL 2 |
|
|
#endif |
|
|
|
|
|
/* external variables referenced. */ |
|
|
extern HWND SDL_HelperWindow; |
|
|
|
|
|
|
|
|
static SDL_bool SDL_RAWINPUT_inited = SDL_FALSE; |
|
|
static int SDL_RAWINPUT_numjoysticks = 0; |
|
|
static SDL_mutex *SDL_RAWINPUT_mutex = NULL; |
|
|
|
|
|
static void RAWINPUT_JoystickClose(SDL_Joystick *joystick); |
|
|
|
|
@@ -625,40 +624,10 @@ RAWINPUT_QuitWindowsGamingInput(RAWINPUT_DeviceContext *ctx) |
|
|
#endif /* SDL_JOYSTICK_RAWINPUT_WGI */ |
|
|
|
|
|
|
|
|
/* Most of the time the raw input messages will get dispatched in the main event loop, |
|
|
* but sometimes we want to get any pending device change messages immediately. |
|
|
*/ |
|
|
static void |
|
|
RAWINPUT_GetPendingDeviceChanges(void) |
|
|
{ |
|
|
MSG msg; |
|
|
while (PeekMessage(&msg, SDL_HelperWindow, WM_INPUT_DEVICE_CHANGE, WM_INPUT_DEVICE_CHANGE + 1, PM_REMOVE)) { |
|
|
TranslateMessage(&msg); |
|
|
DispatchMessage(&msg); |
|
|
} |
|
|
} |
|
|
|
|
|
static SDL_bool pump_device_events; |
|
|
static void |
|
|
RAWINPUT_GetPendingDeviceInput(void) |
|
|
{ |
|
|
if (pump_device_events) { |
|
|
MSG msg; |
|
|
while (PeekMessage(&msg, SDL_HelperWindow, WM_INPUT, WM_INPUT + 1, PM_REMOVE)) { |
|
|
TranslateMessage(&msg); |
|
|
DispatchMessage(&msg); |
|
|
} |
|
|
pump_device_events = SDL_FALSE; |
|
|
} |
|
|
} |
|
|
|
|
|
static int |
|
|
RAWINPUT_JoystickInit(void) |
|
|
{ |
|
|
int ii; |
|
|
RAWINPUTDEVICE rid[SDL_arraysize(subscribed_devices)]; |
|
|
SDL_assert(!SDL_RAWINPUT_inited); |
|
|
SDL_assert(SDL_HelperWindow); |
|
|
|
|
|
if (!SDL_GetHintBoolean(SDL_HINT_JOYSTICK_RAWINPUT, SDL_TRUE)) { |
|
|
return -1; |
|
@@ -668,25 +637,9 @@ RAWINPUT_JoystickInit(void) |
|
|
return -1; |
|
|
} |
|
|
|
|
|
for (ii = 0; ii < SDL_arraysize(subscribed_devices); ii++) { |
|
|
rid[ii].usUsagePage = USB_USAGEPAGE_GENERIC_DESKTOP; |
|
|
rid[ii].usUsage = subscribed_devices[ii]; |
|
|
rid[ii].dwFlags = RIDEV_DEVNOTIFY | RIDEV_INPUTSINK; /* Receive messages when in background, including device add/remove */ |
|
|
rid[ii].hwndTarget = SDL_HelperWindow; |
|
|
} |
|
|
|
|
|
if (!RegisterRawInputDevices(rid, SDL_arraysize(rid), sizeof(RAWINPUTDEVICE))) { |
|
|
SDL_SetError("Couldn't initialize RAWINPUT"); |
|
|
WIN_UnloadHIDDLL(); |
|
|
return -1; |
|
|
} |
|
|
|
|
|
SDL_RAWINPUT_mutex = SDL_CreateMutex(); |
|
|
SDL_RAWINPUT_inited = SDL_TRUE; |
|
|
|
|
|
/* Get initial controller connect messages */ |
|
|
RAWINPUT_GetPendingDeviceChanges(); |
|
|
pump_device_events = SDL_TRUE; |
|
|
|
|
|
return 0; |
|
|
} |
|
|
|
|
@@ -930,8 +883,6 @@ RAWINPUT_PostUpdate(void) |
|
|
guide_button_candidate.joystick = NULL; |
|
|
|
|
|
#endif /* SDL_JOYSTICK_RAWINPUT_MATCHING */ |
|
|
|
|
|
pump_device_events = SDL_TRUE; |
|
|
} |
|
|
|
|
|
SDL_bool |
|
@@ -945,9 +896,6 @@ RAWINPUT_IsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, co |
|
|
{ |
|
|
SDL_RAWINPUT_Device *device; |
|
|
|
|
|
/* Make sure the device list is completely up to date when we check for device presence */ |
|
|
RAWINPUT_GetPendingDeviceChanges(); |
|
|
|
|
|
/* If we're being asked about a device, that means another API just detected one, so rescan */ |
|
|
#ifdef SDL_JOYSTICK_RAWINPUT_XINPUT |
|
|
xinput_device_change = SDL_TRUE; |
|
@@ -983,8 +931,6 @@ RAWINPUT_IsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, co |
|
|
static void |
|
|
RAWINPUT_JoystickDetect(void) |
|
|
{ |
|
|
RAWINPUT_GetPendingDeviceChanges(); |
|
|
|
|
|
RAWINPUT_PostUpdate(); |
|
|
} |
|
|
|
|
@@ -1727,8 +1673,6 @@ RAWINPUT_UpdateOtherAPIs(SDL_Joystick *joystick) |
|
|
static void |
|
|
RAWINPUT_JoystickUpdate(SDL_Joystick *joystick) |
|
|
{ |
|
|
RAWINPUT_GetPendingDeviceInput(); |
|
|
|
|
|
RAWINPUT_UpdateOtherAPIs(joystick); |
|
|
} |
|
|
|
|
@@ -1776,74 +1720,115 @@ RAWINPUT_JoystickClose(SDL_Joystick *joystick) |
|
|
} |
|
|
} |
|
|
|
|
|
LRESULT RAWINPUT_WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) |
|
|
SDL_bool |
|
|
RAWINPUT_RegisterNotifications(HWND hWnd) |
|
|
{ |
|
|
if (!SDL_RAWINPUT_inited) |
|
|
return -1; |
|
|
RAWINPUTDEVICE rid[SDL_arraysize(subscribed_devices)]; |
|
|
int i; |
|
|
|
|
|
switch (msg) |
|
|
{ |
|
|
case WM_INPUT_DEVICE_CHANGE: |
|
|
{ |
|
|
HANDLE hDevice = (HANDLE)lParam; |
|
|
switch (wParam) { |
|
|
case GIDC_ARRIVAL: |
|
|
RAWINPUT_AddDevice(hDevice); |
|
|
break; |
|
|
case GIDC_REMOVAL: { |
|
|
SDL_RAWINPUT_Device *device; |
|
|
device = RAWINPUT_DeviceFromHandle(hDevice); |
|
|
if (device) { |
|
|
RAWINPUT_DelDevice(device, SDL_TRUE); |
|
|
for (i = 0; i < SDL_arraysize(subscribed_devices); i++) { |
|
|
rid[i].usUsagePage = USB_USAGEPAGE_GENERIC_DESKTOP; |
|
|
rid[i].usUsage = subscribed_devices[i]; |
|
|
rid[i].dwFlags = RIDEV_DEVNOTIFY | RIDEV_INPUTSINK; /* Receive messages when in background, including device add/remove */ |
|
|
rid[i].hwndTarget = hWnd; |
|
|
} |
|
|
|
|
|
if (!RegisterRawInputDevices(rid, SDL_arraysize(rid), sizeof(RAWINPUTDEVICE))) { |
|
|
SDL_SetError("Couldn't register for raw input events"); |
|
|
return SDL_FALSE; |
|
|
} |
|
|
return SDL_TRUE; |
|
|
} |
|
|
|
|
|
void |
|
|
RAWINPUT_UnregisterNotifications() |
|
|
{ |
|
|
int i; |
|
|
RAWINPUTDEVICE rid[SDL_arraysize(subscribed_devices)]; |
|
|
|
|
|
for (i = 0; i < SDL_arraysize(subscribed_devices); i++) { |
|
|
rid[i].usUsagePage = USB_USAGEPAGE_GENERIC_DESKTOP; |
|
|
rid[i].usUsage = subscribed_devices[i]; |
|
|
rid[i].dwFlags = RIDEV_REMOVE; |
|
|
rid[i].hwndTarget = NULL; |
|
|
} |
|
|
|
|
|
if (!RegisterRawInputDevices(rid, SDL_arraysize(rid), sizeof(RAWINPUTDEVICE))) { |
|
|
SDL_SetError("Couldn't unregister for raw input events"); |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
LRESULT CALLBACK |
|
|
RAWINPUT_WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) |
|
|
{ |
|
|
LRESULT result = -1; |
|
|
|
|
|
SDL_LockMutex(SDL_RAWINPUT_mutex); |
|
|
|
|
|
if (SDL_RAWINPUT_inited) { |
|
|
switch (msg) { |
|
|
case WM_INPUT_DEVICE_CHANGE: |
|
|
{ |
|
|
HANDLE hDevice = (HANDLE)lParam; |
|
|
switch (wParam) { |
|
|
case GIDC_ARRIVAL: |
|
|
RAWINPUT_AddDevice(hDevice); |
|
|
break; |
|
|
case GIDC_REMOVAL: |
|
|
{ |
|
|
SDL_RAWINPUT_Device *device; |
|
|
device = RAWINPUT_DeviceFromHandle(hDevice); |
|
|
if (device) { |
|
|
RAWINPUT_DelDevice(device, SDL_TRUE); |
|
|
} |
|
|
break; |
|
|
} |
|
|
default: |
|
|
break; |
|
|
} |
|
|
} break; |
|
|
default: |
|
|
return 0; |
|
|
} |
|
|
} |
|
|
return 0; |
|
|
|
|
|
case WM_INPUT: |
|
|
{ |
|
|
Uint8 data[sizeof(RAWINPUTHEADER) + sizeof(RAWHID) + USB_PACKET_LENGTH]; |
|
|
UINT buffer_size = SDL_arraysize(data); |
|
|
|
|
|
if ((int)GetRawInputData((HRAWINPUT)lParam, RID_INPUT, data, &buffer_size, sizeof(RAWINPUTHEADER)) > 0) { |
|
|
PRAWINPUT raw_input = (PRAWINPUT)data; |
|
|
SDL_RAWINPUT_Device *device = RAWINPUT_DeviceFromHandle(raw_input->header.hDevice); |
|
|
if (device) { |
|
|
SDL_Joystick *joystick = device->joystick; |
|
|
if (joystick) { |
|
|
RAWINPUT_HandleStatePacket(joystick, raw_input->data.hid.bRawData, raw_input->data.hid.dwSizeHid); |
|
|
result = 0; |
|
|
break; |
|
|
|
|
|
case WM_INPUT: |
|
|
{ |
|
|
Uint8 data[sizeof(RAWINPUTHEADER) + sizeof(RAWHID) + USB_PACKET_LENGTH]; |
|
|
UINT buffer_size = SDL_arraysize(data); |
|
|
|
|
|
if ((int)GetRawInputData((HRAWINPUT)lParam, RID_INPUT, data, &buffer_size, sizeof(RAWINPUTHEADER)) > 0) { |
|
|
PRAWINPUT raw_input = (PRAWINPUT)data; |
|
|
SDL_RAWINPUT_Device *device = RAWINPUT_DeviceFromHandle(raw_input->header.hDevice); |
|
|
if (device) { |
|
|
SDL_Joystick *joystick = device->joystick; |
|
|
if (joystick) { |
|
|
RAWINPUT_HandleStatePacket(joystick, raw_input->data.hid.bRawData, raw_input->data.hid.dwSizeHid); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
result = 0; |
|
|
break; |
|
|
} |
|
|
return 0; |
|
|
} |
|
|
return -1; |
|
|
|
|
|
SDL_UnlockMutex(SDL_RAWINPUT_mutex); |
|
|
|
|
|
if (result >= 0) { |
|
|
return result; |
|
|
} |
|
|
return CallWindowProc(DefWindowProc, hWnd, msg, wParam, lParam); |
|
|
} |
|
|
|
|
|
static void |
|
|
RAWINPUT_JoystickQuit(void) |
|
|
{ |
|
|
int ii; |
|
|
RAWINPUTDEVICE rid[SDL_arraysize(subscribed_devices)]; |
|
|
|
|
|
if (!SDL_RAWINPUT_inited) |
|
|
if (!SDL_RAWINPUT_inited) { |
|
|
return; |
|
|
|
|
|
for (ii = 0; ii < SDL_arraysize(subscribed_devices); ii++) { |
|
|
rid[ii].usUsagePage = USB_USAGEPAGE_GENERIC_DESKTOP; |
|
|
rid[ii].usUsage = subscribed_devices[ii]; |
|
|
rid[ii].dwFlags = RIDEV_REMOVE; |
|
|
rid[ii].hwndTarget = NULL; |
|
|
} |
|
|
|
|
|
if (!RegisterRawInputDevices(rid, SDL_arraysize(rid), sizeof(RAWINPUTDEVICE))) { |
|
|
SDL_Log("Couldn't un-register RAWINPUT"); |
|
|
} |
|
|
|
|
|
SDL_LockMutex(SDL_RAWINPUT_mutex); |
|
|
|
|
|
while (SDL_RAWINPUT_devices) { |
|
|
RAWINPUT_DelDevice(SDL_RAWINPUT_devices, SDL_FALSE); |
|
|
} |
|
@@ -1853,6 +1838,11 @@ RAWINPUT_JoystickQuit(void) |
|
|
SDL_RAWINPUT_numjoysticks = 0; |
|
|
|
|
|
SDL_RAWINPUT_inited = SDL_FALSE; |
|
|
|
|
|
SDL_UnlockMutex(SDL_RAWINPUT_mutex); |
|
|
SDL_DestroyMutex(SDL_RAWINPUT_mutex); |
|
|
SDL_RAWINPUT_mutex = NULL; |
|
|
|
|
|
} |
|
|
|
|
|
static SDL_bool |
|
|