Added dinput-DIPROP_BUFFERSIZE patchset

This commit is contained in:
Alistair Leslie-Hughes 2020-01-11 16:56:16 +11:00
parent bd8f35fad1
commit 1e3eb08c69
6 changed files with 237 additions and 19 deletions

View File

@ -0,0 +1,187 @@
From 095e3e2646bc5ba024c166a2ac6829a894c0d1f7 Mon Sep 17 00:00:00 2001
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
Date: Fri, 10 Jan 2020 09:28:50 +1100
Subject: [PATCH] dinput: Support default DIPROP_BUFFERSIZE buffer size
When a program calls SetProperty with DIPROP_BUFFERSIZE, dinput records
this value for GetProperty but only uses it when the device can support
that number of buffers otherwise a max value.
In the case of game "Far Cry 5", it passes through (DWORD)-1 which
cause HeapAlloc to fail ((DWORD)-1 * sizeof(DIDEVICEOBJECTDATA)).
Since there is no real way of working out the max value, I've capped it at 100 as
the default value is 20.
MSDN reference.
https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ee417908(v=vs.85)
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45732
Signed-off-by: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
---
dlls/dinput/device.c | 14 ++++++++++----
dlls/dinput/device_private.h | 3 ++-
dlls/dinput/joystick_linux.c | 4 ++++
dlls/dinput/joystick_linuxinput.c | 4 ++++
dlls/dinput/joystick_osx.c | 4 ++++
dlls/dinput/keyboard.c | 3 +++
dlls/dinput/mouse.c | 3 +++
dlls/dinput/tests/device.c | 14 ++++++++++++++
8 files changed, 44 insertions(+), 5 deletions(-)
diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c
index 28329d03b5..1604075f84 100644
--- a/dlls/dinput/device.c
+++ b/dlls/dinput/device.c
@@ -1307,7 +1307,7 @@ HRESULT WINAPI IDirectInputDevice2WImpl_GetProperty(LPDIRECTINPUTDEVICE8W iface,
if (pdiph->dwSize != sizeof(DIPROPDWORD)) return DIERR_INVALIDPARAM;
- pd->dwData = This->queue_len;
+ pd->dwData = This->buffersize;
TRACE("buffersize = %d\n", pd->dwData);
break;
}
@@ -1396,12 +1396,18 @@ HRESULT WINAPI IDirectInputDevice2WImpl_SetProperty(
TRACE("buffersize = %d\n", pd->dwData);
EnterCriticalSection(&This->crit);
+
+ This->buffersize = pd->dwData;
+
+ This->queue_len = This->buffersize > 100 ? 100 : This->buffersize;
+ if (This->buffersize > 100)
+ WARN("Trying to set large buffer size %d\n", pd->dwData);
+
HeapFree(GetProcessHeap(), 0, This->data_queue);
- This->data_queue = !pd->dwData ? NULL : HeapAlloc(GetProcessHeap(), 0,
- pd->dwData * sizeof(DIDEVICEOBJECTDATA));
+ This->data_queue = !This->queue_len ? NULL : HeapAlloc(GetProcessHeap(), 0,
+ This->queue_len * sizeof(DIDEVICEOBJECTDATA));
This->queue_head = This->queue_tail = This->overflow = 0;
- This->queue_len = pd->dwData;
LeaveCriticalSection(&This->crit);
break;
diff --git a/dlls/dinput/device_private.h b/dlls/dinput/device_private.h
index 27e9c26286..23d9e2eebc 100644
--- a/dlls/dinput/device_private.h
+++ b/dlls/dinput/device_private.h
@@ -71,10 +71,11 @@ struct IDirectInputDeviceImpl
DI_EVENT_PROC event_proc; /* function to receive mouse & keyboard events */
LPDIDEVICEOBJECTDATA data_queue; /* buffer for 'GetDeviceData'. */
- int queue_len; /* size of the queue - set in 'SetProperty' */
+ int queue_len; /* valid size of the queue */
int queue_head; /* position to write new event into queue */
int queue_tail; /* next event to read from queue */
BOOL overflow; /* return DI_BUFFEROVERFLOW in 'GetDeviceData' */
+ DWORD buffersize; /* size of the queue - set in 'SetProperty' */
DataFormat data_format; /* user data format and wine to user format converter */
diff --git a/dlls/dinput/joystick_linux.c b/dlls/dinput/joystick_linux.c
index afdf659b4a..1e7bf72936 100644
--- a/dlls/dinput/joystick_linux.c
+++ b/dlls/dinput/joystick_linux.c
@@ -501,6 +501,10 @@ static HRESULT alloc_device(REFGUID rguid, IDirectInputImpl *dinput,
newDevice->generic.base.ref = 1;
newDevice->generic.base.dinput = dinput;
newDevice->generic.base.guid = *rguid;
+ newDevice->generic.base.buffersize = 20;
+ newDevice->generic.base.queue_len = 20;
+ newDevice->generic.base.data_queue = HeapAlloc(GetProcessHeap(), 0,
+ newDevice->generic.base.queue_len * sizeof(DIDEVICEOBJECTDATA));
InitializeCriticalSection(&newDevice->generic.base.crit);
newDevice->generic.base.crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": JoystickImpl*->generic.base.crit");
diff --git a/dlls/dinput/joystick_linuxinput.c b/dlls/dinput/joystick_linuxinput.c
index b5418d805c..98283a1eed 100644
--- a/dlls/dinput/joystick_linuxinput.c
+++ b/dlls/dinput/joystick_linuxinput.c
@@ -471,6 +471,10 @@ static JoystickImpl *alloc_device(REFGUID rguid, IDirectInputImpl *dinput, unsig
newDevice->generic.base.ref = 1;
newDevice->generic.base.guid = *rguid;
newDevice->generic.base.dinput = dinput;
+ newDevice->generic.base.buffersize = 20;
+ newDevice->generic.base.queue_len = 20;
+ newDevice->generic.base.data_queue = HeapAlloc(GetProcessHeap(), 0,
+ newDevice->generic.base.queue_len * sizeof(DIDEVICEOBJECTDATA));
newDevice->generic.joy_polldev = joy_polldev;
newDevice->joyfd = -1;
newDevice->joydev = &joydevs[index];
diff --git a/dlls/dinput/joystick_osx.c b/dlls/dinput/joystick_osx.c
index 990f5d1f07..c48cad1f5a 100644
--- a/dlls/dinput/joystick_osx.c
+++ b/dlls/dinput/joystick_osx.c
@@ -1168,6 +1168,10 @@ static HRESULT alloc_device(REFGUID rguid, IDirectInputImpl *dinput,
newDevice->generic.base.ref = 1;
newDevice->generic.base.dinput = dinput;
newDevice->generic.base.guid = *rguid;
+ newDevice->generic.base.buffersize = 20;
+ newDevice->generic.base.queue_len = 20;
+ newDevice->generic.base.data_queue = HeapAlloc(GetProcessHeap(), 0,
+ newDevice->generic.base.queue_len * sizeof(DIDEVICEOBJECTDATA));
InitializeCriticalSection(&newDevice->generic.base.crit);
newDevice->generic.base.crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": JoystickImpl*->generic.base.crit");
diff --git a/dlls/dinput/keyboard.c b/dlls/dinput/keyboard.c
index 47f28cac52..15a6be4dee 100644
--- a/dlls/dinput/keyboard.c
+++ b/dlls/dinput/keyboard.c
@@ -268,6 +268,9 @@ static SysKeyboardImpl *alloc_device(REFGUID rguid, IDirectInputImpl *dinput)
InitializeCriticalSection(&newDevice->base.crit);
newDevice->base.crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": SysKeyboardImpl*->base.crit");
newDevice->subtype = get_keyboard_subtype();
+ newDevice->base.buffersize = 20;
+ newDevice->base.queue_len = 20;
+ newDevice->base.data_queue = HeapAlloc(GetProcessHeap(), 0, newDevice->base.queue_len * sizeof(DIDEVICEOBJECTDATA));
/* Create copy of default data format */
if (!(df = HeapAlloc(GetProcessHeap(), 0, c_dfDIKeyboard.dwSize))) goto failed;
diff --git a/dlls/dinput/mouse.c b/dlls/dinput/mouse.c
index 08ace2f4e9..59c8c9dad8 100644
--- a/dlls/dinput/mouse.c
+++ b/dlls/dinput/mouse.c
@@ -214,6 +214,9 @@ static SysMouseImpl *alloc_device(REFGUID rguid, IDirectInputImpl *dinput)
newDevice->base.crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": SysMouseImpl*->base.crit");
newDevice->base.dinput = dinput;
newDevice->base.event_proc = dinput_mouse_hook;
+ newDevice->base.buffersize = 20;
+ newDevice->base.queue_len = 20;
+ newDevice->base.data_queue = HeapAlloc(GetProcessHeap(), 0, newDevice->base.queue_len * sizeof(DIDEVICEOBJECTDATA));
get_app_key(&hkey, &appkey);
if (!get_config_key(hkey, appkey, "MouseWarpOverride", buffer, sizeof(buffer)))
diff --git a/dlls/dinput/tests/device.c b/dlls/dinput/tests/device.c
index a2a5a65686..4dd16c70d2 100644
--- a/dlls/dinput/tests/device.c
+++ b/dlls/dinput/tests/device.c
@@ -106,8 +106,22 @@ static void test_object_info(IDirectInputDeviceA *device, HWND hwnd)
dp.diph.dwHeaderSize = sizeof(DIPROPHEADER);
dp.diph.dwHow = DIPH_DEVICE;
dp.diph.dwObj = 0;
+ dp.dwData = -1;
+
+ hr = IDirectInputDevice_GetProperty(device, DIPROP_BUFFERSIZE, &dp.diph);
+ ok(hr == DI_OK, "Failed: %08x\n", hr);
+ ok(dp.dwData == 20, "got %d\n", dp.dwData);
+
+ dp.dwData = -1;
+ hr = IDirectInputDevice_SetProperty(device, DIPROP_BUFFERSIZE, (LPCDIPROPHEADER)&dp.diph);
+ ok(hr == DI_OK, "SetProperty() failed: %08x\n", hr);
+
dp.dwData = 0;
+ hr = IDirectInputDevice_GetProperty(device, DIPROP_BUFFERSIZE, &dp.diph);
+ ok(hr == DI_OK, "Failed: %08x\n", hr);
+ ok(dp.dwData == -1, "got %d\n", dp.dwData);
+ dp.dwData = 0;
hr = IDirectInputDevice_SetProperty(device, DIPROP_BUFFERSIZE, (LPCDIPROPHEADER)&dp.diph);
ok(hr == DI_OK, "SetProperty() failed: %08x\n", hr);
cnt = 5;
--
2.17.1

