This happens if any of the vendor-specific reports is used.
SDL triggers the mode switch when calling SDL_GameControllerSetSensorEnabled() on supported devices.
This is a one-way transition, i.e. cannot be undone without restarting the controller, so it's fine to have it tied to lifetime of winebus.
Signed-off-by: Arkadiusz Hiler ahiler@codeweavers.com --- dlls/winebus.sys/bus_udev.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c index 2269f5b904e..4bd0907fdfd 100644 --- a/dlls/winebus.sys/bus_udev.c +++ b/dlls/winebus.sys/bus_udev.c @@ -360,6 +360,21 @@ static void hidraw_device_read_report(struct unix_device *iface) } }
+static void hidraw_disable_sony_quirks(struct unix_device *iface) +{ + struct hidraw_device *impl = hidraw_impl_from_unix_device(iface); + + /* FIXME: we may want to validate CRC at the end of the outbound HID reports, + * as controllers do not switch modes if it is incorrect. + */ + + if ((impl->quirks & QUIRK_DS4_BT)) + { + TRACE("Disabling report quirk for Bluetooth DualShock4 controller iface %p\n", iface); + impl->quirks &= ~QUIRK_DS4_BT; + } +} + static void hidraw_device_set_output_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io) { struct hidraw_device *impl = hidraw_impl_from_unix_device(iface); @@ -379,6 +394,7 @@ static void hidraw_device_set_output_report(struct unix_device *iface, HID_XFER_
if (count > 0) { + hidraw_disable_sony_quirks(iface); io->Information = count; io->Status = STATUS_SUCCESS; } @@ -411,6 +427,7 @@ static void hidraw_device_get_feature_report(struct unix_device *iface, HID_XFER
if (count > 0) { + hidraw_disable_sony_quirks(iface); io->Information = count; io->Status = STATUS_SUCCESS; } @@ -447,6 +464,7 @@ static void hidraw_device_set_feature_report(struct unix_device *iface, HID_XFER
if (count > 0) { + hidraw_disable_sony_quirks(iface); io->Information = count; io->Status = STATUS_SUCCESS; }