[PATCH 1/5] dinput: return fake DIPROP_GUIDANDPATH property for linux joysticks

Andrew Eikum aeikum at codeweavers.com
Mon Jun 10 09:58:45 CDT 2019


Signed-off-by: Andrew Eikum <aeikum at codeweavers.com>

---
Alexandre, I think it makes sense to squash all 5 of these down to a
single commit.

On Wed, Jun 05, 2019 at 12:53:44AM +0300, Alexey Prokhin wrote:
> Some Ubisoft titles use the property to check if a dinput gamepad is
> also an xinput device.
> 
> Signed-off-by: Alexey Prokhin <alexey at prokhin.ru>
> ---
> A similar patch for the SDL backend has been already accepted into
> Proton. And I have been asked to adapt it for other backends.
> 
> is_xinput_device() is based on the code from winebus.sys. In future,
> the xinput device detection should be kept in sync as much as possible.
> ---
>  dlls/dinput/dinput_main.c      |  1 +
>  dlls/dinput/joystick.c         | 31 +++++++++++++++++++++++++++++++
>  dlls/dinput/joystick_linux.c   | 24 ++++++++++++++++++++++++
>  dlls/dinput/joystick_private.h |  1 +
>  4 files changed, 57 insertions(+)
> 
> diff --git a/dlls/dinput/dinput_main.c b/dlls/dinput/dinput_main.c
> index acf2cf3d23..c02bafad10 100644
> --- a/dlls/dinput/dinput_main.c
> +++ b/dlls/dinput/dinput_main.c
> @@ -48,6 +48,7 @@
>  #include "objbase.h"
>  #include "rpcproxy.h"
>  #include "initguid.h"
> +#include "devguid.h"
>  #include "dinput_private.h"
>  #include "device_private.h"
>  #include "dinputd.h"
> diff --git a/dlls/dinput/joystick.c b/dlls/dinput/joystick.c
> index f758092dab..433348cd04 100644
> --- a/dlls/dinput/joystick.c
> +++ b/dlls/dinput/joystick.c
> @@ -34,6 +34,24 @@
>  
>  WINE_DEFAULT_DEBUG_CHANNEL(dinput);
>  
> +#define VID_MICROSOFT 0x045e
> +
> +static const WORD PID_XBOX_CONTROLLERS[] =  {
> +    0x0202, /* Xbox Controller */
> +    0x0285, /* Xbox Controller S */
> +    0x0289, /* Xbox Controller S */
> +    0x028e, /* Xbox360 Controller */
> +    0x028f, /* Xbox360 Wireless Controller */
> +    0x02d1, /* Xbox One Controller */
> +    0x02dd, /* Xbox One Controller (Covert Forces/Firmware 2015) */
> +    0x02e0, /* Xbox One X Controller */
> +    0x02e3, /* Xbox One Elite Controller */
> +    0x02e6, /* Wireless XBox Controller Dongle */
> +    0x02ea, /* Xbox One S Controller */
> +    0x02fd, /* Xbox One S Controller (Firmware 2017) */
> +    0x0719, /* Xbox 360 Wireless Adapter */
> +};
> +
>  static inline JoystickGenericImpl *impl_from_IDirectInputDevice8A(IDirectInputDevice8A *iface)
>  {
>      return CONTAINING_RECORD(CONTAINING_RECORD(iface, IDirectInputDeviceImpl, IDirectInputDevice8A_iface), JoystickGenericImpl, base);
> @@ -281,6 +299,19 @@ BOOL device_disabled_registry(const char* name)
>      return do_disable;
>  }
>  
> +BOOL is_xinput_device(const DIDEVCAPS *devcaps, WORD vid, WORD pid)
> +{
> +    int i;
> +
> +    if (vid == VID_MICROSOFT)
> +    {
> +        for (i = 0; i < ARRAY_SIZE(PID_XBOX_CONTROLLERS); i++)
> +            if (pid == PID_XBOX_CONTROLLERS[i]) return TRUE;
> +    }
> +
> +    return (devcaps->dwAxes == 6 && devcaps->dwButtons >= 14);
> +}
> +
>  /******************************************************************************
>    *     SetProperty : change input device properties
>    */
> diff --git a/dlls/dinput/joystick_linux.c b/dlls/dinput/joystick_linux.c
> index 2480bc2b76..7e01f90843 100644
> --- a/dlls/dinput/joystick_linux.c
> +++ b/dlls/dinput/joystick_linux.c
> @@ -59,6 +59,7 @@
>  #include "windef.h"
>  #include "winbase.h"
>  #include "winerror.h"
> +#include "devguid.h"
>  #include "dinput.h"
>  
>  #include "dinput_private.h"
> @@ -742,6 +743,29 @@ static HRESULT WINAPI JoystickLinuxWImpl_GetProperty(LPDIRECTINPUTDEVICE8W iface
>              break;
>          }
>  
> +        case (DWORD_PTR) DIPROP_GUIDANDPATH:
> +        {
> +            static const WCHAR formatW[] = {'\\','\\','?','\\','h','i','d','#','v','i','d','_','%','0','4','x','&',
> +                                            'p','i','d','_','%','0','4','x','&','%','s','_','%','h','u',0};
> +            static const WCHAR miW[] = {'m','i',0};
> +            static const WCHAR igW[] = {'i','g',0};
> +
> +            BOOL is_gamepad;
> +            LPDIPROPGUIDANDPATH pd = (LPDIPROPGUIDANDPATH)pdiph;
> +            WORD vid = This->joydev->vendor_id;
> +            WORD pid = This->joydev->product_id;
> +
> +            if (!pid || !vid)
> +                return DIERR_UNSUPPORTED;
> +
> +            is_gamepad = is_xinput_device(&This->generic.devcaps, vid, pid);
> +            pd->guidClass = GUID_DEVCLASS_HIDCLASS;
> +            sprintfW(pd->wszPath, formatW, vid, pid, is_gamepad ? igW : miW, get_joystick_index(&This->generic.base.guid));
> +
> +            TRACE("DIPROP_GUIDANDPATH(%s, %s): returning fake path\n", debugstr_guid(&pd->guidClass), debugstr_w(pd->wszPath));
> +            break;
> +        }
> +
>      default:
>          return JoystickWGenericImpl_GetProperty(iface, rguid, pdiph);
>      }
> diff --git a/dlls/dinput/joystick_private.h b/dlls/dinput/joystick_private.h
> index e758cacf6d..b786c84dec 100644
> --- a/dlls/dinput/joystick_private.h
> +++ b/dlls/dinput/joystick_private.h
> @@ -96,5 +96,6 @@ HRESULT WINAPI JoystickWGenericImpl_SetActionMap(LPDIRECTINPUTDEVICE8W iface, LP
>  
>  DWORD typeFromGUID(REFGUID guid) DECLSPEC_HIDDEN;
>  void dump_DIEFFECT(LPCDIEFFECT eff, REFGUID guid, DWORD dwFlags) DECLSPEC_HIDDEN;
> +BOOL is_xinput_device(const DIDEVCAPS *devcaps, WORD vid, WORD pid) DECLSPEC_HIDDEN;
>  
>  #endif /* __WINE_DLLS_DINPUT_JOYSTICK_PRIVATE_H */
> -- 
> 2.17.2 (Apple Git-113)
> 
> 
> 



More information about the wine-devel mailing list