Don't use raw input while Remote Desktop is active Raw input will not send game controller events while Remote Desktop is active, so dynamically switch between XInput and raw input when Remote Desktop state changes. Fixes https://github.com/libsdl-org/SDL/issues/7759 (cherry picked from commit 767507fcf6f4607edb413acb53a6c029863701ed)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244
diff --git a/src/joystick/windows/SDL_dinputjoystick.c b/src/joystick/windows/SDL_dinputjoystick.c
index bac7956..9299619 100644
--- a/src/joystick/windows/SDL_dinputjoystick.c
+++ b/src/joystick/windows/SDL_dinputjoystick.c
@@ -240,7 +240,7 @@ static int SetDIerror(const char *function, HRESULT code)
static SDL_bool SDL_IsXInputDevice(Uint16 vendor_id, Uint16 product_id, const char *hidPath)
{
-#ifdef SDL_JOYSTICK_XINPUT
+#if defined(SDL_JOYSTICK_XINPUT) || defined(SDL_JOYSTICK_RAWINPUT)
SDL_GameControllerType type;
/* XInput and RawInput backends will pick up XInput-compatible devices */
@@ -264,7 +264,7 @@ static SDL_bool SDL_IsXInputDevice(Uint16 vendor_id, Uint16 product_id, const ch
(vendor_id == USB_VENDOR_VALVE && product_id == USB_PRODUCT_STEAM_VIRTUAL_GAMEPAD)) {
return SDL_TRUE;
}
-#endif /* SDL_JOYSTICK_XINPUT */
+#endif /* SDL_JOYSTICK_XINPUT || SDL_JOYSTICK_RAWINPUT */
return SDL_FALSE;
}
diff --git a/src/joystick/windows/SDL_rawinputjoystick.c b/src/joystick/windows/SDL_rawinputjoystick.c
index 6331bc7..fe08553 100644
--- a/src/joystick/windows/SDL_rawinputjoystick.c
+++ b/src/joystick/windows/SDL_rawinputjoystick.c
@@ -96,7 +96,11 @@ typedef struct WindowsGamingInputGamepadState WindowsGamingInputGamepadState;
#define GIDC_REMOVAL 2
#endif
+extern void WINDOWS_RAWINPUTEnabledChanged(void);
+extern void WINDOWS_JoystickDetect(void);
+
static SDL_bool SDL_RAWINPUT_inited = SDL_FALSE;
+static SDL_bool SDL_RAWINPUT_remote_desktop = SDL_FALSE;
static int SDL_RAWINPUT_numjoysticks = 0;
static void RAWINPUT_JoystickClose(SDL_Joystick *joystick);
@@ -843,10 +847,36 @@ static void RAWINPUT_DelDevice(SDL_RAWINPUT_Device *device, SDL_bool send_event)
}
}
-static int RAWINPUT_JoystickInit(void)
+static void RAWINPUT_DetectDevices(void)
{
UINT device_count = 0;
+ if ((GetRawInputDeviceList(NULL, &device_count, sizeof(RAWINPUTDEVICELIST)) != -1) && device_count > 0) {
+ PRAWINPUTDEVICELIST devices = NULL;
+ UINT i;
+
+ devices = (PRAWINPUTDEVICELIST)SDL_malloc(sizeof(RAWINPUTDEVICELIST) * device_count);
+ if (devices) {
+ if (GetRawInputDeviceList(devices, &device_count, sizeof(RAWINPUTDEVICELIST)) != -1) {
+ for (i = 0; i < device_count; ++i) {
+ RAWINPUT_AddDevice(devices[i].hDevice);
+ }
+ }
+ SDL_free(devices);
+ }
+ }
+}
+
+static void RAWINPUT_RemoveDevices(void)
+{
+ while (SDL_RAWINPUT_devices) {
+ RAWINPUT_DelDevice(SDL_RAWINPUT_devices, SDL_FALSE);
+ }
+ SDL_assert(SDL_RAWINPUT_numjoysticks == 0);
+}
+
+static int RAWINPUT_JoystickInit(void)
+{
SDL_assert(!SDL_RAWINPUT_inited);
if (!WIN_IsWindowsVistaOrGreater()) {
@@ -864,20 +894,7 @@ static int RAWINPUT_JoystickInit(void)
SDL_RAWINPUT_inited = SDL_TRUE;
- if ((GetRawInputDeviceList(NULL, &device_count, sizeof(RAWINPUTDEVICELIST)) != -1) && device_count > 0) {
- PRAWINPUTDEVICELIST devices = NULL;
- UINT i;
-
- devices = (PRAWINPUTDEVICELIST)SDL_malloc(sizeof(RAWINPUTDEVICELIST) * device_count);
- if (devices) {
- if (GetRawInputDeviceList(devices, &device_count, sizeof(RAWINPUTDEVICELIST)) != -1) {
- for (i = 0; i < device_count; ++i) {
- RAWINPUT_AddDevice(devices[i].hDevice);
- }
- }
- SDL_free(devices);
- }
- }
+ RAWINPUT_DetectDevices();
return 0;
}
@@ -889,7 +906,7 @@ static int RAWINPUT_JoystickGetCount(void)
SDL_bool RAWINPUT_IsEnabled()
{
- return SDL_RAWINPUT_inited;
+ return SDL_RAWINPUT_inited && !SDL_RAWINPUT_remote_desktop;
}
SDL_bool RAWINPUT_IsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name)
@@ -991,6 +1008,21 @@ static void RAWINPUT_PostUpdate(void)
static void RAWINPUT_JoystickDetect(void)
{
+ SDL_bool remote_desktop = GetSystemMetrics(SM_REMOTESESSION) ? SDL_TRUE : SDL_FALSE;
+
+ if (remote_desktop != SDL_RAWINPUT_remote_desktop) {
+ SDL_RAWINPUT_remote_desktop = remote_desktop;
+
+ WINDOWS_RAWINPUTEnabledChanged();
+
+ if (remote_desktop) {
+ RAWINPUT_RemoveDevices();
+ WINDOWS_JoystickDetect();
+ } else {
+ WINDOWS_JoystickDetect();
+ RAWINPUT_DetectDevices();
+ }
+ }
RAWINPUT_PostUpdate();
}
@@ -1981,14 +2013,10 @@ static void RAWINPUT_JoystickQuit(void)
return;
}
- while (SDL_RAWINPUT_devices) {
- RAWINPUT_DelDevice(SDL_RAWINPUT_devices, SDL_FALSE);
- }
+ RAWINPUT_RemoveDevices();
WIN_UnloadHIDDLL();
- SDL_RAWINPUT_numjoysticks = 0;
-
SDL_RAWINPUT_inited = SDL_FALSE;
}
diff --git a/src/joystick/windows/SDL_windows_gaming_input.c b/src/joystick/windows/SDL_windows_gaming_input.c
index 828977c..06e555c 100644
--- a/src/joystick/windows/SDL_windows_gaming_input.c
+++ b/src/joystick/windows/SDL_windows_gaming_input.c
@@ -108,7 +108,7 @@ extern SDL_bool SDL_DINPUT_JoystickPresent(Uint16 vendor, Uint16 product, Uint16
static SDL_bool SDL_IsXInputDevice(Uint16 vendor, Uint16 product)
{
-#ifdef SDL_JOYSTICK_XINPUT
+#if defined(SDL_JOYSTICK_XINPUT) || defined(SDL_JOYSTICK_RAWINPUT)
PRAWINPUTDEVICELIST raw_devices = NULL;
UINT i, raw_device_count = 0;
LONG vidpid = MAKELONG(vendor, product);
@@ -206,7 +206,7 @@ static SDL_bool SDL_IsXInputDevice(Uint16 vendor, Uint16 product)
}
SDL_free(raw_devices);
-#endif /* SDL_JOYSTICK_XINPUT */
+#endif /* SDL_JOYSTICK_XINPUT || SDL_JOYSTICK_RAWINPUT */
return SDL_FALSE;
}
diff --git a/src/joystick/windows/SDL_windowsjoystick.c b/src/joystick/windows/SDL_windowsjoystick.c
index 0f46a74..d94b314 100644
--- a/src/joystick/windows/SDL_windowsjoystick.c
+++ b/src/joystick/windows/SDL_windowsjoystick.c
@@ -165,6 +165,11 @@ static CM_Register_NotificationFunc CM_Register_Notification;
static CM_Unregister_NotificationFunc CM_Unregister_Notification;
static HCMNOTIFICATION s_DeviceNotificationFuncHandle;
+void WINDOWS_RAWINPUTEnabledChanged(void)
+{
+ s_bWindowsDeviceChanged = SDL_TRUE;
+}
+
static DWORD CALLBACK SDL_DeviceNotificationFunc(HCMNOTIFICATION hNotify, PVOID context, CM_NOTIFY_ACTION action, PCM_NOTIFY_EVENT_DATA eventData, DWORD event_data_size)
{
if (action == CM_NOTIFY_ACTION_DEVICEINTERFACEARRIVAL ||
@@ -459,8 +464,8 @@ void WINDOWS_AddJoystickDevice(JoyStick_DeviceData *device)
SYS_Joystick = device;
}
-static void WINDOWS_JoystickDetect(void);
-static void WINDOWS_JoystickQuit(void);
+void WINDOWS_JoystickDetect(void);
+void WINDOWS_JoystickQuit(void);
/* Function to scan the system for joysticks.
* Joystick 0 should be the system default joystick.
@@ -521,7 +526,7 @@ static int WINDOWS_JoystickGetCount(void)
}
/* detect any new joysticks being inserted into the system */
-static void WINDOWS_JoystickDetect(void)
+void WINDOWS_JoystickDetect(void)
{
JoyStick_DeviceData *pCurList = NULL;
@@ -750,7 +755,7 @@ static void WINDOWS_JoystickClose(SDL_Joystick *joystick)
}
/* Function to perform any system-specific joystick related cleanup */
-static void WINDOWS_JoystickQuit(void)
+void WINDOWS_JoystickQuit(void)
{
JoyStick_DeviceData *device = SYS_Joystick;
diff --git a/src/joystick/windows/SDL_xinputjoystick.c b/src/joystick/windows/SDL_xinputjoystick.c
index a0cf911..1cc8a2e 100644
--- a/src/joystick/windows/SDL_xinputjoystick.c
+++ b/src/joystick/windows/SDL_xinputjoystick.c
@@ -68,13 +68,6 @@ int SDL_XINPUT_JoystickInit(void)
{
s_bXInputEnabled = SDL_GetHintBoolean(SDL_HINT_XINPUT_ENABLED, SDL_TRUE);
-#ifdef SDL_JOYSTICK_RAWINPUT
- if (RAWINPUT_IsEnabled()) {
- /* The raw input driver handles more than 4 controllers, so prefer that when available */
- s_bXInputEnabled = SDL_FALSE;
- }
-#endif
-
if (s_bXInputEnabled && WIN_LoadXInputDLL() < 0) {
s_bXInputEnabled = SDL_FALSE; /* oh well. */
}
@@ -329,6 +322,13 @@ void SDL_XINPUT_JoystickDetect(JoyStick_DeviceData **pContext)
return;
}
+#ifdef SDL_JOYSTICK_RAWINPUT
+ if (RAWINPUT_IsEnabled()) {
+ /* The raw input driver handles more than 4 controllers, so prefer that when available */
+ return;
+ }
+#endif
+
/* iterate in reverse, so these are in the final list in ascending numeric order. */
for (iuserid = XUSER_MAX_COUNT - 1; iuserid >= 0; iuserid--) {
const Uint8 userid = (Uint8)iuserid;