mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-11-21 16:46:54 -08:00
Added dinput-reconnect-joystick patchset
This commit is contained in:
parent
e6cfe1ccd8
commit
4a23a62b5d
@ -0,0 +1,240 @@
|
||||
From 47a1e3618a1629a6f7cca1b84f761eaab3627f75 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 +++++++++++++++++++++++++++++---------
|
||||
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
|
||||
--- a/dlls/dinput/joystick_linuxinput.c
|
||||
+++ b/dlls/dinput/joystick_linuxinput.c
|
||||
@@ -83,6 +83,13 @@ struct wine_input_absinfo {
|
||||
LONG flat;
|
||||
};
|
||||
|
||||
+enum wine_joystick_linuxinput_fd_state {
|
||||
+ WINE_FD_STATE_CLOSED = 0, /* No device has been opened yet */
|
||||
+ WINE_FD_STATE_OK, /* File descriptor is open and ready for reading */
|
||||
+ WINE_FD_STATE_DISCONNECTED, /* Read error occurred; might be able to reopen later */
|
||||
+ WINE_FD_STATE_INVALID, /* Device is no longer available at original pathname */
|
||||
+};
|
||||
+
|
||||
/* 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
|
||||
|
||||
/* joystick private */
|
||||
int joyfd;
|
||||
+ enum wine_joystick_linuxinput_fd_state joyfd_state;
|
||||
|
||||
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;
|
||||
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
|
||||
return DIERR_DEVICENOTREG;
|
||||
}
|
||||
|
||||
-
|
||||
-const struct dinput_device joystick_linuxinput_device = {
|
||||
- "Wine Linux-input joystick driver",
|
||||
- joydev_enum_deviceA,
|
||||
- joydev_enum_deviceW,
|
||||
- joydev_create_device
|
||||
-};
|
||||
-
|
||||
-/******************************************************************************
|
||||
- * Acquire : gets exclusive control of the joystick
|
||||
- */
|
||||
-static HRESULT WINAPI JoystickWImpl_Acquire(LPDIRECTINPUTDEVICE8W iface)
|
||||
+static int joydev_open_evdev(JoystickImpl *This)
|
||||
{
|
||||
- JoystickImpl *This = impl_from_IDirectInputDevice8W(iface);
|
||||
- HRESULT res;
|
||||
-
|
||||
- TRACE("(this=%p)\n",This);
|
||||
+ int fd;
|
||||
|
||||
- if ((res = IDirectInputDevice2WImpl_Acquire(iface)) != DI_OK)
|
||||
+ if ((fd = open(This->joydev->device, O_RDWR)) == -1)
|
||||
{
|
||||
- WARN("Failed to acquire: %x\n", res);
|
||||
- return res;
|
||||
- }
|
||||
-
|
||||
- if ((This->joyfd = open(This->joydev->device, O_RDWR)) == -1)
|
||||
- {
|
||||
- if ((This->joyfd = open(This->joydev->device, O_RDONLY)) == -1)
|
||||
+ if ((fd = open(This->joydev->device, O_RDONLY)) == -1)
|
||||
{
|
||||
/* Couldn't open the device at all */
|
||||
- ERR("Failed to open device %s: %d %s\n", This->joydev->device, errno, strerror(errno));
|
||||
- IDirectInputDevice2WImpl_Unacquire(iface);
|
||||
- return DIERR_NOTFOUND;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -715,18 +701,53 @@ static HRESULT WINAPI JoystickWImpl_Acquire(LPDIRECTINPUTDEVICE8W iface)
|
||||
event.type = EV_FF;
|
||||
event.code = FF_GAIN;
|
||||
event.value = This->ff_gain;
|
||||
- if (write(This->joyfd, &event, sizeof(event)) == -1)
|
||||
+ if (write(fd, &event, sizeof(event)) == -1)
|
||||
ERR("Failed to set gain (%i): %d %s\n", This->ff_gain, errno, strerror(errno));
|
||||
if (!This->ff_autocenter)
|
||||
{
|
||||
/* Disable autocenter. */
|
||||
event.code = FF_AUTOCENTER;
|
||||
event.value = 0;
|
||||
- if (write(This->joyfd, &event, sizeof(event)) == -1)
|
||||
+ if (write(fd, &event, sizeof(event)) == -1)
|
||||
ERR("Failed disabling autocenter: %d %s\n", errno, strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
+ return fd;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+const struct dinput_device joystick_linuxinput_device = {
|
||||
+ "Wine Linux-input joystick driver",
|
||||
+ joydev_enum_deviceA,
|
||||
+ joydev_enum_deviceW,
|
||||
+ joydev_create_device
|
||||
+};
|
||||
+
|
||||
+/******************************************************************************
|
||||
+ * Acquire : gets exclusive control of the joystick
|
||||
+ */
|
||||
+static HRESULT WINAPI JoystickWImpl_Acquire(LPDIRECTINPUTDEVICE8W iface)
|
||||
+{
|
||||
+ JoystickImpl *This = impl_from_IDirectInputDevice8W(iface);
|
||||
+ HRESULT res;
|
||||
+
|
||||
+ TRACE("(this=%p)\n",This);
|
||||
+
|
||||
+ if ((res = IDirectInputDevice2WImpl_Acquire(iface)) != DI_OK)
|
||||
+ {
|
||||
+ WARN("Failed to acquire: %x\n", res);
|
||||
+ return res;
|
||||
+ }
|
||||
+
|
||||
+ if ((This->joyfd = joydev_open_evdev(This)) == -1)
|
||||
+ {
|
||||
+ ERR("Failed to open device %s: %d %s\n", This->joydev->device, errno, strerror(errno));
|
||||
+ IDirectInputDevice2WImpl_Unacquire(iface);
|
||||
+ return DIERR_NOTFOUND;
|
||||
+ }
|
||||
+
|
||||
+ This->joyfd_state = WINE_FD_STATE_OK;
|
||||
return DI_OK;
|
||||
}
|
||||
|
||||
@@ -764,6 +785,7 @@ static HRESULT WINAPI JoystickWImpl_Unacquire(LPDIRECTINPUTDEVICE8W iface)
|
||||
|
||||
close(This->joyfd);
|
||||
This->joyfd = -1;
|
||||
+ This->joyfd_state = WINE_FD_STATE_CLOSED;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
@@ -808,23 +830,79 @@ static void joy_polldev(LPDIRECTINPUTDEVICE8A iface)
|
||||
struct input_event ie;
|
||||
JoystickImpl *This = impl_from_IDirectInputDevice8A(iface);
|
||||
|
||||
- if (This->joyfd==-1)
|
||||
- return;
|
||||
+ if (This->joyfd == -1)
|
||||
+ {
|
||||
+ int fd;
|
||||
+ char namebuf[MAX_PATH + 8]; /* 8 == strlen(EVDEVDRIVER) */
|
||||
+
|
||||
+ if (This->joyfd_state != WINE_FD_STATE_DISCONNECTED)
|
||||
+ return;
|
||||
+ /* Try to reconnect to the device. */
|
||||
+ fd = joydev_open_evdev(This);
|
||||
+ if (fd == -1)
|
||||
+ return;
|
||||
+ namebuf[sizeof(namebuf) - strlen(EVDEVDRIVER) - 1] = 0;
|
||||
+ if (ioctl(fd, EVIOCGNAME(sizeof(namebuf) - strlen(EVDEVDRIVER) - 1), namebuf) == -1)
|
||||
+ {
|
||||
+ /* Couldn't get the name; assume it's a different device. */
|
||||
+ ERR("EVIOCGNAME(%s) failed: %d %s", This->joydev->device, errno, strerror(errno));
|
||||
+ This->joyfd_state = WINE_FD_STATE_INVALID;
|
||||
+ return;
|
||||
+ }
|
||||
+ strcat(namebuf, EVDEVDRIVER); /* Guaranteed to be safe. */
|
||||
+ if (strcmp(namebuf, This->joydev->name) != 0)
|
||||
+ {
|
||||
+ ERR("Device %s changed from \"%s\" to \"%s\"! Can't reconnect.\n", This->joydev->device, This->joydev->name, namebuf);
|
||||
+ This->joyfd_state = WINE_FD_STATE_INVALID;
|
||||
+ return;
|
||||
+ }
|
||||
+ if (InterlockedCompareExchange(&This->joyfd, fd, -1) == -1)
|
||||
+ {
|
||||
+ This->joyfd_state = WINE_FD_STATE_OK;
|
||||
+ TRACE("Reconnected to \"%s\" on %s", This->joydev->name, This->joydev->device);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ /* Somebody beat us to it! Throw away our fd and use theirs. */
|
||||
+ close(fd);
|
||||
+ }
|
||||
+ }
|
||||
|
||||
while (1)
|
||||
{
|
||||
LONG value = 0;
|
||||
int inst_id = -1;
|
||||
+ int result;
|
||||
|
||||
plfd.fd = This->joyfd;
|
||||
plfd.events = POLLIN;
|
||||
|
||||
- if (poll(&plfd,1,0) != 1)
|
||||
- return;
|
||||
+ result = poll(&plfd,1,0);
|
||||
+ if (result != 1)
|
||||
+ {
|
||||
+ if (result == -1)
|
||||
+ {
|
||||
+ ERR("poll failed: %d %s\n", errno, strerror(errno));
|
||||
+ close(This->joyfd);
|
||||
+ This->joyfd = -1;
|
||||
+ This->joyfd_state = WINE_FD_STATE_DISCONNECTED;
|
||||
+ }
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
/* we have one event, so we can read */
|
||||
- if (sizeof(ie)!=read(This->joyfd,&ie,sizeof(ie)))
|
||||
- return;
|
||||
+ result = read(This->joyfd,&ie,sizeof(ie));
|
||||
+ if (result != sizeof(ie))
|
||||
+ {
|
||||
+ if (result == -1)
|
||||
+ {
|
||||
+ ERR("read failed: %d %s\n", errno, strerror(errno));
|
||||
+ close(This->joyfd);
|
||||
+ This->joyfd = -1;
|
||||
+ This->joyfd_state = WINE_FD_STATE_DISCONNECTED;
|
||||
+ }
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
TRACE("input_event: type %d, code %d, value %d\n",ie.type,ie.code,ie.value);
|
||||
switch (ie.type) {
|
||||
--
|
||||
1.9.1
|
||||
|
2
patches/dinput-reconnect-joystick/definition
Normal file
2
patches/dinput-reconnect-joystick/definition
Normal file
@ -0,0 +1,2 @@
|
||||
Fixes: [34297] dinput: Allow reconnecting to disconnected joysticks
|
||||
|
@ -133,6 +133,7 @@ patch_enable_all ()
|
||||
enable_ddraw_version_check="$1"
|
||||
enable_dinput_Deadlock="$1"
|
||||
enable_dinput_Initialize="$1"
|
||||
enable_dinput_reconnect_joystick="$1"
|
||||
enable_dinput_remap_joystick="$1"
|
||||
enable_dsound_EAX="$1"
|
||||
enable_dsound_Fast_Mixer="$1"
|
||||
@ -548,6 +549,9 @@ patch_enable ()
|
||||
dinput-Initialize)
|
||||
enable_dinput_Initialize="$2"
|
||||
;;
|
||||
dinput-reconnect-joystick)
|
||||
enable_dinput_reconnect_joystick="$2"
|
||||
;;
|
||||
dinput-remap-joystick)
|
||||
enable_dinput_remap_joystick="$2"
|
||||
;;
|
||||
@ -3235,6 +3239,21 @@ if test "$enable_dinput_Initialize" -eq 1; then
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset dinput-reconnect-joystick
|
||||
# |
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
# | * [#34297] dinput: Allow reconnecting to disconnected joysticks
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * dlls/dinput/joystick_linuxinput.c
|
||||
# |
|
||||
if test "$enable_dinput_reconnect_joystick" -eq 1; then
|
||||
patch_apply dinput-reconnect-joystick/0001-dinput-Allow-reconnecting-to-disconnected-joysticks.patch
|
||||
(
|
||||
printf '%s\n' '+ { "Andrew Church", "dinput: Allow reconnecting to disconnected joysticks.", 1 },';
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset dinput-remap-joystick
|
||||
# |
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
|
Loading…
x
Reference in New Issue
Block a user