View File

@ -0,0 +1 @@
Fixes: [45732] Far Cry 5 Cannot Steer Land Vehicles

View File

@ -1,18 +1,18 @@
From 47a1e3618a1629a6f7cca1b84f761eaab3627f75 Mon Sep 17 00:00:00 2001
From dd42a25720d9d711137e84a449319fc197b2639f Mon Sep 17 00:00:00 2001
From: Andrew Church <achurch@achurch.org>
Date: Mon, 25 Feb 2019 11:23:12 +1100
Subject: [PATCH] dinput: Allow reconnecting to disconnected joysticks
Wine-bug: https://bugs.winehq.org/show_bug.cgi?id=34297
---
dlls/dinput/joystick_linuxinput.c | 148 +++++++++++++++++++++++++++++---------
dlls/dinput/joystick_linuxinput.c | 148 +++++++++++++++++++++++-------
1 file changed, 113 insertions(+), 35 deletions(-)
diff --git a/dlls/dinput/joystick_linuxinput.c b/dlls/dinput/joystick_linuxinput.c
index ace4641..233dd25 100644
index 98283a1eedd..439e7d84bd4 100644
--- a/dlls/dinput/joystick_linuxinput.c
+++ b/dlls/dinput/joystick_linuxinput.c
@@ -83,6 +83,13 @@ struct wine_input_absinfo {
@@ -84,6 +84,13 @@ struct wine_input_absinfo {
LONG flat;
};
@ -26,7 +26,7 @@ index ace4641..233dd25 100644
/* implemented in effect_linuxinput.c */
HRESULT linuxinput_create_effect(int* fd, REFGUID rguid, struct list *parent_list_entry, LPDIRECTINPUTEFFECT* peff);
HRESULT linuxinput_get_info_A(int fd, REFGUID rguid, LPDIEFFECTINFOA info);
@@ -122,6 +129,7 @@ struct JoystickImpl
@@ -123,6 +130,7 @@ struct JoystickImpl
/* joystick private */
int joyfd;
@ -34,15 +34,15 @@ index ace4641..233dd25 100644
int dev_axes_to_di[ABS_MAX];
POINTL povs[4];
@@ -466,6 +474,7 @@ static JoystickImpl *alloc_device(REFGUID rguid, IDirectInputImpl *dinput, unsig
newDevice->generic.base.dinput = dinput;
@@ -477,6 +485,7 @@ static JoystickImpl *alloc_device(REFGUID rguid, IDirectInputImpl *dinput, unsig
newDevice->generic.base.queue_len * sizeof(DIDEVICEOBJECTDATA));
newDevice->generic.joy_polldev = joy_polldev;
newDevice->joyfd = -1;
+ newDevice->joyfd_state = WINE_FD_STATE_CLOSED;
newDevice->joydev = &joydevs[index];
newDevice->generic.name = newDevice->joydev->name;
list_init(&newDevice->ff_effects);
@@ -669,38 +678,15 @@ static HRESULT joydev_create_device(IDirectInputImpl *dinput, REFGUID rguid, REF
@@ -684,38 +693,15 @@ static HRESULT joydev_create_device(IDirectInputImpl *dinput, REFGUID rguid, REF
return DIERR_DEVICENOTREG;
}
@ -85,7 +85,7 @@ index ace4641..233dd25 100644
}
else
{
@@ -715,18 +701,53 @@ static HRESULT WINAPI JoystickWImpl_Acquire(LPDIRECTINPUTDEVICE8W iface)
@@ -730,18 +716,53 @@ static HRESULT WINAPI JoystickWImpl_Acquire(LPDIRECTINPUTDEVICE8W iface)
event.type = EV_FF;
event.code = FF_GAIN;
event.value = This->ff_gain;
@ -141,7 +141,7 @@ index ace4641..233dd25 100644
return DI_OK;
}
@@ -764,6 +785,7 @@ static HRESULT WINAPI JoystickWImpl_Unacquire(LPDIRECTINPUTDEVICE8W iface)
@@ -779,6 +800,7 @@ static HRESULT WINAPI JoystickWImpl_Unacquire(LPDIRECTINPUTDEVICE8W iface)
close(This->joyfd);
This->joyfd = -1;
@ -149,7 +149,7 @@ index ace4641..233dd25 100644
}
return res;
}
@@ -808,23 +830,79 @@ static void joy_polldev(LPDIRECTINPUTDEVICE8A iface)
@@ -823,23 +845,79 @@ static void joy_polldev(LPDIRECTINPUTDEVICE8A iface)
struct input_event ie;
JoystickImpl *This = impl_from_IDirectInputDevice8A(iface);
@ -236,5 +236,5 @@ index ace4641..233dd25 100644
TRACE("input_event: type %d, code %d, value %d\n",ie.type,ie.code,ie.value);
switch (ie.type) {
--
1.9.1
2.24.1

View File

@ -1,2 +1,2 @@
Fixes: [34297] dinput: Allow reconnecting to disconnected joysticks
Depends: dinput-DIPROP_BUFFERSIZE

View File

@ -52,7 +52,7 @@ usage()
# Get the upstream commit sha
upstream_commit()
{
echo "4f0212c4fd35ac4b03a082cab27e629130ac1b13"
echo "c84fa0a2661f2235fac6f3427201fbb3fd8c8028"
}
# Show version information
@ -128,6 +128,7 @@ patch_enable_all ()
enable_ddraw_Texture_Wrong_Caps="$1"
enable_ddraw_Write_Vtable="$1"
enable_ddraw_version_check="$1"
enable_dinput_DIPROP_BUFFERSIZE="$1"
enable_dinput_SetActionMap_genre="$1"
enable_dinput_axis_recalc="$1"
enable_dinput_joy_mappings="$1"
@ -518,6 +519,9 @@ patch_enable ()
ddraw-version-check)
enable_ddraw_version_check="$2"
;;
dinput-DIPROP_BUFFERSIZE)
enable_dinput_DIPROP_BUFFERSIZE="$2"
;;
dinput-SetActionMap-genre)
enable_dinput_SetActionMap_genre="$2"
;;
@ -2049,6 +2053,13 @@ if test "$enable_dsound_EAX" -eq 1; then
enable_dsound_Fast_Mixer=1
fi
if test "$enable_dinput_reconnect_joystick" -eq 1; then
if test "$enable_dinput_DIPROP_BUFFERSIZE" -gt 1; then
abort "Patchset dinput-DIPROP_BUFFERSIZE disabled, but dinput-reconnect-joystick depends on that."
fi
enable_dinput_DIPROP_BUFFERSIZE=1
fi
if test "$enable_dinput_SetActionMap_genre" -eq 1; then
if test "$enable_dinput_joy_mappings" -gt 1; then
abort "Patchset dinput-joy-mappings disabled, but dinput-SetActionMap-genre depends on that."
@ -3089,6 +3100,22 @@ if test "$enable_ddraw_version_check" -eq 1; then
) >> "$patchlist"
fi
# Patchset dinput-DIPROP_BUFFERSIZE
# |
# | This patchset fixes the following Wine bugs:
# | * [#45732] Far Cry 5 Cannot Steer Land Vehicles
# |
# | Modified files:
# | * dlls/dinput/device.c, dlls/dinput/device_private.h, dlls/dinput/joystick_linux.c, dlls/dinput/joystick_linuxinput.c,
# | dlls/dinput/joystick_osx.c, dlls/dinput/keyboard.c, dlls/dinput/mouse.c, dlls/dinput/tests/device.c
# |
if test "$enable_dinput_DIPROP_BUFFERSIZE" -eq 1; then
patch_apply dinput-DIPROP_BUFFERSIZE/0001-dinput-Support-default-DIPROP_BUFFERSIZE-buffer-size.patch
(
printf '%s\n' '+ { "Alistair Leslie-Hughes", "dinput: Support default DIPROP_BUFFERSIZE buffer size.", 1 },';
) >> "$patchlist"
fi
# Patchset dinput-joy-mappings
# |
# | This patchset fixes the following Wine bugs:
@ -3148,6 +3175,9 @@ fi
# Patchset dinput-reconnect-joystick
# |
# | This patchset has the following (direct or indirect) dependencies:
# | * dinput-DIPROP_BUFFERSIZE
# |
# | This patchset fixes the following Wine bugs:
# | * [#34297] dinput: Allow reconnecting to disconnected joysticks
# |

View File

@ -1,8 +1,8 @@
From 7f814cd77f1766b98318bbc8ea5fff241c20ec4b Mon Sep 17 00:00:00 2001
From 8217791e4b68de86e713dee0ecdd3c5ccd029017 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Mon, 26 Aug 2019 16:06:59 +0200
Subject: [PATCH 11/12] dinput8: Add support for dinput devices that use raw
input interface.
Subject: [PATCH] dinput8: Add support for dinput devices that use raw input
interface.
This adds a global message window that will receive WM_INPUT messages,
dispatched to every raw input device event_proc.
@ -16,7 +16,7 @@ outside of dinput, as exposed by the unit tests.
2 files changed, 86 insertions(+), 1 deletion(-)
diff --git a/dlls/dinput/device_private.h b/dlls/dinput/device_private.h
index 114e3971ed8..9116aaeab66 100644
index 423e8f77792..b0fb181fc6d 100644
--- a/dlls/dinput/device_private.h
+++ b/dlls/dinput/device_private.h
@@ -70,6 +70,9 @@ struct IDirectInputDeviceImpl
@ -27,7 +27,7 @@ index 114e3971ed8..9116aaeab66 100644
+ RAWINPUTDEVICE raw_device; /* raw device to (un)register */
+
LPDIDEVICEOBJECTDATA data_queue; /* buffer for 'GetDeviceData'. */
int queue_len; /* size of the queue - set in 'SetProperty' */
int queue_len; /* valid size of the queue */
int queue_head; /* position to write new event into queue */
diff --git a/dlls/dinput/dinput_main.c b/dlls/dinput/dinput_main.c
index 4d2d4afe106..9e3b9f48250 100644