mirror of
https://github.com/reactos/reactos.git
synced 2025-07-31 22:02:14 +00:00
[DINPUT] Sync with Wine Staging 4.18. CORE-16441
This commit is contained in:
parent
1477b2deb7
commit
41c8c312e1
16 changed files with 1001 additions and 376 deletions
|
@ -59,6 +59,7 @@
|
|||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winerror.h"
|
||||
#include "devguid.h"
|
||||
#include "dinput.h"
|
||||
|
||||
#include "dinput_private.h"
|
||||
|
@ -84,6 +85,8 @@ struct JoyDev
|
|||
int *dev_axes_map;
|
||||
|
||||
WORD vendor_id, product_id, bus_type;
|
||||
|
||||
BOOL is_joystick;
|
||||
};
|
||||
|
||||
typedef struct JoystickImpl JoystickImpl;
|
||||
|
@ -123,19 +126,6 @@ static const GUID DInput_Wine_Joystick_GUID = { /* 9e573ed9-7734-11d2-8d4a-23903
|
|||
{0x8d, 0x4a, 0x23, 0x90, 0x3f, 0xb6, 0xbd, 0xf7}
|
||||
};
|
||||
|
||||
/*
|
||||
* Construct the GUID in the same way of Windows doing this.
|
||||
* Data1 is concatenation of productid and vendorid.
|
||||
* Data2 and Data3 are NULL.
|
||||
* Data4 seems to be a constant.
|
||||
*/
|
||||
static const GUID DInput_Wine_Joystick_Constant_Part_GUID = {
|
||||
0x000000000,
|
||||
0x0000,
|
||||
0x0000,
|
||||
{0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44}
|
||||
};
|
||||
|
||||
#define MAX_JOYSTICKS 64
|
||||
static INT joystick_devices_count = -1;
|
||||
static struct JoyDev *joystick_devices;
|
||||
|
@ -177,6 +167,8 @@ static INT find_joystick_devices(void)
|
|||
int fd;
|
||||
struct JoyDev joydev, *new_joydevs;
|
||||
BYTE axes_map[ABS_MAX + 1];
|
||||
SHORT btn_map[KEY_MAX - BTN_MISC + 1];
|
||||
BOOL is_stylus = FALSE;
|
||||
|
||||
snprintf(joydev.device, sizeof(joydev.device), "%s%d", JOYDEV_NEW, i);
|
||||
if ((fd = open(joydev.device, O_RDONLY)) == -1)
|
||||
|
@ -220,6 +212,52 @@ static INT find_joystick_devices(void)
|
|||
joydev.button_count = 2;
|
||||
#endif
|
||||
|
||||
joydev.is_joystick = FALSE;
|
||||
if (ioctl(fd, JSIOCGBTNMAP, btn_map) < 0)
|
||||
{
|
||||
WARN("ioctl(%s,JSIOCGBTNMAP) failed: %s\n", joydev.device, strerror(errno));
|
||||
}
|
||||
else
|
||||
{
|
||||
INT j;
|
||||
/* in lieu of properly reporting HID usage, detect presence of
|
||||
* "joystick buttons" and report those devices as joysticks instead of
|
||||
* gamepads */
|
||||
for (j = 0; !joydev.is_joystick && j < joydev.button_count; j++)
|
||||
{
|
||||
switch (btn_map[j])
|
||||
{
|
||||
case BTN_TRIGGER:
|
||||
case BTN_THUMB:
|
||||
case BTN_THUMB2:
|
||||
case BTN_TOP:
|
||||
case BTN_TOP2:
|
||||
case BTN_PINKIE:
|
||||
case BTN_BASE:
|
||||
case BTN_BASE2:
|
||||
case BTN_BASE3:
|
||||
case BTN_BASE4:
|
||||
case BTN_BASE5:
|
||||
case BTN_BASE6:
|
||||
case BTN_DEAD:
|
||||
joydev.is_joystick = TRUE;
|
||||
break;
|
||||
case BTN_STYLUS:
|
||||
is_stylus = TRUE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(is_stylus)
|
||||
{
|
||||
TRACE("Stylus detected. Skipping\n");
|
||||
close(fd);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ioctl(fd, JSIOCGAXMAP, axes_map) < 0)
|
||||
{
|
||||
WARN("ioctl(%s,JSIOCGAXMAP) failed: %s\n", joydev.device, strerror(errno));
|
||||
|
@ -239,6 +277,14 @@ static INT find_joystick_devices(void)
|
|||
joydev.dev_axes_map[j] = j;
|
||||
found_axes++;
|
||||
}
|
||||
else if (axes_map[j] <= 10)
|
||||
{
|
||||
/* Axes 8 through 10 are Wheel, Gas and Brake,
|
||||
* remap to 0, 1 and 2
|
||||
*/
|
||||
joydev.dev_axes_map[j] = axes_map[j] - 8;
|
||||
found_axes++;
|
||||
}
|
||||
else if (axes_map[j] == 16 ||
|
||||
axes_map[j] == 17)
|
||||
{
|
||||
|
@ -279,7 +325,7 @@ static INT find_joystick_devices(void)
|
|||
else
|
||||
{
|
||||
/* Concatenate product_id with vendor_id to mimic Windows behaviour */
|
||||
joydev.guid_product = DInput_Wine_Joystick_Constant_Part_GUID;
|
||||
joydev.guid_product = DInput_PIDVID_Product_GUID;
|
||||
joydev.guid_product.Data1 = MAKELONG(joydev.vendor_id, joydev.product_id);
|
||||
}
|
||||
|
||||
|
@ -314,11 +360,7 @@ static void fill_joystick_dideviceinstanceW(LPDIDEVICEINSTANCEW lpddi, DWORD ver
|
|||
lpddi->guidInstance = DInput_Wine_Joystick_GUID;
|
||||
lpddi->guidInstance.Data3 = id;
|
||||
lpddi->guidProduct = joystick_devices[id].guid_product;
|
||||
/* we only support traditional joysticks for now */
|
||||
if (version >= 0x0800)
|
||||
lpddi->dwDevType = DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_STANDARD << 8);
|
||||
else
|
||||
lpddi->dwDevType = DIDEVTYPE_JOYSTICK | (DIDEVTYPEJOYSTICK_TRADITIONAL << 8);
|
||||
lpddi->dwDevType = get_device_type(version, joystick_devices[id].is_joystick);
|
||||
|
||||
/* Assume the joystick as HID if it is attached to USB bus and has a valid VID/PID */
|
||||
if (joystick_devices[id].bus_type == BUS_USB &&
|
||||
|
@ -326,7 +368,7 @@ static void fill_joystick_dideviceinstanceW(LPDIDEVICEINSTANCEW lpddi, DWORD ver
|
|||
{
|
||||
lpddi->dwDevType |= DIDEVTYPE_HID;
|
||||
lpddi->wUsagePage = 0x01; /* Desktop */
|
||||
if (lpddi->dwDevType == DI8DEVTYPE_JOYSTICK || lpddi->dwDevType == DIDEVTYPE_JOYSTICK)
|
||||
if (joystick_devices[id].is_joystick)
|
||||
lpddi->wUsage = 0x04; /* Joystick */
|
||||
else
|
||||
lpddi->wUsage = 0x05; /* Game Pad */
|
||||
|
@ -372,7 +414,7 @@ static HRESULT joydev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINS
|
|||
}
|
||||
|
||||
if ((dwDevType == 0) ||
|
||||
((dwDevType == DIDEVTYPE_JOYSTICK) && (version > 0x0300 && version < 0x0800)) ||
|
||||
((dwDevType == DIDEVTYPE_JOYSTICK) && (version >= 0x0300 && version < 0x0800)) ||
|
||||
(((dwDevType == DI8DEVCLASS_GAMECTRL) || (dwDevType == DI8DEVTYPE_JOYSTICK)) && (version >= 0x0800))) {
|
||||
/* check whether we have a joystick */
|
||||
if ((fd = open(joystick_devices[id].device, O_RDONLY)) == -1)
|
||||
|
@ -401,7 +443,7 @@ static HRESULT joydev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINS
|
|||
}
|
||||
|
||||
if ((dwDevType == 0) ||
|
||||
((dwDevType == DIDEVTYPE_JOYSTICK) && (version > 0x0300 && version < 0x0800)) ||
|
||||
((dwDevType == DIDEVTYPE_JOYSTICK) && (version >= 0x0300 && version < 0x0800)) ||
|
||||
(((dwDevType == DI8DEVCLASS_GAMECTRL) || (dwDevType == DI8DEVTYPE_JOYSTICK)) && (version >= 0x0800))) {
|
||||
/* check whether we have a joystick */
|
||||
if ((fd = open(joystick_devices[id].device, O_RDONLY)) == -1)
|
||||
|
@ -673,7 +715,7 @@ static HRESULT WINAPI JoystickLinuxWImpl_GetProperty(LPDIRECTINPUTDEVICE8W iface
|
|||
{
|
||||
JoystickImpl *This = impl_from_IDirectInputDevice8W(iface);
|
||||
|
||||
TRACE("(this=%p,%s,%p)\n", iface, debugstr_guid(rguid), pdiph);
|
||||
TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(rguid), pdiph);
|
||||
_dump_DIPROPHEADER(pdiph);
|
||||
|
||||
if (!IS_DIPROP(rguid)) return DI_OK;
|
||||
|
@ -699,6 +741,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);
|
||||
}
|
||||
|
@ -807,10 +872,13 @@ static void joy_polldev(LPDIRECTINPUTDEVICE8A iface)
|
|||
jse.type,jse.number,jse.value);
|
||||
if (jse.type & JS_EVENT_BUTTON)
|
||||
{
|
||||
int button;
|
||||
if (jse.number >= This->generic.devcaps.dwButtons) return;
|
||||
|
||||
inst_id = DIDFT_MAKEINSTANCE(jse.number) | DIDFT_PSHBUTTON;
|
||||
This->generic.js.rgbButtons[jse.number] = value = jse.value ? 0x80 : 0x00;
|
||||
button = This->generic.button_map[jse.number];
|
||||
|
||||
inst_id = DIDFT_MAKEINSTANCE(button) | DIDFT_PSHBUTTON;
|
||||
This->generic.js.rgbButtons[button] = value = jse.value ? 0x80 : 0x00;
|
||||
}
|
||||
else if (jse.type & JS_EVENT_AXIS)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue