1.1 --- a/include/SDL_config_windows.h Fri Nov 27 11:33:53 2020 -0800
1.2 +++ b/include/SDL_config_windows.h Fri Nov 27 13:08:40 2020 -0800
1.3 @@ -215,7 +215,9 @@
1.4 /* Enable various input drivers */
1.5 #define SDL_JOYSTICK_DINPUT 1
1.6 #define SDL_JOYSTICK_HIDAPI 1
1.7 +#ifndef __WINRT__
1.8 #define SDL_JOYSTICK_RAWINPUT 1
1.9 +#endif
1.10 #define SDL_JOYSTICK_VIRTUAL 1
1.11 #ifdef SDL_WINDOWS10_SDK
1.12 #define SDL_JOYSTICK_WGI 1
2.1 --- a/src/joystick/hidapi/SDL_hidapijoystick.c Fri Nov 27 11:33:53 2020 -0800
2.2 +++ b/src/joystick/hidapi/SDL_hidapijoystick.c Fri Nov 27 13:08:40 2020 -0800
2.3 @@ -192,7 +192,7 @@
2.4 #if defined(__WIN32__)
2.5 SDL_HIDAPI_discovery.m_nThreadID = SDL_ThreadID();
2.6
2.7 - SDL_memset(&SDL_HIDAPI_discovery.m_wndClass, 0x0, sizeof(SDL_HIDAPI_discovery.m_wndClass));
2.8 + SDL_zero(SDL_HIDAPI_discovery.m_wndClass);
2.9 SDL_HIDAPI_discovery.m_wndClass.hInstance = GetModuleHandle(NULL);
2.10 SDL_HIDAPI_discovery.m_wndClass.lpszClassName = "SDL_HIDAPI_DEVICE_DETECTION";
2.11 SDL_HIDAPI_discovery.m_wndClass.lpfnWndProc = ControllerWndProc; /* This function is called by windows */
2.12 @@ -203,8 +203,8 @@
2.13
2.14 {
2.15 DEV_BROADCAST_DEVICEINTERFACE_A devBroadcast;
2.16 - SDL_memset( &devBroadcast, 0x0, sizeof( devBroadcast ) );
2.17
2.18 + SDL_zero(devBroadcast);
2.19 devBroadcast.dbcc_size = sizeof( devBroadcast );
2.20 devBroadcast.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
2.21 devBroadcast.dbcc_classguid = GUID_DEVINTERFACE_USB_DEVICE;
3.1 --- a/src/joystick/windows/SDL_rawinputjoystick.c Fri Nov 27 11:33:53 2020 -0800
3.2 +++ b/src/joystick/windows/SDL_rawinputjoystick.c Fri Nov 27 13:08:40 2020 -0800
3.3 @@ -37,6 +37,7 @@
3.4 #include "SDL_endian.h"
3.5 #include "SDL_events.h"
3.6 #include "SDL_hints.h"
3.7 +#include "SDL_mutex.h"
3.8 #include "SDL_timer.h"
3.9 #include "../usb_ids.h"
3.10 #include "../SDL_sysjoystick.h"
3.11 @@ -84,12 +85,10 @@
3.12 #define GIDC_REMOVAL 2
3.13 #endif
3.14
3.15 -/* external variables referenced. */
3.16 -extern HWND SDL_HelperWindow;
3.17 -
3.18
3.19 static SDL_bool SDL_RAWINPUT_inited = SDL_FALSE;
3.20 static int SDL_RAWINPUT_numjoysticks = 0;
3.21 +static SDL_mutex *SDL_RAWINPUT_mutex = NULL;
3.22
3.23 static void RAWINPUT_JoystickClose(SDL_Joystick *joystick);
3.24
3.25 @@ -625,40 +624,10 @@
3.26 #endif /* SDL_JOYSTICK_RAWINPUT_WGI */
3.27
3.28
3.29 -/* Most of the time the raw input messages will get dispatched in the main event loop,
3.30 - * but sometimes we want to get any pending device change messages immediately.
3.31 - */
3.32 -static void
3.33 -RAWINPUT_GetPendingDeviceChanges(void)
3.34 -{
3.35 - MSG msg;
3.36 - while (PeekMessage(&msg, SDL_HelperWindow, WM_INPUT_DEVICE_CHANGE, WM_INPUT_DEVICE_CHANGE + 1, PM_REMOVE)) {
3.37 - TranslateMessage(&msg);
3.38 - DispatchMessage(&msg);
3.39 - }
3.40 -}
3.41 -
3.42 -static SDL_bool pump_device_events;
3.43 -static void
3.44 -RAWINPUT_GetPendingDeviceInput(void)
3.45 -{
3.46 - if (pump_device_events) {
3.47 - MSG msg;
3.48 - while (PeekMessage(&msg, SDL_HelperWindow, WM_INPUT, WM_INPUT + 1, PM_REMOVE)) {
3.49 - TranslateMessage(&msg);
3.50 - DispatchMessage(&msg);
3.51 - }
3.52 - pump_device_events = SDL_FALSE;
3.53 - }
3.54 -}
3.55 -
3.56 static int
3.57 RAWINPUT_JoystickInit(void)
3.58 {
3.59 - int ii;
3.60 - RAWINPUTDEVICE rid[SDL_arraysize(subscribed_devices)];
3.61 SDL_assert(!SDL_RAWINPUT_inited);
3.62 - SDL_assert(SDL_HelperWindow);
3.63
3.64 if (!SDL_GetHintBoolean(SDL_HINT_JOYSTICK_RAWINPUT, SDL_TRUE)) {
3.65 return -1;
3.66 @@ -668,25 +637,9 @@
3.67 return -1;
3.68 }
3.69
3.70 - for (ii = 0; ii < SDL_arraysize(subscribed_devices); ii++) {
3.71 - rid[ii].usUsagePage = USB_USAGEPAGE_GENERIC_DESKTOP;
3.72 - rid[ii].usUsage = subscribed_devices[ii];
3.73 - rid[ii].dwFlags = RIDEV_DEVNOTIFY | RIDEV_INPUTSINK; /* Receive messages when in background, including device add/remove */
3.74 - rid[ii].hwndTarget = SDL_HelperWindow;
3.75 - }
3.76 -
3.77 - if (!RegisterRawInputDevices(rid, SDL_arraysize(rid), sizeof(RAWINPUTDEVICE))) {
3.78 - SDL_SetError("Couldn't initialize RAWINPUT");
3.79 - WIN_UnloadHIDDLL();
3.80 - return -1;
3.81 - }
3.82 -
3.83 + SDL_RAWINPUT_mutex = SDL_CreateMutex();
3.84 SDL_RAWINPUT_inited = SDL_TRUE;
3.85
3.86 - /* Get initial controller connect messages */
3.87 - RAWINPUT_GetPendingDeviceChanges();
3.88 - pump_device_events = SDL_TRUE;
3.89 -
3.90 return 0;
3.91 }
3.92
3.93 @@ -930,8 +883,6 @@
3.94 guide_button_candidate.joystick = NULL;
3.95
3.96 #endif /* SDL_JOYSTICK_RAWINPUT_MATCHING */
3.97 -
3.98 - pump_device_events = SDL_TRUE;
3.99 }
3.100
3.101 SDL_bool
3.102 @@ -945,9 +896,6 @@
3.103 {
3.104 SDL_RAWINPUT_Device *device;
3.105
3.106 - /* Make sure the device list is completely up to date when we check for device presence */
3.107 - RAWINPUT_GetPendingDeviceChanges();
3.108 -
3.109 /* If we're being asked about a device, that means another API just detected one, so rescan */
3.110 #ifdef SDL_JOYSTICK_RAWINPUT_XINPUT
3.111 xinput_device_change = SDL_TRUE;
3.112 @@ -983,8 +931,6 @@
3.113 static void
3.114 RAWINPUT_JoystickDetect(void)
3.115 {
3.116 - RAWINPUT_GetPendingDeviceChanges();
3.117 -
3.118 RAWINPUT_PostUpdate();
3.119 }
3.120
3.121 @@ -1727,8 +1673,6 @@
3.122 static void
3.123 RAWINPUT_JoystickUpdate(SDL_Joystick *joystick)
3.124 {
3.125 - RAWINPUT_GetPendingDeviceInput();
3.126 -
3.127 RAWINPUT_UpdateOtherAPIs(joystick);
3.128 }
3.129
3.130 @@ -1776,74 +1720,115 @@
3.131 }
3.132 }
3.133
3.134 -LRESULT RAWINPUT_WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
3.135 +SDL_bool
3.136 +RAWINPUT_RegisterNotifications(HWND hWnd)
3.137 {
3.138 - if (!SDL_RAWINPUT_inited)
3.139 - return -1;
3.140 + RAWINPUTDEVICE rid[SDL_arraysize(subscribed_devices)];
3.141 + int i;
3.142 +
3.143 + for (i = 0; i < SDL_arraysize(subscribed_devices); i++) {
3.144 + rid[i].usUsagePage = USB_USAGEPAGE_GENERIC_DESKTOP;
3.145 + rid[i].usUsage = subscribed_devices[i];
3.146 + rid[i].dwFlags = RIDEV_DEVNOTIFY | RIDEV_INPUTSINK; /* Receive messages when in background, including device add/remove */
3.147 + rid[i].hwndTarget = hWnd;
3.148 + }
3.149 +
3.150 + if (!RegisterRawInputDevices(rid, SDL_arraysize(rid), sizeof(RAWINPUTDEVICE))) {
3.151 + SDL_SetError("Couldn't register for raw input events");
3.152 + return SDL_FALSE;
3.153 + }
3.154 + return SDL_TRUE;
3.155 +}
3.156 +
3.157 +void
3.158 +RAWINPUT_UnregisterNotifications()
3.159 +{
3.160 + int i;
3.161 + RAWINPUTDEVICE rid[SDL_arraysize(subscribed_devices)];
3.162
3.163 - switch (msg)
3.164 - {
3.165 - case WM_INPUT_DEVICE_CHANGE:
3.166 - {
3.167 - HANDLE hDevice = (HANDLE)lParam;
3.168 - switch (wParam) {
3.169 - case GIDC_ARRIVAL:
3.170 - RAWINPUT_AddDevice(hDevice);
3.171 - break;
3.172 - case GIDC_REMOVAL: {
3.173 - SDL_RAWINPUT_Device *device;
3.174 - device = RAWINPUT_DeviceFromHandle(hDevice);
3.175 - if (device) {
3.176 - RAWINPUT_DelDevice(device, SDL_TRUE);
3.177 + for (i = 0; i < SDL_arraysize(subscribed_devices); i++) {
3.178 + rid[i].usUsagePage = USB_USAGEPAGE_GENERIC_DESKTOP;
3.179 + rid[i].usUsage = subscribed_devices[i];
3.180 + rid[i].dwFlags = RIDEV_REMOVE;
3.181 + rid[i].hwndTarget = NULL;
3.182 + }
3.183 +
3.184 + if (!RegisterRawInputDevices(rid, SDL_arraysize(rid), sizeof(RAWINPUTDEVICE))) {
3.185 + SDL_SetError("Couldn't unregister for raw input events");
3.186 + return;
3.187 + }
3.188 +}
3.189 +
3.190 +LRESULT CALLBACK
3.191 +RAWINPUT_WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
3.192 +{
3.193 + LRESULT result = -1;
3.194 +
3.195 + SDL_LockMutex(SDL_RAWINPUT_mutex);
3.196 +
3.197 + if (SDL_RAWINPUT_inited) {
3.198 + switch (msg) {
3.199 + case WM_INPUT_DEVICE_CHANGE:
3.200 + {
3.201 + HANDLE hDevice = (HANDLE)lParam;
3.202 + switch (wParam) {
3.203 + case GIDC_ARRIVAL:
3.204 + RAWINPUT_AddDevice(hDevice);
3.205 + break;
3.206 + case GIDC_REMOVAL:
3.207 + {
3.208 + SDL_RAWINPUT_Device *device;
3.209 + device = RAWINPUT_DeviceFromHandle(hDevice);
3.210 + if (device) {
3.211 + RAWINPUT_DelDevice(device, SDL_TRUE);
3.212 + }
3.213 + break;
3.214 }
3.215 - } break;
3.216 - default:
3.217 - return 0;
3.218 + default:
3.219 + break;
3.220 + }
3.221 }
3.222 - }
3.223 - return 0;
3.224 + result = 0;
3.225 + break;
3.226
3.227 - case WM_INPUT:
3.228 - {
3.229 - Uint8 data[sizeof(RAWINPUTHEADER) + sizeof(RAWHID) + USB_PACKET_LENGTH];
3.230 - UINT buffer_size = SDL_arraysize(data);
3.231 + case WM_INPUT:
3.232 + {
3.233 + Uint8 data[sizeof(RAWINPUTHEADER) + sizeof(RAWHID) + USB_PACKET_LENGTH];
3.234 + UINT buffer_size = SDL_arraysize(data);
3.235
3.236 - if ((int)GetRawInputData((HRAWINPUT)lParam, RID_INPUT, data, &buffer_size, sizeof(RAWINPUTHEADER)) > 0) {
3.237 - PRAWINPUT raw_input = (PRAWINPUT)data;
3.238 - SDL_RAWINPUT_Device *device = RAWINPUT_DeviceFromHandle(raw_input->header.hDevice);
3.239 - if (device) {
3.240 - SDL_Joystick *joystick = device->joystick;
3.241 - if (joystick) {
3.242 - RAWINPUT_HandleStatePacket(joystick, raw_input->data.hid.bRawData, raw_input->data.hid.dwSizeHid);
3.243 + if ((int)GetRawInputData((HRAWINPUT)lParam, RID_INPUT, data, &buffer_size, sizeof(RAWINPUTHEADER)) > 0) {
3.244 + PRAWINPUT raw_input = (PRAWINPUT)data;
3.245 + SDL_RAWINPUT_Device *device = RAWINPUT_DeviceFromHandle(raw_input->header.hDevice);
3.246 + if (device) {
3.247 + SDL_Joystick *joystick = device->joystick;
3.248 + if (joystick) {
3.249 + RAWINPUT_HandleStatePacket(joystick, raw_input->data.hid.bRawData, raw_input->data.hid.dwSizeHid);
3.250 + }
3.251 }
3.252 }
3.253 }
3.254 + result = 0;
3.255 + break;
3.256 }
3.257 - return 0;
3.258 }
3.259 - return -1;
3.260 +
3.261 + SDL_UnlockMutex(SDL_RAWINPUT_mutex);
3.262 +
3.263 + if (result >= 0) {
3.264 + return result;
3.265 + }
3.266 + return CallWindowProc(DefWindowProc, hWnd, msg, wParam, lParam);
3.267 }
3.268
3.269 static void
3.270 RAWINPUT_JoystickQuit(void)
3.271 {
3.272 - int ii;
3.273 - RAWINPUTDEVICE rid[SDL_arraysize(subscribed_devices)];
3.274 -
3.275 - if (!SDL_RAWINPUT_inited)
3.276 + if (!SDL_RAWINPUT_inited) {
3.277 return;
3.278 -
3.279 - for (ii = 0; ii < SDL_arraysize(subscribed_devices); ii++) {
3.280 - rid[ii].usUsagePage = USB_USAGEPAGE_GENERIC_DESKTOP;
3.281 - rid[ii].usUsage = subscribed_devices[ii];
3.282 - rid[ii].dwFlags = RIDEV_REMOVE;
3.283 - rid[ii].hwndTarget = NULL;
3.284 }
3.285
3.286 - if (!RegisterRawInputDevices(rid, SDL_arraysize(rid), sizeof(RAWINPUTDEVICE))) {
3.287 - SDL_Log("Couldn't un-register RAWINPUT");
3.288 - }
3.289 -
3.290 + SDL_LockMutex(SDL_RAWINPUT_mutex);
3.291 +
3.292 while (SDL_RAWINPUT_devices) {
3.293 RAWINPUT_DelDevice(SDL_RAWINPUT_devices, SDL_FALSE);
3.294 }
3.295 @@ -1853,6 +1838,11 @@
3.296 SDL_RAWINPUT_numjoysticks = 0;
3.297
3.298 SDL_RAWINPUT_inited = SDL_FALSE;
3.299 +
3.300 + SDL_UnlockMutex(SDL_RAWINPUT_mutex);
3.301 + SDL_DestroyMutex(SDL_RAWINPUT_mutex);
3.302 + SDL_RAWINPUT_mutex = NULL;
3.303 +
3.304 }
3.305
3.306 static SDL_bool
4.1 --- a/src/joystick/windows/SDL_rawinputjoystick_c.h Fri Nov 27 11:33:53 2020 -0800
4.2 +++ b/src/joystick/windows/SDL_rawinputjoystick_c.h Fri Nov 27 13:08:40 2020 -0800
4.3 @@ -27,8 +27,12 @@
4.4 /* Return true if a RawInput device is present and supported as a joystick */
4.5 extern SDL_bool RAWINPUT_IsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name);
4.6
4.7 +/* Registers for input events */
4.8 +extern SDL_bool RAWINPUT_RegisterNotifications(HWND hWnd);
4.9 +extern void RAWINPUT_UnregisterNotifications();
4.10 +
4.11 /* Returns 0 if message was handled */
4.12 -extern LRESULT RAWINPUT_WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
4.13 +extern LRESULT CALLBACK RAWINPUT_WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
4.14
4.15
4.16 /* vi: set ts=4 sw=4 expandtab: */
5.1 --- a/src/joystick/windows/SDL_windowsjoystick.c Fri Nov 27 11:33:53 2020 -0800
5.2 +++ b/src/joystick/windows/SDL_windowsjoystick.c Fri Nov 27 13:08:40 2020 -0800
5.3 @@ -49,6 +49,7 @@
5.4 #include "SDL_windowsjoystick_c.h"
5.5 #include "SDL_dinputjoystick_c.h"
5.6 #include "SDL_xinputjoystick_c.h"
5.7 +#include "SDL_rawinputjoystick_c.h"
5.8
5.9 #include "../../haptic/windows/SDL_dinputhaptic_c.h" /* For haptic hot plugging */
5.10 #include "../../haptic/windows/SDL_xinputhaptic_c.h" /* For haptic hot plugging */
5.11 @@ -109,9 +110,9 @@
5.12
5.13 /* windowproc for our joystick detect thread message only window, to detect any USB device addition/removal */
5.14 static LRESULT CALLBACK
5.15 -SDL_PrivateJoystickDetectProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
5.16 +SDL_PrivateJoystickDetectProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
5.17 {
5.18 - switch (message) {
5.19 + switch (msg) {
5.20 case WM_DEVICECHANGE:
5.21 switch (wParam) {
5.22 case DBT_DEVICEARRIVAL:
5.23 @@ -130,12 +131,20 @@
5.24 return 0;
5.25 }
5.26
5.27 - return DefWindowProc (hwnd, message, wParam, lParam);
5.28 +#if SDL_JOYSTICK_RAWINPUT
5.29 + return CallWindowProc(RAWINPUT_WindowProc, hwnd, msg, wParam, lParam);
5.30 +#else
5.31 + return CallWindowProc(DefWindowProc, hwnd, msg, wParam, lParam);
5.32 +#endif
5.33 }
5.34
5.35 static void
5.36 SDL_CleanupDeviceNotification(SDL_DeviceNotificationData *data)
5.37 {
5.38 +#if SDL_JOYSTICK_RAWINPUT
5.39 + RAWINPUT_UnregisterNotifications();
5.40 +#endif
5.41 +
5.42 if (data->hNotify)
5.43 UnregisterDeviceNotification(data->hNotify);
5.44
5.45 @@ -188,6 +197,10 @@
5.46 SDL_CleanupDeviceNotification(data);
5.47 return -1;
5.48 }
5.49 +
5.50 +#if SDL_JOYSTICK_RAWINPUT
5.51 + RAWINPUT_RegisterNotifications(data->messageWindow);
5.52 +#endif
5.53 return 0;
5.54 }
5.55
6.1 --- a/src/video/windows/SDL_windowswindow.c Fri Nov 27 11:33:53 2020 -0800
6.2 +++ b/src/video/windows/SDL_windowswindow.c Fri Nov 27 13:08:40 2020 -0800
6.3 @@ -30,7 +30,6 @@
6.4 #include "../../events/SDL_keyboard_c.h"
6.5 #include "../../events/SDL_mouse_c.h"
6.6
6.7 -#include "../../joystick/windows/SDL_rawinputjoystick_c.h"
6.8 #include "SDL_windowsvideo.h"
6.9 #include "SDL_windowswindow.h"
6.10 #include "SDL_hints.h"
6.11 @@ -811,18 +810,8 @@
6.12 }
6.13 }
6.14
6.15 -static LRESULT CALLBACK SDL_HelperWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
6.16 -{
6.17 -#if SDL_JOYSTICK_RAWINPUT
6.18 - if (RAWINPUT_WindowProc(hWnd, msg, wParam, lParam) == 0) {
6.19 - return 0;
6.20 - }
6.21 -#endif
6.22 - return DefWindowProc(hWnd, msg, wParam, lParam);
6.23 -}
6.24 -
6.25 /*
6.26 - * Creates a HelperWindow used for DirectInput and RawInput events.
6.27 + * Creates a HelperWindow used for DirectInput.
6.28 */
6.29 int
6.30 SDL_HelperWindowCreate(void)
6.31 @@ -837,7 +826,7 @@
6.32
6.33 /* Create the class. */
6.34 SDL_zero(wce);
6.35 - wce.lpfnWndProc = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_RAWINPUT, SDL_TRUE) ? SDL_HelperWindowProc : DefWindowProc;
6.36 + wce.lpfnWndProc = DefWindowProc;
6.37 wce.lpszClassName = (LPCWSTR) SDL_HelperWindowClassName;
6.38 wce.hInstance = hInstance;
6.39