Signed-off-by: Rémi Bernon rbernon@codeweavers.com ---
v2: Pass a size to joyGetDevCapsW matching the one passed to joyGetDevCapsA, fixing some tests, as the winejoystick.drv isn't accepting JOYCAPS2W sizes for the moment.
dlls/winmm/joystick.c | 99 ++++++++++++++++++++++++------------------- 1 file changed, 56 insertions(+), 43 deletions(-)
diff --git a/dlls/winmm/joystick.c b/dlls/winmm/joystick.c index 2b1811d3778..bb8142a29a9 100644 --- a/dlls/winmm/joystick.c +++ b/dlls/winmm/joystick.c @@ -167,64 +167,77 @@ UINT WINAPI DECLSPEC_HOTPATCH joyGetNumDevs(void) /************************************************************************** * joyGetDevCapsW [WINMM.@] */ -MMRESULT WINAPI DECLSPEC_HOTPATCH joyGetDevCapsW(UINT_PTR wID, LPJOYCAPSW lpCaps, UINT wSize) +MMRESULT WINAPI DECLSPEC_HOTPATCH joyGetDevCapsW( UINT_PTR id, JOYCAPSW *caps, UINT size ) { - if (wID >= MAXJOYSTICK) return JOYERR_PARMS; - if (!JOY_LoadDriver(wID)) return MMSYSERR_NODRIVER; + TRACE( "id %d, caps %p, size %u.\n", (int)id, caps, size );
- lpCaps->wPeriodMin = JOY_PERIOD_MIN; /* FIXME */ - lpCaps->wPeriodMax = JOY_PERIOD_MAX; /* FIXME (same as MS Joystick Driver) */ + if (!caps) return MMSYSERR_INVALPARAM; + if (size != sizeof(JOYCAPSW) && size != sizeof(JOYCAPS2W)) return JOYERR_PARMS;
- return SendDriverMessage(JOY_Sticks[wID].hDriver, JDD_GETDEVCAPS, (LPARAM)lpCaps, wSize); + if (id >= MAXJOYSTICK) return JOYERR_PARMS; + if (!JOY_LoadDriver( id )) return MMSYSERR_NODRIVER; + + caps->wPeriodMin = JOY_PERIOD_MIN; /* FIXME */ + caps->wPeriodMax = JOY_PERIOD_MAX; /* FIXME (same as MS Joystick Driver) */ + + return SendDriverMessage( JOY_Sticks[id].hDriver, JDD_GETDEVCAPS, (LPARAM)caps, size ); }
/************************************************************************** * joyGetDevCapsA [WINMM.@] */ -MMRESULT WINAPI DECLSPEC_HOTPATCH joyGetDevCapsA(UINT_PTR wID, LPJOYCAPSA lpCaps, UINT wSize) +MMRESULT WINAPI DECLSPEC_HOTPATCH joyGetDevCapsA( UINT_PTR id, JOYCAPSA *caps, UINT size ) { - JOYCAPSW jcw; - MMRESULT ret; + UINT size_w = sizeof(JOYCAPS2W); + JOYCAPS2W caps_w; + MMRESULT res;
- if (lpCaps == NULL) return MMSYSERR_INVALPARAM; + TRACE( "id %d, caps %p, size %u.\n", (int)id, caps, size );
- ret = joyGetDevCapsW(wID, &jcw, sizeof(jcw)); + if (!caps) return MMSYSERR_INVALPARAM; + if (size != sizeof(JOYCAPSA) && size != sizeof(JOYCAPS2A)) return JOYERR_PARMS;
- if (ret == JOYERR_NOERROR) + if (size == sizeof(JOYCAPSA)) size_w = sizeof(JOYCAPSW); + res = joyGetDevCapsW( id, (JOYCAPSW *)&caps_w, size_w ); + if (res) return res; + + caps->wMid = caps_w.wMid; + caps->wPid = caps_w.wPid; + WideCharToMultiByte( CP_ACP, 0, caps_w.szPname, -1, caps->szPname, + sizeof(caps->szPname), NULL, NULL ); + caps->wXmin = caps_w.wXmin; + caps->wXmax = caps_w.wXmax; + caps->wYmin = caps_w.wYmin; + caps->wYmax = caps_w.wYmax; + caps->wZmin = caps_w.wZmin; + caps->wZmax = caps_w.wZmax; + caps->wNumButtons = caps_w.wNumButtons; + caps->wPeriodMin = caps_w.wPeriodMin; + caps->wPeriodMax = caps_w.wPeriodMax; + caps->wRmin = caps_w.wRmin; + caps->wRmax = caps_w.wRmax; + caps->wUmin = caps_w.wUmin; + caps->wUmax = caps_w.wUmax; + caps->wVmin = caps_w.wVmin; + caps->wVmax = caps_w.wVmax; + caps->wCaps = caps_w.wCaps; + caps->wMaxAxes = caps_w.wMaxAxes; + caps->wNumAxes = caps_w.wNumAxes; + caps->wMaxButtons = caps_w.wMaxButtons; + WideCharToMultiByte( CP_ACP, 0, caps_w.szRegKey, -1, caps->szRegKey, + sizeof(caps->szRegKey), NULL, NULL ); + WideCharToMultiByte( CP_ACP, 0, caps_w.szOEMVxD, -1, caps->szOEMVxD, + sizeof(caps->szOEMVxD), NULL, NULL ); + + if (size == sizeof(JOYCAPS2A)) { - lpCaps->wMid = jcw.wMid; - lpCaps->wPid = jcw.wPid; - WideCharToMultiByte( CP_ACP, 0, jcw.szPname, -1, lpCaps->szPname, - sizeof(lpCaps->szPname), NULL, NULL ); - lpCaps->wXmin = jcw.wXmin; - lpCaps->wXmax = jcw.wXmax; - lpCaps->wYmin = jcw.wYmin; - lpCaps->wYmax = jcw.wYmax; - lpCaps->wZmin = jcw.wZmin; - lpCaps->wZmax = jcw.wZmax; - lpCaps->wNumButtons = jcw.wNumButtons; - lpCaps->wPeriodMin = jcw.wPeriodMin; - lpCaps->wPeriodMax = jcw.wPeriodMax; - - if (wSize >= sizeof(JOYCAPSA)) { /* Win95 extensions ? */ - lpCaps->wRmin = jcw.wRmin; - lpCaps->wRmax = jcw.wRmax; - lpCaps->wUmin = jcw.wUmin; - lpCaps->wUmax = jcw.wUmax; - lpCaps->wVmin = jcw.wVmin; - lpCaps->wVmax = jcw.wVmax; - lpCaps->wCaps = jcw.wCaps; - lpCaps->wMaxAxes = jcw.wMaxAxes; - lpCaps->wNumAxes = jcw.wNumAxes; - lpCaps->wMaxButtons = jcw.wMaxButtons; - WideCharToMultiByte( CP_ACP, 0, jcw.szRegKey, -1, lpCaps->szRegKey, - sizeof(lpCaps->szRegKey), NULL, NULL ); - WideCharToMultiByte( CP_ACP, 0, jcw.szOEMVxD, -1, lpCaps->szOEMVxD, - sizeof(lpCaps->szOEMVxD), NULL, NULL ); - } + JOYCAPS2A *caps2_a = (JOYCAPS2A *)caps; + caps2_a->ManufacturerGuid = caps_w.ManufacturerGuid; + caps2_a->ProductGuid = caps_w.ProductGuid; + caps2_a->NameGuid = caps_w.NameGuid; }
- return ret; + return JOYERR_NOERROR; }
/**************************************************************************
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput8/tests/Makefile.in | 2 +- dlls/dinput8/tests/hid.c | 337 +++++++++++++++++++++++++++++++++ 2 files changed, 338 insertions(+), 1 deletion(-)
diff --git a/dlls/dinput8/tests/Makefile.in b/dlls/dinput8/tests/Makefile.in index 18624b9d523..336dbd500ba 100644 --- a/dlls/dinput8/tests/Makefile.in +++ b/dlls/dinput8/tests/Makefile.in @@ -1,5 +1,5 @@ TESTDLL = dinput8.dll -IMPORTS = dinput8 dinput ole32 user32 hid advapi32 uuid crypt32 newdev setupapi wintrust +IMPORTS = dinput8 dinput ole32 user32 hid advapi32 uuid crypt32 newdev setupapi wintrust winmm
driver_hid_IMPORTS = winecrt0 ntoskrnl hal hidclass driver_hid_EXTRADLLFLAGS = -nodefaultlibs -nostartfiles -Wl,--subsystem,native diff --git a/dlls/dinput8/tests/hid.c b/dlls/dinput8/tests/hid.c index 0a58f215ea9..4aa37539202 100644 --- a/dlls/dinput8/tests/hid.c +++ b/dlls/dinput8/tests/hid.c @@ -46,6 +46,7 @@ #include "wingdi.h" #include "dinput.h" #include "dinputd.h" +#include "mmsystem.h"
#include "initguid.h" #include "ddk/wdm.h" @@ -9588,6 +9589,338 @@ done: winetest_pop_context(); }
+static void test_winmm_joystick(void) +{ +#include "psh_hid_macros.h" + const unsigned char report_desc[] = { + USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC), + USAGE(1, HID_USAGE_GENERIC_JOYSTICK), + COLLECTION(1, Application), + USAGE(1, HID_USAGE_GENERIC_JOYSTICK), + COLLECTION(1, Report), + REPORT_ID(1, 1), + + USAGE(1, HID_USAGE_GENERIC_X), + USAGE(1, HID_USAGE_GENERIC_Y), + USAGE(1, HID_USAGE_GENERIC_Z), + USAGE(1, HID_USAGE_GENERIC_WHEEL), + USAGE(1, HID_USAGE_GENERIC_SLIDER), + USAGE(1, HID_USAGE_GENERIC_RX), + USAGE(1, HID_USAGE_GENERIC_RY), + USAGE(1, HID_USAGE_GENERIC_RZ), + LOGICAL_MINIMUM(1, 1), + LOGICAL_MAXIMUM(4, 0xffff), + PHYSICAL_MINIMUM(1, 1), + PHYSICAL_MAXIMUM(4, 0xffff), + REPORT_SIZE(1, 16), + REPORT_COUNT(1, 8), + INPUT(1, Data|Var|Abs), + + USAGE(1, HID_USAGE_GENERIC_HATSWITCH), + LOGICAL_MINIMUM(1, 1), + LOGICAL_MAXIMUM(1, 8), + PHYSICAL_MINIMUM(1, 0), + PHYSICAL_MAXIMUM(1, 8), + REPORT_SIZE(1, 4), + REPORT_COUNT(1, 1), + INPUT(1, Data|Var|Abs|Null), + + USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON), + USAGE_MINIMUM(1, 1), + USAGE_MAXIMUM(1, 4), + LOGICAL_MINIMUM(1, 0), + LOGICAL_MAXIMUM(1, 1), + PHYSICAL_MINIMUM(1, 0), + PHYSICAL_MAXIMUM(1, 1), + REPORT_SIZE(1, 1), + REPORT_COUNT(1, 4), + INPUT(1, Data|Var|Abs), + END_COLLECTION, + END_COLLECTION, + }; +#include "pop_hid_macros.h" + + static const HIDP_CAPS hid_caps = + { + .InputReportByteLength = 18, + }; + static const JOYCAPS2W expect_regcaps = + { + .szRegKey = L"DINPUT.DLL", + }; + static const JOYCAPS2W expect_caps = + { + .wMid = 0x1209, + .wPid = 0x0001, + .szPname = L"Microsoft PC-joystick driver", + .wXmax = 0xffff, + .wYmax = 0xffff, + .wZmax = 0xffff, + .wNumButtons = 4, + .wPeriodMin = 10, + .wPeriodMax = 1000, + .wRmax = 0xffff, + .wUmax = 0xffff, + .wVmax = 0xffff, + .wCaps = JOYCAPS_HASZ|JOYCAPS_HASR|JOYCAPS_HASU|JOYCAPS_HASV|JOYCAPS_HASPOV|JOYCAPS_POV4DIR, + .wMaxAxes = 6, + .wNumAxes = 6, + .wMaxButtons = 32, + .szRegKey = L"DINPUT.DLL", + }; + static const JOYINFOEX expect_infoex = + { + .dwSize = sizeof(JOYINFOEX), + .dwFlags = 0xff, + .dwXpos = 0x7fff, + .dwYpos = 0x7fff, + .dwZpos = 0x7fff, + .dwRpos = 0x7fff, + .dwUpos = 0x7fff, + .dwVpos = 0x7fff, + .dwButtons = 0, + .dwButtonNumber = 0, + .dwPOV = 0xffff, + .dwReserved1 = 0xcdcdcdcd, + .dwReserved2 = 0xcdcdcdcd, + }; + static const JOYINFO expect_info = + { + .wXpos = 0x7fff, + .wYpos = 0x7fff, + .wZpos = 0x7fff, + .wButtons = 0, + }; + JOYINFOEX infoex = {.dwSize = sizeof(JOYINFOEX)}; + WCHAR cwd[MAX_PATH], tempdir[MAX_PATH]; + JOYCAPS2W caps = {0}; + JOYINFO info = {0}; + UINT ret; + + GetCurrentDirectoryW( ARRAY_SIZE(cwd), cwd ); + GetTempPathW( ARRAY_SIZE(tempdir), tempdir ); + SetCurrentDirectoryW( tempdir ); + + cleanup_registry_keys(); + + ret = joyGetNumDevs(); + todo_wine + ok( ret == 16, "joyGetNumDevs returned %u\n", ret ); + + ret = joyGetDevCapsW( 0, (JOYCAPSW *)&caps, sizeof(JOYCAPSW) ); + /* FIXME: Marvin somehow manages to get a device, ignore it */ + if (!strcmp( winetest_platform, "wine") && ret == 0 && + !wcscmp( caps.szPname, L"QEMU Virtio Tablet" )) + return; + ok( ret == JOYERR_PARMS, "joyGetDevCapsW returned %u\n", ret ); + + memset( &caps, 0xcd, sizeof(caps) ); + ret = joyGetDevCapsW( -1, (JOYCAPSW *)&caps, sizeof(caps) ); + todo_wine + ok( ret == 0, "joyGetDevCapsW returned %u\n", ret ); + todo_wine + check_member( caps, expect_regcaps, "%#x", wMid ); + todo_wine + check_member( caps, expect_regcaps, "%#x", wPid ); + todo_wine + check_member_wstr( caps, expect_regcaps, szPname ); + todo_wine + check_member( caps, expect_regcaps, "%#x", wXmin ); + todo_wine + check_member( caps, expect_regcaps, "%#x", wXmax ); + todo_wine + check_member( caps, expect_regcaps, "%#x", wYmin ); + todo_wine + check_member( caps, expect_regcaps, "%#x", wYmax ); + todo_wine + check_member( caps, expect_regcaps, "%#x", wZmin ); + todo_wine + check_member( caps, expect_regcaps, "%#x", wZmax ); + todo_wine + check_member( caps, expect_regcaps, "%#x", wNumButtons ); + todo_wine + check_member( caps, expect_regcaps, "%#x", wPeriodMin ); + todo_wine + check_member( caps, expect_regcaps, "%#x", wPeriodMax ); + todo_wine + check_member( caps, expect_regcaps, "%#x", wRmin ); + todo_wine + check_member( caps, expect_regcaps, "%#x", wRmax ); + todo_wine + check_member( caps, expect_regcaps, "%#x", wUmin ); + todo_wine + check_member( caps, expect_regcaps, "%#x", wUmax ); + todo_wine + check_member( caps, expect_regcaps, "%#x", wVmin ); + todo_wine + check_member( caps, expect_regcaps, "%#x", wVmax ); + todo_wine + check_member( caps, expect_regcaps, "%#x", wCaps ); + todo_wine + check_member( caps, expect_regcaps, "%#x", wMaxAxes ); + todo_wine + check_member( caps, expect_regcaps, "%#x", wNumAxes ); + todo_wine + check_member( caps, expect_regcaps, "%#x", wMaxButtons ); + todo_wine + check_member_wstr( caps, expect_regcaps, szRegKey ); + todo_wine + check_member_wstr( caps, expect_regcaps, szOEMVxD ); + todo_wine + check_member_guid( caps, expect_regcaps, ManufacturerGuid ); + todo_wine + check_member_guid( caps, expect_regcaps, ProductGuid ); + todo_wine + check_member_guid( caps, expect_regcaps, NameGuid ); + + if (!dinput_driver_start( report_desc, sizeof(report_desc), &hid_caps, NULL, 0 )) goto done; + + ret = joyGetNumDevs(); + todo_wine + ok( ret == 16, "joyGetNumDevs returned %u\n", ret ); + + ret = joyGetPosEx( 1, &infoex ); + ok( ret == JOYERR_PARMS, "joyGetPosEx returned %u\n", ret ); + ret = joyGetPosEx( 0, &infoex ); + /* first call for an index sometimes fail */ + if (ret == JOYERR_PARMS) ret = joyGetPosEx( 0, &infoex ); + todo_wine + ok( ret == 0, "joyGetPosEx returned %u\n", ret ); + + ret = joyGetDevCapsW( 1, (JOYCAPSW *)&caps, sizeof(JOYCAPSW) ); + ok( ret == JOYERR_PARMS, "joyGetDevCapsW returned %u\n", ret ); + + memset( &caps, 0xcd, sizeof(caps) ); + ret = joyGetDevCapsW( 0, (JOYCAPSW *)&caps, sizeof(caps) ); + todo_wine + ok( ret == 0, "joyGetDevCapsW returned %u\n", ret ); + todo_wine + check_member( caps, expect_caps, "%#x", wMid ); + todo_wine + check_member( caps, expect_caps, "%#x", wPid ); + todo_wine + check_member_wstr( caps, expect_caps, szPname ); + todo_wine + check_member( caps, expect_caps, "%#x", wXmin ); + todo_wine + check_member( caps, expect_caps, "%#x", wXmax ); + todo_wine + check_member( caps, expect_caps, "%#x", wYmin ); + todo_wine + check_member( caps, expect_caps, "%#x", wYmax ); + todo_wine + check_member( caps, expect_caps, "%#x", wZmin ); + todo_wine + check_member( caps, expect_caps, "%#x", wZmax ); + todo_wine + check_member( caps, expect_caps, "%#x", wNumButtons ); + check_member( caps, expect_caps, "%#x", wPeriodMin ); + check_member( caps, expect_caps, "%#x", wPeriodMax ); + todo_wine + check_member( caps, expect_caps, "%#x", wRmin ); + todo_wine + check_member( caps, expect_caps, "%#x", wRmax ); + todo_wine + check_member( caps, expect_caps, "%#x", wUmin ); + todo_wine + check_member( caps, expect_caps, "%#x", wUmax ); + todo_wine + check_member( caps, expect_caps, "%#x", wVmin ); + todo_wine + check_member( caps, expect_caps, "%#x", wVmax ); + todo_wine + check_member( caps, expect_caps, "%#x", wCaps ); + todo_wine + check_member( caps, expect_caps, "%#x", wMaxAxes ); + todo_wine + check_member( caps, expect_caps, "%#x", wNumAxes ); + todo_wine + check_member( caps, expect_caps, "%#x", wMaxButtons ); + todo_wine + check_member_wstr( caps, expect_caps, szRegKey ); + todo_wine + check_member_wstr( caps, expect_caps, szOEMVxD ); + todo_wine + check_member_guid( caps, expect_caps, ManufacturerGuid ); + todo_wine + check_member_guid( caps, expect_caps, ProductGuid ); + todo_wine + check_member_guid( caps, expect_caps, NameGuid ); + + ret = joyGetDevCapsW( 0, (JOYCAPSW *)&caps, sizeof(JOYCAPSW) ); + todo_wine + ok( ret == 0, "joyGetDevCapsW returned %u\n", ret ); + ret = joyGetDevCapsW( 0, NULL, sizeof(JOYCAPSW) ); + ok( ret == MMSYSERR_INVALPARAM, "joyGetDevCapsW returned %u\n", ret ); + ret = joyGetDevCapsW( 0, (JOYCAPSW *)&caps, sizeof(JOYCAPSW) + 4 ); + ok( ret == JOYERR_PARMS, "joyGetDevCapsW returned %u\n", ret ); + ret = joyGetDevCapsW( 0, (JOYCAPSW *)&caps, sizeof(JOYCAPSW) - 4 ); + ok( ret == JOYERR_PARMS, "joyGetDevCapsW returned %u\n", ret ); + + infoex.dwSize = sizeof(JOYINFOEX); + infoex.dwFlags = JOY_RETURNALL; + ret = joyGetPosEx( -1, &infoex ); + ok( ret == JOYERR_PARMS, "joyGetPosEx returned %u\n", ret ); + ret = joyGetPosEx( 1, &infoex ); + ok( ret == JOYERR_PARMS, "joyGetPosEx returned %u\n", ret ); + ret = joyGetPosEx( 16, &infoex ); + ok( ret == JOYERR_PARMS, "joyGetPosEx returned %u\n", ret ); + + memset( &infoex, 0xcd, sizeof(infoex) ); + infoex.dwSize = sizeof(JOYINFOEX); + infoex.dwFlags = JOY_RETURNALL; + ret = joyGetPosEx( 0, &infoex ); + todo_wine + ok( ret == 0, "joyGetPosEx returned %u\n", ret ); + check_member( infoex, expect_infoex, "%#x", dwSize ); + check_member( infoex, expect_infoex, "%#x", dwFlags ); + todo_wine + check_member( infoex, expect_infoex, "%#x", dwXpos ); + todo_wine + check_member( infoex, expect_infoex, "%#x", dwYpos ); + todo_wine + check_member( infoex, expect_infoex, "%#x", dwZpos ); + todo_wine + check_member( infoex, expect_infoex, "%#x", dwRpos ); + todo_wine + check_member( infoex, expect_infoex, "%#x", dwUpos ); + todo_wine + check_member( infoex, expect_infoex, "%#x", dwVpos ); + check_member( infoex, expect_infoex, "%#x", dwButtons ); + check_member( infoex, expect_infoex, "%#x", dwButtonNumber ); + todo_wine + check_member( infoex, expect_infoex, "%#x", dwPOV ); + todo_wine + check_member( infoex, expect_infoex, "%#x", dwReserved1 ); + todo_wine + check_member( infoex, expect_infoex, "%#x", dwReserved2 ); + + infoex.dwSize = sizeof(JOYINFOEX) - 4; + ret = joyGetPosEx( 0, &infoex ); + ok( ret == JOYERR_PARMS, "joyGetPosEx returned %u\n", ret ); + + ret = joyGetPos( -1, &info ); + ok( ret == JOYERR_PARMS, "joyGetPos returned %u\n", ret ); + ret = joyGetPos( 1, &info ); + ok( ret == JOYERR_PARMS, "joyGetPos returned %u\n", ret ); + memset( &info, 0xcd, sizeof(info) ); + ret = joyGetPos( 0, &info ); + todo_wine + ok( ret == 0, "joyGetPos returned %u\n", ret ); + todo_wine + check_member( info, expect_info, "%#x", wXpos ); + todo_wine + check_member( info, expect_info, "%#x", wYpos ); + todo_wine + check_member( info, expect_info, "%#x", wZpos ); + check_member( info, expect_info, "%#x", wButtons ); + +done: + pnp_driver_stop(); + cleanup_registry_keys(); + SetCurrentDirectoryW( cwd ); +} + START_TEST( hid ) { HANDLE mapping; @@ -9630,6 +9963,10 @@ START_TEST( hid ) CoInitialize( NULL ); if (test_device_types( 0x800 )) { + /* This needs to be done before doing anything involving dinput.dll + * on Windows, or the tests will fail, dinput8.dll is fine though. */ + test_winmm_joystick(); + test_device_types( 0x500 ); test_device_types( 0x700 );
Signed-off-by: Andrew Eikum aeikum@codeweavers.com
On Fri, Dec 03, 2021 at 12:19:02PM +0100, Rémi Bernon wrote:
Signed-off-by: Rémi Bernon rbernon@codeweavers.com
dlls/dinput8/tests/Makefile.in | 2 +- dlls/dinput8/tests/hid.c | 337 +++++++++++++++++++++++++++++++++ 2 files changed, 338 insertions(+), 1 deletion(-)
diff --git a/dlls/dinput8/tests/Makefile.in b/dlls/dinput8/tests/Makefile.in index 18624b9d523..336dbd500ba 100644 --- a/dlls/dinput8/tests/Makefile.in +++ b/dlls/dinput8/tests/Makefile.in @@ -1,5 +1,5 @@ TESTDLL = dinput8.dll -IMPORTS = dinput8 dinput ole32 user32 hid advapi32 uuid crypt32 newdev setupapi wintrust +IMPORTS = dinput8 dinput ole32 user32 hid advapi32 uuid crypt32 newdev setupapi wintrust winmm
driver_hid_IMPORTS = winecrt0 ntoskrnl hal hidclass driver_hid_EXTRADLLFLAGS = -nodefaultlibs -nostartfiles -Wl,--subsystem,native diff --git a/dlls/dinput8/tests/hid.c b/dlls/dinput8/tests/hid.c index 0a58f215ea9..4aa37539202 100644 --- a/dlls/dinput8/tests/hid.c +++ b/dlls/dinput8/tests/hid.c @@ -46,6 +46,7 @@ #include "wingdi.h" #include "dinput.h" #include "dinputd.h" +#include "mmsystem.h"
#include "initguid.h" #include "ddk/wdm.h" @@ -9588,6 +9589,338 @@ done: winetest_pop_context(); }
+static void test_winmm_joystick(void) +{ +#include "psh_hid_macros.h"
- const unsigned char report_desc[] = {
USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC),
USAGE(1, HID_USAGE_GENERIC_JOYSTICK),
COLLECTION(1, Application),
USAGE(1, HID_USAGE_GENERIC_JOYSTICK),
COLLECTION(1, Report),
REPORT_ID(1, 1),
USAGE(1, HID_USAGE_GENERIC_X),
USAGE(1, HID_USAGE_GENERIC_Y),
USAGE(1, HID_USAGE_GENERIC_Z),
USAGE(1, HID_USAGE_GENERIC_WHEEL),
USAGE(1, HID_USAGE_GENERIC_SLIDER),
USAGE(1, HID_USAGE_GENERIC_RX),
USAGE(1, HID_USAGE_GENERIC_RY),
USAGE(1, HID_USAGE_GENERIC_RZ),
LOGICAL_MINIMUM(1, 1),
LOGICAL_MAXIMUM(4, 0xffff),
PHYSICAL_MINIMUM(1, 1),
PHYSICAL_MAXIMUM(4, 0xffff),
REPORT_SIZE(1, 16),
REPORT_COUNT(1, 8),
INPUT(1, Data|Var|Abs),
USAGE(1, HID_USAGE_GENERIC_HATSWITCH),
LOGICAL_MINIMUM(1, 1),
LOGICAL_MAXIMUM(1, 8),
PHYSICAL_MINIMUM(1, 0),
PHYSICAL_MAXIMUM(1, 8),
REPORT_SIZE(1, 4),
REPORT_COUNT(1, 1),
INPUT(1, Data|Var|Abs|Null),
USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON),
USAGE_MINIMUM(1, 1),
USAGE_MAXIMUM(1, 4),
LOGICAL_MINIMUM(1, 0),
LOGICAL_MAXIMUM(1, 1),
PHYSICAL_MINIMUM(1, 0),
PHYSICAL_MAXIMUM(1, 1),
REPORT_SIZE(1, 1),
REPORT_COUNT(1, 4),
INPUT(1, Data|Var|Abs),
END_COLLECTION,
END_COLLECTION,
- };
+#include "pop_hid_macros.h"
- static const HIDP_CAPS hid_caps =
- {
.InputReportByteLength = 18,
- };
- static const JOYCAPS2W expect_regcaps =
- {
.szRegKey = L"DINPUT.DLL",
- };
- static const JOYCAPS2W expect_caps =
- {
.wMid = 0x1209,
.wPid = 0x0001,
.szPname = L"Microsoft PC-joystick driver",
.wXmax = 0xffff,
.wYmax = 0xffff,
.wZmax = 0xffff,
.wNumButtons = 4,
.wPeriodMin = 10,
.wPeriodMax = 1000,
.wRmax = 0xffff,
.wUmax = 0xffff,
.wVmax = 0xffff,
.wCaps = JOYCAPS_HASZ|JOYCAPS_HASR|JOYCAPS_HASU|JOYCAPS_HASV|JOYCAPS_HASPOV|JOYCAPS_POV4DIR,
.wMaxAxes = 6,
.wNumAxes = 6,
.wMaxButtons = 32,
.szRegKey = L"DINPUT.DLL",
- };
- static const JOYINFOEX expect_infoex =
- {
.dwSize = sizeof(JOYINFOEX),
.dwFlags = 0xff,
.dwXpos = 0x7fff,
.dwYpos = 0x7fff,
.dwZpos = 0x7fff,
.dwRpos = 0x7fff,
.dwUpos = 0x7fff,
.dwVpos = 0x7fff,
.dwButtons = 0,
.dwButtonNumber = 0,
.dwPOV = 0xffff,
.dwReserved1 = 0xcdcdcdcd,
.dwReserved2 = 0xcdcdcdcd,
- };
- static const JOYINFO expect_info =
- {
.wXpos = 0x7fff,
.wYpos = 0x7fff,
.wZpos = 0x7fff,
.wButtons = 0,
- };
- JOYINFOEX infoex = {.dwSize = sizeof(JOYINFOEX)};
- WCHAR cwd[MAX_PATH], tempdir[MAX_PATH];
- JOYCAPS2W caps = {0};
- JOYINFO info = {0};
- UINT ret;
- GetCurrentDirectoryW( ARRAY_SIZE(cwd), cwd );
- GetTempPathW( ARRAY_SIZE(tempdir), tempdir );
- SetCurrentDirectoryW( tempdir );
- cleanup_registry_keys();
- ret = joyGetNumDevs();
- todo_wine
- ok( ret == 16, "joyGetNumDevs returned %u\n", ret );
- ret = joyGetDevCapsW( 0, (JOYCAPSW *)&caps, sizeof(JOYCAPSW) );
- /* FIXME: Marvin somehow manages to get a device, ignore it */
- if (!strcmp( winetest_platform, "wine") && ret == 0 &&
!wcscmp( caps.szPname, L"QEMU Virtio Tablet" ))
return;
- ok( ret == JOYERR_PARMS, "joyGetDevCapsW returned %u\n", ret );
- memset( &caps, 0xcd, sizeof(caps) );
- ret = joyGetDevCapsW( -1, (JOYCAPSW *)&caps, sizeof(caps) );
- todo_wine
- ok( ret == 0, "joyGetDevCapsW returned %u\n", ret );
- todo_wine
- check_member( caps, expect_regcaps, "%#x", wMid );
- todo_wine
- check_member( caps, expect_regcaps, "%#x", wPid );
- todo_wine
- check_member_wstr( caps, expect_regcaps, szPname );
- todo_wine
- check_member( caps, expect_regcaps, "%#x", wXmin );
- todo_wine
- check_member( caps, expect_regcaps, "%#x", wXmax );
- todo_wine
- check_member( caps, expect_regcaps, "%#x", wYmin );
- todo_wine
- check_member( caps, expect_regcaps, "%#x", wYmax );
- todo_wine
- check_member( caps, expect_regcaps, "%#x", wZmin );
- todo_wine
- check_member( caps, expect_regcaps, "%#x", wZmax );
- todo_wine
- check_member( caps, expect_regcaps, "%#x", wNumButtons );
- todo_wine
- check_member( caps, expect_regcaps, "%#x", wPeriodMin );
- todo_wine
- check_member( caps, expect_regcaps, "%#x", wPeriodMax );
- todo_wine
- check_member( caps, expect_regcaps, "%#x", wRmin );
- todo_wine
- check_member( caps, expect_regcaps, "%#x", wRmax );
- todo_wine
- check_member( caps, expect_regcaps, "%#x", wUmin );
- todo_wine
- check_member( caps, expect_regcaps, "%#x", wUmax );
- todo_wine
- check_member( caps, expect_regcaps, "%#x", wVmin );
- todo_wine
- check_member( caps, expect_regcaps, "%#x", wVmax );
- todo_wine
- check_member( caps, expect_regcaps, "%#x", wCaps );
- todo_wine
- check_member( caps, expect_regcaps, "%#x", wMaxAxes );
- todo_wine
- check_member( caps, expect_regcaps, "%#x", wNumAxes );
- todo_wine
- check_member( caps, expect_regcaps, "%#x", wMaxButtons );
- todo_wine
- check_member_wstr( caps, expect_regcaps, szRegKey );
- todo_wine
- check_member_wstr( caps, expect_regcaps, szOEMVxD );
- todo_wine
- check_member_guid( caps, expect_regcaps, ManufacturerGuid );
- todo_wine
- check_member_guid( caps, expect_regcaps, ProductGuid );
- todo_wine
- check_member_guid( caps, expect_regcaps, NameGuid );
- if (!dinput_driver_start( report_desc, sizeof(report_desc), &hid_caps, NULL, 0 )) goto done;
- ret = joyGetNumDevs();
- todo_wine
- ok( ret == 16, "joyGetNumDevs returned %u\n", ret );
- ret = joyGetPosEx( 1, &infoex );
- ok( ret == JOYERR_PARMS, "joyGetPosEx returned %u\n", ret );
- ret = joyGetPosEx( 0, &infoex );
- /* first call for an index sometimes fail */
- if (ret == JOYERR_PARMS) ret = joyGetPosEx( 0, &infoex );
- todo_wine
- ok( ret == 0, "joyGetPosEx returned %u\n", ret );
- ret = joyGetDevCapsW( 1, (JOYCAPSW *)&caps, sizeof(JOYCAPSW) );
- ok( ret == JOYERR_PARMS, "joyGetDevCapsW returned %u\n", ret );
- memset( &caps, 0xcd, sizeof(caps) );
- ret = joyGetDevCapsW( 0, (JOYCAPSW *)&caps, sizeof(caps) );
- todo_wine
- ok( ret == 0, "joyGetDevCapsW returned %u\n", ret );
- todo_wine
- check_member( caps, expect_caps, "%#x", wMid );
- todo_wine
- check_member( caps, expect_caps, "%#x", wPid );
- todo_wine
- check_member_wstr( caps, expect_caps, szPname );
- todo_wine
- check_member( caps, expect_caps, "%#x", wXmin );
- todo_wine
- check_member( caps, expect_caps, "%#x", wXmax );
- todo_wine
- check_member( caps, expect_caps, "%#x", wYmin );
- todo_wine
- check_member( caps, expect_caps, "%#x", wYmax );
- todo_wine
- check_member( caps, expect_caps, "%#x", wZmin );
- todo_wine
- check_member( caps, expect_caps, "%#x", wZmax );
- todo_wine
- check_member( caps, expect_caps, "%#x", wNumButtons );
- check_member( caps, expect_caps, "%#x", wPeriodMin );
- check_member( caps, expect_caps, "%#x", wPeriodMax );
- todo_wine
- check_member( caps, expect_caps, "%#x", wRmin );
- todo_wine
- check_member( caps, expect_caps, "%#x", wRmax );
- todo_wine
- check_member( caps, expect_caps, "%#x", wUmin );
- todo_wine
- check_member( caps, expect_caps, "%#x", wUmax );
- todo_wine
- check_member( caps, expect_caps, "%#x", wVmin );
- todo_wine
- check_member( caps, expect_caps, "%#x", wVmax );
- todo_wine
- check_member( caps, expect_caps, "%#x", wCaps );
- todo_wine
- check_member( caps, expect_caps, "%#x", wMaxAxes );
- todo_wine
- check_member( caps, expect_caps, "%#x", wNumAxes );
- todo_wine
- check_member( caps, expect_caps, "%#x", wMaxButtons );
- todo_wine
- check_member_wstr( caps, expect_caps, szRegKey );
- todo_wine
- check_member_wstr( caps, expect_caps, szOEMVxD );
- todo_wine
- check_member_guid( caps, expect_caps, ManufacturerGuid );
- todo_wine
- check_member_guid( caps, expect_caps, ProductGuid );
- todo_wine
- check_member_guid( caps, expect_caps, NameGuid );
- ret = joyGetDevCapsW( 0, (JOYCAPSW *)&caps, sizeof(JOYCAPSW) );
- todo_wine
- ok( ret == 0, "joyGetDevCapsW returned %u\n", ret );
- ret = joyGetDevCapsW( 0, NULL, sizeof(JOYCAPSW) );
- ok( ret == MMSYSERR_INVALPARAM, "joyGetDevCapsW returned %u\n", ret );
- ret = joyGetDevCapsW( 0, (JOYCAPSW *)&caps, sizeof(JOYCAPSW) + 4 );
- ok( ret == JOYERR_PARMS, "joyGetDevCapsW returned %u\n", ret );
- ret = joyGetDevCapsW( 0, (JOYCAPSW *)&caps, sizeof(JOYCAPSW) - 4 );
- ok( ret == JOYERR_PARMS, "joyGetDevCapsW returned %u\n", ret );
- infoex.dwSize = sizeof(JOYINFOEX);
- infoex.dwFlags = JOY_RETURNALL;
- ret = joyGetPosEx( -1, &infoex );
- ok( ret == JOYERR_PARMS, "joyGetPosEx returned %u\n", ret );
- ret = joyGetPosEx( 1, &infoex );
- ok( ret == JOYERR_PARMS, "joyGetPosEx returned %u\n", ret );
- ret = joyGetPosEx( 16, &infoex );
- ok( ret == JOYERR_PARMS, "joyGetPosEx returned %u\n", ret );
- memset( &infoex, 0xcd, sizeof(infoex) );
- infoex.dwSize = sizeof(JOYINFOEX);
- infoex.dwFlags = JOY_RETURNALL;
- ret = joyGetPosEx( 0, &infoex );
- todo_wine
- ok( ret == 0, "joyGetPosEx returned %u\n", ret );
- check_member( infoex, expect_infoex, "%#x", dwSize );
- check_member( infoex, expect_infoex, "%#x", dwFlags );
- todo_wine
- check_member( infoex, expect_infoex, "%#x", dwXpos );
- todo_wine
- check_member( infoex, expect_infoex, "%#x", dwYpos );
- todo_wine
- check_member( infoex, expect_infoex, "%#x", dwZpos );
- todo_wine
- check_member( infoex, expect_infoex, "%#x", dwRpos );
- todo_wine
- check_member( infoex, expect_infoex, "%#x", dwUpos );
- todo_wine
- check_member( infoex, expect_infoex, "%#x", dwVpos );
- check_member( infoex, expect_infoex, "%#x", dwButtons );
- check_member( infoex, expect_infoex, "%#x", dwButtonNumber );
- todo_wine
- check_member( infoex, expect_infoex, "%#x", dwPOV );
- todo_wine
- check_member( infoex, expect_infoex, "%#x", dwReserved1 );
- todo_wine
- check_member( infoex, expect_infoex, "%#x", dwReserved2 );
- infoex.dwSize = sizeof(JOYINFOEX) - 4;
- ret = joyGetPosEx( 0, &infoex );
- ok( ret == JOYERR_PARMS, "joyGetPosEx returned %u\n", ret );
- ret = joyGetPos( -1, &info );
- ok( ret == JOYERR_PARMS, "joyGetPos returned %u\n", ret );
- ret = joyGetPos( 1, &info );
- ok( ret == JOYERR_PARMS, "joyGetPos returned %u\n", ret );
- memset( &info, 0xcd, sizeof(info) );
- ret = joyGetPos( 0, &info );
- todo_wine
- ok( ret == 0, "joyGetPos returned %u\n", ret );
- todo_wine
- check_member( info, expect_info, "%#x", wXpos );
- todo_wine
- check_member( info, expect_info, "%#x", wYpos );
- todo_wine
- check_member( info, expect_info, "%#x", wZpos );
- check_member( info, expect_info, "%#x", wButtons );
+done:
- pnp_driver_stop();
- cleanup_registry_keys();
- SetCurrentDirectoryW( cwd );
+}
START_TEST( hid ) { HANDLE mapping; @@ -9630,6 +9963,10 @@ START_TEST( hid ) CoInitialize( NULL ); if (test_device_types( 0x800 )) {
/* This needs to be done before doing anything involving dinput.dll
* on Windows, or the tests will fail, dinput8.dll is fine though. */
test_winmm_joystick();
test_device_types( 0x500 ); test_device_types( 0x700 );
-- 2.34.0
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput8/tests/hid.c | 171 ++++++++++++++++++++++++++++++++------- 1 file changed, 144 insertions(+), 27 deletions(-)
diff --git a/dlls/dinput8/tests/hid.c b/dlls/dinput8/tests/hid.c index 4aa37539202..677d436b894 100644 --- a/dlls/dinput8/tests/hid.c +++ b/dlls/dinput8/tests/hid.c @@ -9668,21 +9668,37 @@ static void test_winmm_joystick(void) .wMaxButtons = 32, .szRegKey = L"DINPUT.DLL", }; - static const JOYINFOEX expect_infoex = + struct hid_expect injected_input[] = { - .dwSize = sizeof(JOYINFOEX), - .dwFlags = 0xff, - .dwXpos = 0x7fff, - .dwYpos = 0x7fff, - .dwZpos = 0x7fff, - .dwRpos = 0x7fff, - .dwUpos = 0x7fff, - .dwVpos = 0x7fff, - .dwButtons = 0, - .dwButtonNumber = 0, - .dwPOV = 0xffff, - .dwReserved1 = 0xcdcdcdcd, - .dwReserved2 = 0xcdcdcdcd, + { + .code = IOCTL_HID_READ_REPORT, + .report_buf = {1,0x00,0x00,0x00,0x08,0x00,0x10,0x00,0x18,0x00,0x20,0x00,0x28,0x00,0x30,0x00,0x38,0xf1}, + }, + { + .code = IOCTL_HID_READ_REPORT, + .report_buf = {1,0x00,0x38,0x00,0x30,0x00,0x28,0x00,0x20,0x00,0x18,0x00,0x10,0x00,0x08,0x00,0x00,0x63}, + }, + }; + static const JOYINFOEX expect_infoex[] = + { + { + .dwSize = sizeof(JOYINFOEX), .dwFlags = 0xff, + .dwXpos = 0x7fff, .dwYpos = 0x7fff, .dwZpos = 0x7fff, .dwRpos = 0x7fff, .dwUpos = 0x7fff, .dwVpos = 0x7fff, + .dwButtons = 0, .dwButtonNumber = 0, .dwPOV = 0xffff, + .dwReserved1 = 0xcdcdcdcd, .dwReserved2 = 0xcdcdcdcd, + }, + { + .dwSize = sizeof(JOYINFOEX), .dwFlags = 0xff, + .dwXpos = 0, .dwYpos = 0x07ff, .dwZpos = 0x17ff, .dwRpos = 0x37ff, .dwUpos = 0x1fff, .dwVpos = 0x27ff, + .dwButtons = 0xf, .dwButtonNumber = 0x4, .dwPOV = 0, + .dwReserved1 = 0xcdcdcdcd, .dwReserved2 = 0xcdcdcdcd, + }, + { + .dwSize = sizeof(JOYINFOEX), .dwFlags = 0xff, + .dwXpos = 0x37ff, .dwYpos = 0x2fff, .dwZpos = 0x1fff, .dwRpos = 0, .dwUpos = 0x17ff, .dwVpos = 0x0fff, + .dwButtons = 0x6, .dwButtonNumber = 0x2, .dwPOV = 0x2328, + .dwReserved1 = 0xcdcdcdcd, .dwReserved2 = 0xcdcdcdcd, + }, }; static const JOYINFO expect_info = { @@ -9692,9 +9708,22 @@ static void test_winmm_joystick(void) .wButtons = 0, }; JOYINFOEX infoex = {.dwSize = sizeof(JOYINFOEX)}; + DIPROPGUIDANDPATH prop_guid_path = + { + .diph = + { + .dwSize = sizeof(DIPROPGUIDANDPATH), + .dwHeaderSize = sizeof(DIPROPHEADER), + .dwHow = DIPH_DEVICE, + }, + }; WCHAR cwd[MAX_PATH], tempdir[MAX_PATH]; + DIDEVICEINSTANCEW devinst = {0}; + IDirectInputDevice8W *device; JOYCAPS2W caps = {0}; JOYINFO info = {0}; + HANDLE event, file; + HRESULT hr; UINT ret;
GetCurrentDirectoryW( ARRAY_SIZE(cwd), cwd ); @@ -9872,28 +9901,28 @@ static void test_winmm_joystick(void) ret = joyGetPosEx( 0, &infoex ); todo_wine ok( ret == 0, "joyGetPosEx returned %u\n", ret ); - check_member( infoex, expect_infoex, "%#x", dwSize ); - check_member( infoex, expect_infoex, "%#x", dwFlags ); + check_member( infoex, expect_infoex[0], "%#x", dwSize ); + check_member( infoex, expect_infoex[0], "%#x", dwFlags ); todo_wine - check_member( infoex, expect_infoex, "%#x", dwXpos ); + check_member( infoex, expect_infoex[0], "%#x", dwXpos ); todo_wine - check_member( infoex, expect_infoex, "%#x", dwYpos ); + check_member( infoex, expect_infoex[0], "%#x", dwYpos ); todo_wine - check_member( infoex, expect_infoex, "%#x", dwZpos ); + check_member( infoex, expect_infoex[0], "%#x", dwZpos ); todo_wine - check_member( infoex, expect_infoex, "%#x", dwRpos ); + check_member( infoex, expect_infoex[0], "%#x", dwRpos ); todo_wine - check_member( infoex, expect_infoex, "%#x", dwUpos ); + check_member( infoex, expect_infoex[0], "%#x", dwUpos ); todo_wine - check_member( infoex, expect_infoex, "%#x", dwVpos ); - check_member( infoex, expect_infoex, "%#x", dwButtons ); - check_member( infoex, expect_infoex, "%#x", dwButtonNumber ); + check_member( infoex, expect_infoex[0], "%#x", dwVpos ); + check_member( infoex, expect_infoex[0], "%#x", dwButtons ); + check_member( infoex, expect_infoex[0], "%#x", dwButtonNumber ); todo_wine - check_member( infoex, expect_infoex, "%#x", dwPOV ); + check_member( infoex, expect_infoex[0], "%#x", dwPOV ); todo_wine - check_member( infoex, expect_infoex, "%#x", dwReserved1 ); + check_member( infoex, expect_infoex[0], "%#x", dwReserved1 ); todo_wine - check_member( infoex, expect_infoex, "%#x", dwReserved2 ); + check_member( infoex, expect_infoex[0], "%#x", dwReserved2 );
infoex.dwSize = sizeof(JOYINFOEX) - 4; ret = joyGetPosEx( 0, &infoex ); @@ -9915,6 +9944,94 @@ static void test_winmm_joystick(void) check_member( info, expect_info, "%#x", wZpos ); check_member( info, expect_info, "%#x", wButtons );
+ if (FAILED(hr = create_dinput_device( DIRECTINPUT_VERSION, &devinst, &device ))) goto done; + + event = CreateEventW( NULL, FALSE, FALSE, NULL ); + ok( event != NULL, "CreateEventW failed, last error %u\n", GetLastError() ); + hr = IDirectInputDevice8_SetEventNotification( device, event ); + ok( hr == DI_OK, "SetEventNotification returned: %#x\n", hr ); + + hr = IDirectInputDevice8_GetProperty( device, DIPROP_GUIDANDPATH, &prop_guid_path.diph ); + ok( hr == DI_OK, "GetProperty DIPROP_GUIDANDPATH returned %#x\n", hr ); + file = CreateFileW( prop_guid_path.wszPath, FILE_READ_ACCESS | FILE_WRITE_ACCESS, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, + FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING, NULL ); + ok( file != INVALID_HANDLE_VALUE, "got error %u\n", GetLastError() ); + + hr = IDirectInputDevice8_SetDataFormat( device, &c_dfDIJoystick2 ); + ok( hr == DI_OK, "SetDataFormat returned: %#x\n", hr ); + hr = IDirectInputDevice8_SetCooperativeLevel( device, NULL, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE ); + ok( hr == DI_OK, "SetCooperativeLevel returned: %#x\n", hr ); + hr = IDirectInputDevice8_Acquire( device ); + ok( hr == DI_OK, "Acquire returned: %#x\n", hr ); + + send_hid_input( file, &injected_input[0], sizeof(struct hid_expect) ); + ret = WaitForSingleObject( event, 100 ); + ok( ret != WAIT_TIMEOUT, "WaitForSingleObject returned %#x\n", ret ); + Sleep( 50 ); /* leave some time for winmm to keep up */ + + memset( &infoex, 0xcd, sizeof(infoex) ); + infoex.dwSize = sizeof(JOYINFOEX); + infoex.dwFlags = JOY_RETURNALL; + ret = joyGetPosEx( 0, &infoex ); + todo_wine + ok( ret == 0, "joyGetPosEx returned %u\n", ret ); + check_member( infoex, expect_infoex[1], "%#x", dwSize ); + check_member( infoex, expect_infoex[1], "%#x", dwFlags ); + check_member( infoex, expect_infoex[1], "%#x", dwXpos ); + todo_wine + check_member( infoex, expect_infoex[1], "%#x", dwYpos ); + todo_wine + check_member( infoex, expect_infoex[1], "%#x", dwZpos ); + todo_wine + check_member( infoex, expect_infoex[1], "%#x", dwRpos ); + todo_wine + check_member( infoex, expect_infoex[1], "%#x", dwUpos ); + todo_wine + check_member( infoex, expect_infoex[1], "%#x", dwVpos ); + todo_wine + check_member( infoex, expect_infoex[1], "%#x", dwButtons ); + todo_wine + check_member( infoex, expect_infoex[1], "%#x", dwButtonNumber ); + check_member( infoex, expect_infoex[1], "%#x", dwPOV ); + + send_hid_input( file, &injected_input[1], sizeof(struct hid_expect) ); + ret = WaitForSingleObject( event, 100 ); + ok( ret != WAIT_TIMEOUT, "WaitForSingleObject returned %#x\n", ret ); + Sleep( 50 ); /* leave some time for winmm to keep up */ + + memset( &infoex, 0xcd, sizeof(infoex) ); + infoex.dwSize = sizeof(JOYINFOEX); + infoex.dwFlags = JOY_RETURNALL; + ret = joyGetPosEx( 0, &infoex ); + todo_wine + ok( ret == 0, "joyGetPosEx returned %u\n", ret ); + check_member( infoex, expect_infoex[2], "%#x", dwSize ); + check_member( infoex, expect_infoex[2], "%#x", dwFlags ); + todo_wine + check_member( infoex, expect_infoex[2], "%#x", dwXpos ); + todo_wine + check_member( infoex, expect_infoex[2], "%#x", dwYpos ); + todo_wine + check_member( infoex, expect_infoex[2], "%#x", dwZpos ); + check_member( infoex, expect_infoex[2], "%#x", dwRpos ); + todo_wine + check_member( infoex, expect_infoex[2], "%#x", dwUpos ); + todo_wine + check_member( infoex, expect_infoex[2], "%#x", dwVpos ); + todo_wine + check_member( infoex, expect_infoex[2], "%#x", dwButtons ); + todo_wine + check_member( infoex, expect_infoex[2], "%#x", dwButtonNumber ); + todo_wine + check_member( infoex, expect_infoex[2], "%#x", dwPOV ); + + ret = IDirectInputDevice8_Release( device ); + ok( ret == 0, "Release returned %d\n", ret ); + + CloseHandle( event ); + CloseHandle( file ); + done: pnp_driver_stop(); cleanup_registry_keys();
Signed-off-by: Andrew Eikum aeikum@codeweavers.com
On Fri, Dec 03, 2021 at 12:19:03PM +0100, Rémi Bernon wrote:
Signed-off-by: Rémi Bernon rbernon@codeweavers.com
dlls/dinput8/tests/hid.c | 171 ++++++++++++++++++++++++++++++++------- 1 file changed, 144 insertions(+), 27 deletions(-)
diff --git a/dlls/dinput8/tests/hid.c b/dlls/dinput8/tests/hid.c index 4aa37539202..677d436b894 100644 --- a/dlls/dinput8/tests/hid.c +++ b/dlls/dinput8/tests/hid.c @@ -9668,21 +9668,37 @@ static void test_winmm_joystick(void) .wMaxButtons = 32, .szRegKey = L"DINPUT.DLL", };
- static const JOYINFOEX expect_infoex =
- struct hid_expect injected_input[] = {
.dwSize = sizeof(JOYINFOEX),
.dwFlags = 0xff,
.dwXpos = 0x7fff,
.dwYpos = 0x7fff,
.dwZpos = 0x7fff,
.dwRpos = 0x7fff,
.dwUpos = 0x7fff,
.dwVpos = 0x7fff,
.dwButtons = 0,
.dwButtonNumber = 0,
.dwPOV = 0xffff,
.dwReserved1 = 0xcdcdcdcd,
.dwReserved2 = 0xcdcdcdcd,
{
.code = IOCTL_HID_READ_REPORT,
.report_buf = {1,0x00,0x00,0x00,0x08,0x00,0x10,0x00,0x18,0x00,0x20,0x00,0x28,0x00,0x30,0x00,0x38,0xf1},
},
{
.code = IOCTL_HID_READ_REPORT,
.report_buf = {1,0x00,0x38,0x00,0x30,0x00,0x28,0x00,0x20,0x00,0x18,0x00,0x10,0x00,0x08,0x00,0x00,0x63},
},
- };
- static const JOYINFOEX expect_infoex[] =
- {
{
.dwSize = sizeof(JOYINFOEX), .dwFlags = 0xff,
.dwXpos = 0x7fff, .dwYpos = 0x7fff, .dwZpos = 0x7fff, .dwRpos = 0x7fff, .dwUpos = 0x7fff, .dwVpos = 0x7fff,
.dwButtons = 0, .dwButtonNumber = 0, .dwPOV = 0xffff,
.dwReserved1 = 0xcdcdcdcd, .dwReserved2 = 0xcdcdcdcd,
},
{
.dwSize = sizeof(JOYINFOEX), .dwFlags = 0xff,
.dwXpos = 0, .dwYpos = 0x07ff, .dwZpos = 0x17ff, .dwRpos = 0x37ff, .dwUpos = 0x1fff, .dwVpos = 0x27ff,
.dwButtons = 0xf, .dwButtonNumber = 0x4, .dwPOV = 0,
.dwReserved1 = 0xcdcdcdcd, .dwReserved2 = 0xcdcdcdcd,
},
{
.dwSize = sizeof(JOYINFOEX), .dwFlags = 0xff,
.dwXpos = 0x37ff, .dwYpos = 0x2fff, .dwZpos = 0x1fff, .dwRpos = 0, .dwUpos = 0x17ff, .dwVpos = 0x0fff,
.dwButtons = 0x6, .dwButtonNumber = 0x2, .dwPOV = 0x2328,
.dwReserved1 = 0xcdcdcdcd, .dwReserved2 = 0xcdcdcdcd,
}; static const JOYINFO expect_info = {},
@@ -9692,9 +9708,22 @@ static void test_winmm_joystick(void) .wButtons = 0, }; JOYINFOEX infoex = {.dwSize = sizeof(JOYINFOEX)};
DIPROPGUIDANDPATH prop_guid_path =
{
.diph =
{
.dwSize = sizeof(DIPROPGUIDANDPATH),
.dwHeaderSize = sizeof(DIPROPHEADER),
.dwHow = DIPH_DEVICE,
},
}; WCHAR cwd[MAX_PATH], tempdir[MAX_PATH];
DIDEVICEINSTANCEW devinst = {0};
IDirectInputDevice8W *device; JOYCAPS2W caps = {0}; JOYINFO info = {0};
HANDLE event, file;
HRESULT hr; UINT ret;
GetCurrentDirectoryW( ARRAY_SIZE(cwd), cwd );
@@ -9872,28 +9901,28 @@ static void test_winmm_joystick(void) ret = joyGetPosEx( 0, &infoex ); todo_wine ok( ret == 0, "joyGetPosEx returned %u\n", ret );
- check_member( infoex, expect_infoex, "%#x", dwSize );
- check_member( infoex, expect_infoex, "%#x", dwFlags );
- check_member( infoex, expect_infoex[0], "%#x", dwSize );
- check_member( infoex, expect_infoex[0], "%#x", dwFlags ); todo_wine
- check_member( infoex, expect_infoex, "%#x", dwXpos );
- check_member( infoex, expect_infoex[0], "%#x", dwXpos ); todo_wine
- check_member( infoex, expect_infoex, "%#x", dwYpos );
- check_member( infoex, expect_infoex[0], "%#x", dwYpos ); todo_wine
- check_member( infoex, expect_infoex, "%#x", dwZpos );
- check_member( infoex, expect_infoex[0], "%#x", dwZpos ); todo_wine
- check_member( infoex, expect_infoex, "%#x", dwRpos );
- check_member( infoex, expect_infoex[0], "%#x", dwRpos ); todo_wine
- check_member( infoex, expect_infoex, "%#x", dwUpos );
- check_member( infoex, expect_infoex[0], "%#x", dwUpos ); todo_wine
- check_member( infoex, expect_infoex, "%#x", dwVpos );
- check_member( infoex, expect_infoex, "%#x", dwButtons );
- check_member( infoex, expect_infoex, "%#x", dwButtonNumber );
- check_member( infoex, expect_infoex[0], "%#x", dwVpos );
- check_member( infoex, expect_infoex[0], "%#x", dwButtons );
- check_member( infoex, expect_infoex[0], "%#x", dwButtonNumber ); todo_wine
- check_member( infoex, expect_infoex, "%#x", dwPOV );
- check_member( infoex, expect_infoex[0], "%#x", dwPOV ); todo_wine
- check_member( infoex, expect_infoex, "%#x", dwReserved1 );
- check_member( infoex, expect_infoex[0], "%#x", dwReserved1 ); todo_wine
- check_member( infoex, expect_infoex, "%#x", dwReserved2 );
check_member( infoex, expect_infoex[0], "%#x", dwReserved2 );
infoex.dwSize = sizeof(JOYINFOEX) - 4; ret = joyGetPosEx( 0, &infoex );
@@ -9915,6 +9944,94 @@ static void test_winmm_joystick(void) check_member( info, expect_info, "%#x", wZpos ); check_member( info, expect_info, "%#x", wButtons );
- if (FAILED(hr = create_dinput_device( DIRECTINPUT_VERSION, &devinst, &device ))) goto done;
- event = CreateEventW( NULL, FALSE, FALSE, NULL );
- ok( event != NULL, "CreateEventW failed, last error %u\n", GetLastError() );
- hr = IDirectInputDevice8_SetEventNotification( device, event );
- ok( hr == DI_OK, "SetEventNotification returned: %#x\n", hr );
- hr = IDirectInputDevice8_GetProperty( device, DIPROP_GUIDANDPATH, &prop_guid_path.diph );
- ok( hr == DI_OK, "GetProperty DIPROP_GUIDANDPATH returned %#x\n", hr );
- file = CreateFileW( prop_guid_path.wszPath, FILE_READ_ACCESS | FILE_WRITE_ACCESS,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING, NULL );
- ok( file != INVALID_HANDLE_VALUE, "got error %u\n", GetLastError() );
- hr = IDirectInputDevice8_SetDataFormat( device, &c_dfDIJoystick2 );
- ok( hr == DI_OK, "SetDataFormat returned: %#x\n", hr );
- hr = IDirectInputDevice8_SetCooperativeLevel( device, NULL, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE );
- ok( hr == DI_OK, "SetCooperativeLevel returned: %#x\n", hr );
- hr = IDirectInputDevice8_Acquire( device );
- ok( hr == DI_OK, "Acquire returned: %#x\n", hr );
- send_hid_input( file, &injected_input[0], sizeof(struct hid_expect) );
- ret = WaitForSingleObject( event, 100 );
- ok( ret != WAIT_TIMEOUT, "WaitForSingleObject returned %#x\n", ret );
- Sleep( 50 ); /* leave some time for winmm to keep up */
- memset( &infoex, 0xcd, sizeof(infoex) );
- infoex.dwSize = sizeof(JOYINFOEX);
- infoex.dwFlags = JOY_RETURNALL;
- ret = joyGetPosEx( 0, &infoex );
- todo_wine
- ok( ret == 0, "joyGetPosEx returned %u\n", ret );
- check_member( infoex, expect_infoex[1], "%#x", dwSize );
- check_member( infoex, expect_infoex[1], "%#x", dwFlags );
- check_member( infoex, expect_infoex[1], "%#x", dwXpos );
- todo_wine
- check_member( infoex, expect_infoex[1], "%#x", dwYpos );
- todo_wine
- check_member( infoex, expect_infoex[1], "%#x", dwZpos );
- todo_wine
- check_member( infoex, expect_infoex[1], "%#x", dwRpos );
- todo_wine
- check_member( infoex, expect_infoex[1], "%#x", dwUpos );
- todo_wine
- check_member( infoex, expect_infoex[1], "%#x", dwVpos );
- todo_wine
- check_member( infoex, expect_infoex[1], "%#x", dwButtons );
- todo_wine
- check_member( infoex, expect_infoex[1], "%#x", dwButtonNumber );
- check_member( infoex, expect_infoex[1], "%#x", dwPOV );
- send_hid_input( file, &injected_input[1], sizeof(struct hid_expect) );
- ret = WaitForSingleObject( event, 100 );
- ok( ret != WAIT_TIMEOUT, "WaitForSingleObject returned %#x\n", ret );
- Sleep( 50 ); /* leave some time for winmm to keep up */
- memset( &infoex, 0xcd, sizeof(infoex) );
- infoex.dwSize = sizeof(JOYINFOEX);
- infoex.dwFlags = JOY_RETURNALL;
- ret = joyGetPosEx( 0, &infoex );
- todo_wine
- ok( ret == 0, "joyGetPosEx returned %u\n", ret );
- check_member( infoex, expect_infoex[2], "%#x", dwSize );
- check_member( infoex, expect_infoex[2], "%#x", dwFlags );
- todo_wine
- check_member( infoex, expect_infoex[2], "%#x", dwXpos );
- todo_wine
- check_member( infoex, expect_infoex[2], "%#x", dwYpos );
- todo_wine
- check_member( infoex, expect_infoex[2], "%#x", dwZpos );
- check_member( infoex, expect_infoex[2], "%#x", dwRpos );
- todo_wine
- check_member( infoex, expect_infoex[2], "%#x", dwUpos );
- todo_wine
- check_member( infoex, expect_infoex[2], "%#x", dwVpos );
- todo_wine
- check_member( infoex, expect_infoex[2], "%#x", dwButtons );
- todo_wine
- check_member( infoex, expect_infoex[2], "%#x", dwButtonNumber );
- todo_wine
- check_member( infoex, expect_infoex[2], "%#x", dwPOV );
- ret = IDirectInputDevice8_Release( device );
- ok( ret == 0, "Release returned %d\n", ret );
- CloseHandle( event );
- CloseHandle( file );
done: pnp_driver_stop(); cleanup_registry_keys(); -- 2.34.0
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput8/tests/hid.c | 39 --------------------------------------- dlls/winmm/joystick.c | 4 ++++ 2 files changed, 4 insertions(+), 39 deletions(-)
diff --git a/dlls/dinput8/tests/hid.c b/dlls/dinput8/tests/hid.c index 677d436b894..13b6e7bbec4 100644 --- a/dlls/dinput8/tests/hid.c +++ b/dlls/dinput8/tests/hid.c @@ -9745,61 +9745,33 @@ static void test_winmm_joystick(void)
memset( &caps, 0xcd, sizeof(caps) ); ret = joyGetDevCapsW( -1, (JOYCAPSW *)&caps, sizeof(caps) ); - todo_wine ok( ret == 0, "joyGetDevCapsW returned %u\n", ret ); - todo_wine check_member( caps, expect_regcaps, "%#x", wMid ); - todo_wine check_member( caps, expect_regcaps, "%#x", wPid ); - todo_wine check_member_wstr( caps, expect_regcaps, szPname ); - todo_wine check_member( caps, expect_regcaps, "%#x", wXmin ); - todo_wine check_member( caps, expect_regcaps, "%#x", wXmax ); - todo_wine check_member( caps, expect_regcaps, "%#x", wYmin ); - todo_wine check_member( caps, expect_regcaps, "%#x", wYmax ); - todo_wine check_member( caps, expect_regcaps, "%#x", wZmin ); - todo_wine check_member( caps, expect_regcaps, "%#x", wZmax ); - todo_wine check_member( caps, expect_regcaps, "%#x", wNumButtons ); - todo_wine check_member( caps, expect_regcaps, "%#x", wPeriodMin ); - todo_wine check_member( caps, expect_regcaps, "%#x", wPeriodMax ); - todo_wine check_member( caps, expect_regcaps, "%#x", wRmin ); - todo_wine check_member( caps, expect_regcaps, "%#x", wRmax ); - todo_wine check_member( caps, expect_regcaps, "%#x", wUmin ); - todo_wine check_member( caps, expect_regcaps, "%#x", wUmax ); - todo_wine check_member( caps, expect_regcaps, "%#x", wVmin ); - todo_wine check_member( caps, expect_regcaps, "%#x", wVmax ); - todo_wine check_member( caps, expect_regcaps, "%#x", wCaps ); - todo_wine check_member( caps, expect_regcaps, "%#x", wMaxAxes ); - todo_wine check_member( caps, expect_regcaps, "%#x", wNumAxes ); - todo_wine check_member( caps, expect_regcaps, "%#x", wMaxButtons ); - todo_wine check_member_wstr( caps, expect_regcaps, szRegKey ); - todo_wine check_member_wstr( caps, expect_regcaps, szOEMVxD ); - todo_wine check_member_guid( caps, expect_regcaps, ManufacturerGuid ); - todo_wine check_member_guid( caps, expect_regcaps, ProductGuid ); - todo_wine check_member_guid( caps, expect_regcaps, NameGuid );
if (!dinput_driver_start( report_desc, sizeof(report_desc), &hid_caps, NULL, 0 )) goto done; @@ -9829,15 +9801,12 @@ static void test_winmm_joystick(void) check_member( caps, expect_caps, "%#x", wPid ); todo_wine check_member_wstr( caps, expect_caps, szPname ); - todo_wine check_member( caps, expect_caps, "%#x", wXmin ); todo_wine check_member( caps, expect_caps, "%#x", wXmax ); - todo_wine check_member( caps, expect_caps, "%#x", wYmin ); todo_wine check_member( caps, expect_caps, "%#x", wYmax ); - todo_wine check_member( caps, expect_caps, "%#x", wZmin ); todo_wine check_member( caps, expect_caps, "%#x", wZmax ); @@ -9845,15 +9814,12 @@ static void test_winmm_joystick(void) check_member( caps, expect_caps, "%#x", wNumButtons ); check_member( caps, expect_caps, "%#x", wPeriodMin ); check_member( caps, expect_caps, "%#x", wPeriodMax ); - todo_wine check_member( caps, expect_caps, "%#x", wRmin ); todo_wine check_member( caps, expect_caps, "%#x", wRmax ); - todo_wine check_member( caps, expect_caps, "%#x", wUmin ); todo_wine check_member( caps, expect_caps, "%#x", wUmax ); - todo_wine check_member( caps, expect_caps, "%#x", wVmin ); todo_wine check_member( caps, expect_caps, "%#x", wVmax ); @@ -9865,15 +9831,10 @@ static void test_winmm_joystick(void) check_member( caps, expect_caps, "%#x", wNumAxes ); todo_wine check_member( caps, expect_caps, "%#x", wMaxButtons ); - todo_wine check_member_wstr( caps, expect_caps, szRegKey ); - todo_wine check_member_wstr( caps, expect_caps, szOEMVxD ); - todo_wine check_member_guid( caps, expect_caps, ManufacturerGuid ); - todo_wine check_member_guid( caps, expect_caps, ProductGuid ); - todo_wine check_member_guid( caps, expect_caps, NameGuid );
ret = joyGetDevCapsW( 0, (JOYCAPSW *)&caps, sizeof(JOYCAPSW) ); diff --git a/dlls/winmm/joystick.c b/dlls/winmm/joystick.c index bb8142a29a9..234dd4db594 100644 --- a/dlls/winmm/joystick.c +++ b/dlls/winmm/joystick.c @@ -174,6 +174,10 @@ MMRESULT WINAPI DECLSPEC_HOTPATCH joyGetDevCapsW( UINT_PTR id, JOYCAPSW *caps, U if (!caps) return MMSYSERR_INVALPARAM; if (size != sizeof(JOYCAPSW) && size != sizeof(JOYCAPS2W)) return JOYERR_PARMS;
+ memset( caps, 0, size ); + wcscpy( caps->szRegKey, L"DINPUT.DLL" ); + if (id == ~(UINT_PTR)0) return JOYERR_NOERROR; + if (id >= MAXJOYSTICK) return JOYERR_PARMS; if (!JOY_LoadDriver( id )) return MMSYSERR_NODRIVER;
Signed-off-by: Andrew Eikum aeikum@codeweavers.com
On Fri, Dec 03, 2021 at 12:19:04PM +0100, Rémi Bernon wrote:
Signed-off-by: Rémi Bernon rbernon@codeweavers.com
dlls/dinput8/tests/hid.c | 39 --------------------------------------- dlls/winmm/joystick.c | 4 ++++ 2 files changed, 4 insertions(+), 39 deletions(-)
diff --git a/dlls/dinput8/tests/hid.c b/dlls/dinput8/tests/hid.c index 677d436b894..13b6e7bbec4 100644 --- a/dlls/dinput8/tests/hid.c +++ b/dlls/dinput8/tests/hid.c @@ -9745,61 +9745,33 @@ static void test_winmm_joystick(void)
memset( &caps, 0xcd, sizeof(caps) ); ret = joyGetDevCapsW( -1, (JOYCAPSW *)&caps, sizeof(caps) );
todo_wine ok( ret == 0, "joyGetDevCapsW returned %u\n", ret );
todo_wine check_member( caps, expect_regcaps, "%#x", wMid );
todo_wine check_member( caps, expect_regcaps, "%#x", wPid );
todo_wine check_member_wstr( caps, expect_regcaps, szPname );
todo_wine check_member( caps, expect_regcaps, "%#x", wXmin );
todo_wine check_member( caps, expect_regcaps, "%#x", wXmax );
todo_wine check_member( caps, expect_regcaps, "%#x", wYmin );
todo_wine check_member( caps, expect_regcaps, "%#x", wYmax );
todo_wine check_member( caps, expect_regcaps, "%#x", wZmin );
todo_wine check_member( caps, expect_regcaps, "%#x", wZmax );
todo_wine check_member( caps, expect_regcaps, "%#x", wNumButtons );
todo_wine check_member( caps, expect_regcaps, "%#x", wPeriodMin );
todo_wine check_member( caps, expect_regcaps, "%#x", wPeriodMax );
todo_wine check_member( caps, expect_regcaps, "%#x", wRmin );
todo_wine check_member( caps, expect_regcaps, "%#x", wRmax );
todo_wine check_member( caps, expect_regcaps, "%#x", wUmin );
todo_wine check_member( caps, expect_regcaps, "%#x", wUmax );
todo_wine check_member( caps, expect_regcaps, "%#x", wVmin );
todo_wine check_member( caps, expect_regcaps, "%#x", wVmax );
todo_wine check_member( caps, expect_regcaps, "%#x", wCaps );
todo_wine check_member( caps, expect_regcaps, "%#x", wMaxAxes );
todo_wine check_member( caps, expect_regcaps, "%#x", wNumAxes );
todo_wine check_member( caps, expect_regcaps, "%#x", wMaxButtons );
todo_wine check_member_wstr( caps, expect_regcaps, szRegKey );
todo_wine check_member_wstr( caps, expect_regcaps, szOEMVxD );
todo_wine check_member_guid( caps, expect_regcaps, ManufacturerGuid );
todo_wine check_member_guid( caps, expect_regcaps, ProductGuid );
todo_wine check_member_guid( caps, expect_regcaps, NameGuid );
if (!dinput_driver_start( report_desc, sizeof(report_desc), &hid_caps, NULL, 0 )) goto done;
@@ -9829,15 +9801,12 @@ static void test_winmm_joystick(void) check_member( caps, expect_caps, "%#x", wPid ); todo_wine check_member_wstr( caps, expect_caps, szPname );
- todo_wine check_member( caps, expect_caps, "%#x", wXmin ); todo_wine check_member( caps, expect_caps, "%#x", wXmax );
- todo_wine check_member( caps, expect_caps, "%#x", wYmin ); todo_wine check_member( caps, expect_caps, "%#x", wYmax );
- todo_wine check_member( caps, expect_caps, "%#x", wZmin ); todo_wine check_member( caps, expect_caps, "%#x", wZmax );
@@ -9845,15 +9814,12 @@ static void test_winmm_joystick(void) check_member( caps, expect_caps, "%#x", wNumButtons ); check_member( caps, expect_caps, "%#x", wPeriodMin ); check_member( caps, expect_caps, "%#x", wPeriodMax );
- todo_wine check_member( caps, expect_caps, "%#x", wRmin ); todo_wine check_member( caps, expect_caps, "%#x", wRmax );
- todo_wine check_member( caps, expect_caps, "%#x", wUmin ); todo_wine check_member( caps, expect_caps, "%#x", wUmax );
- todo_wine check_member( caps, expect_caps, "%#x", wVmin ); todo_wine check_member( caps, expect_caps, "%#x", wVmax );
@@ -9865,15 +9831,10 @@ static void test_winmm_joystick(void) check_member( caps, expect_caps, "%#x", wNumAxes ); todo_wine check_member( caps, expect_caps, "%#x", wMaxButtons );
todo_wine check_member_wstr( caps, expect_caps, szRegKey );
todo_wine check_member_wstr( caps, expect_caps, szOEMVxD );
todo_wine check_member_guid( caps, expect_caps, ManufacturerGuid );
todo_wine check_member_guid( caps, expect_caps, ProductGuid );
todo_wine check_member_guid( caps, expect_caps, NameGuid );
ret = joyGetDevCapsW( 0, (JOYCAPSW *)&caps, sizeof(JOYCAPSW) );
diff --git a/dlls/winmm/joystick.c b/dlls/winmm/joystick.c index bb8142a29a9..234dd4db594 100644 --- a/dlls/winmm/joystick.c +++ b/dlls/winmm/joystick.c @@ -174,6 +174,10 @@ MMRESULT WINAPI DECLSPEC_HOTPATCH joyGetDevCapsW( UINT_PTR id, JOYCAPSW *caps, U if (!caps) return MMSYSERR_INVALPARAM; if (size != sizeof(JOYCAPSW) && size != sizeof(JOYCAPS2W)) return JOYERR_PARMS;
- memset( caps, 0, size );
- wcscpy( caps->szRegKey, L"DINPUT.DLL" );
- if (id == ~(UINT_PTR)0) return JOYERR_NOERROR;
- if (id >= MAXJOYSTICK) return JOYERR_PARMS; if (!JOY_LoadDriver( id )) return MMSYSERR_NODRIVER;
-- 2.34.0
And rename the array from JOY_Sticks to joysticks.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput8/tests/hid.c | 2 - dlls/winmm/joystick.c | 79 ++++++++++++++++------------------------ 2 files changed, 32 insertions(+), 49 deletions(-)
diff --git a/dlls/dinput8/tests/hid.c b/dlls/dinput8/tests/hid.c index 13b6e7bbec4..f82fa9a7cb0 100644 --- a/dlls/dinput8/tests/hid.c +++ b/dlls/dinput8/tests/hid.c @@ -9733,7 +9733,6 @@ static void test_winmm_joystick(void) cleanup_registry_keys();
ret = joyGetNumDevs(); - todo_wine ok( ret == 16, "joyGetNumDevs returned %u\n", ret );
ret = joyGetDevCapsW( 0, (JOYCAPSW *)&caps, sizeof(JOYCAPSW) ); @@ -9777,7 +9776,6 @@ static void test_winmm_joystick(void) if (!dinput_driver_start( report_desc, sizeof(report_desc), &hid_caps, NULL, 0 )) goto done;
ret = joyGetNumDevs(); - todo_wine ok( ret == 16, "joyGetNumDevs returned %u\n", ret );
ret = joyGetPosEx( 1, &infoex ); diff --git a/dlls/winmm/joystick.c b/dlls/winmm/joystick.c index 234dd4db594..604b0d7c0ba 100644 --- a/dlls/winmm/joystick.c +++ b/dlls/winmm/joystick.c @@ -40,7 +40,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(winmm);
-#define MAXJOYSTICK (JOYSTICKID2 + 30) #define JOY_PERIOD_MIN (10) /* min Capture time period */ #define JOY_PERIOD_MAX (1000) /* max Capture time period */
@@ -53,7 +52,7 @@ typedef struct tagWINE_JOYSTICK { HDRVR hDriver; } WINE_JOYSTICK;
-static WINE_JOYSTICK JOY_Sticks[MAXJOYSTICK]; +static WINE_JOYSTICK joysticks[16];
static BOOL compare_uint(unsigned int x, unsigned int y, unsigned int max_diff) { @@ -68,14 +67,12 @@ static BOOL JOY_LoadDriver(DWORD dwJoyID) { static BOOL winejoystick_missing = FALSE;
- if (dwJoyID >= MAXJOYSTICK || winejoystick_missing) - return FALSE; - if (JOY_Sticks[dwJoyID].hDriver) - return TRUE; + if (dwJoyID >= ARRAY_SIZE(joysticks) || winejoystick_missing) return FALSE; + if (joysticks[dwJoyID].hDriver) return TRUE;
- JOY_Sticks[dwJoyID].hDriver = OpenDriverA("winejoystick.drv", 0, dwJoyID); + joysticks[dwJoyID].hDriver = OpenDriverA( "winejoystick.drv", 0, dwJoyID );
- if (!JOY_Sticks[dwJoyID].hDriver) + if (!joysticks[dwJoyID].hDriver) { WARN("OpenDriverA("winejoystick.drv") failed\n");
@@ -83,7 +80,7 @@ static BOOL JOY_LoadDriver(DWORD dwJoyID) winejoystick_missing = TRUE; }
- return (JOY_Sticks[dwJoyID].hDriver != 0); + return (joysticks[dwJoyID].hDriver != 0); }
/************************************************************************** @@ -98,10 +95,11 @@ static void CALLBACK JOY_Timer(HWND hWnd, UINT wMsg, UINT_PTR wTimer, DWORD dwTi LONG pos; unsigned buttonChange;
- for (i = 0; i < MAXJOYSTICK; i++) { - joy = &JOY_Sticks[i]; + for (i = 0; i < ARRAY_SIZE(joysticks); i++) + { + joy = &joysticks[i];
- if (joy->hCapture != hWnd) continue; + if (joy->hCapture != hWnd) continue;
res = joyGetPos(i, &ji); if (res != JOYERR_NOERROR) { @@ -153,15 +151,7 @@ MMRESULT WINAPI joyConfigChanged(DWORD flags) */ UINT WINAPI DECLSPEC_HOTPATCH joyGetNumDevs(void) { - UINT ret = 0; - int i; - - for (i = 0; i < MAXJOYSTICK; i++) { - if (JOY_LoadDriver(i)) { - ret += SendDriverMessage(JOY_Sticks[i].hDriver, JDD_GETNUMDEVS, 0, 0); - } - } - return ret; + return ARRAY_SIZE(joysticks); }
/************************************************************************** @@ -178,13 +168,13 @@ MMRESULT WINAPI DECLSPEC_HOTPATCH joyGetDevCapsW( UINT_PTR id, JOYCAPSW *caps, U wcscpy( caps->szRegKey, L"DINPUT.DLL" ); if (id == ~(UINT_PTR)0) return JOYERR_NOERROR;
- if (id >= MAXJOYSTICK) return JOYERR_PARMS; + if (id >= ARRAY_SIZE(joysticks)) return JOYERR_PARMS; if (!JOY_LoadDriver( id )) return MMSYSERR_NODRIVER;
caps->wPeriodMin = JOY_PERIOD_MIN; /* FIXME */ caps->wPeriodMax = JOY_PERIOD_MAX; /* FIXME (same as MS Joystick Driver) */
- return SendDriverMessage( JOY_Sticks[id].hDriver, JDD_GETDEVCAPS, (LPARAM)caps, size ); + return SendDriverMessage( joysticks[id].hDriver, JDD_GETDEVCAPS, (LPARAM)caps, size ); }
/************************************************************************** @@ -252,7 +242,7 @@ MMRESULT WINAPI DECLSPEC_HOTPATCH joyGetPosEx(UINT wID, LPJOYINFOEX lpInfo) TRACE("(%d, %p);\n", wID, lpInfo);
if (!lpInfo) return MMSYSERR_INVALPARAM; - if (wID >= MAXJOYSTICK || lpInfo->dwSize < sizeof(JOYINFOEX)) return JOYERR_PARMS; + if (wID >= ARRAY_SIZE(joysticks) || lpInfo->dwSize < sizeof(JOYINFOEX)) return JOYERR_PARMS; if (!JOY_LoadDriver(wID)) return MMSYSERR_NODRIVER;
lpInfo->dwXpos = 0; @@ -267,7 +257,7 @@ MMRESULT WINAPI DECLSPEC_HOTPATCH joyGetPosEx(UINT wID, LPJOYINFOEX lpInfo) lpInfo->dwReserved1 = 0; lpInfo->dwReserved2 = 0;
- return SendDriverMessage(JOY_Sticks[wID].hDriver, JDD_GETPOSEX, (LPARAM)lpInfo, 0); + return SendDriverMessage( joysticks[wID].hDriver, JDD_GETPOSEX, (LPARAM)lpInfo, 0 ); }
/************************************************************************** @@ -278,7 +268,7 @@ MMRESULT WINAPI joyGetPos(UINT wID, LPJOYINFO lpInfo) TRACE("(%d, %p);\n", wID, lpInfo);
if (!lpInfo) return MMSYSERR_INVALPARAM; - if (wID >= MAXJOYSTICK) return JOYERR_PARMS; + if (wID >= ARRAY_SIZE(joysticks)) return JOYERR_PARMS; if (!JOY_LoadDriver(wID)) return MMSYSERR_NODRIVER;
lpInfo->wXpos = 0; @@ -286,7 +276,7 @@ MMRESULT WINAPI joyGetPos(UINT wID, LPJOYINFO lpInfo) lpInfo->wZpos = 0; lpInfo->wButtons = 0;
- return SendDriverMessage(JOY_Sticks[wID].hDriver, JDD_GETPOS, (LPARAM)lpInfo, 0); + return SendDriverMessage( joysticks[wID].hDriver, JDD_GETPOS, (LPARAM)lpInfo, 0 ); }
/************************************************************************** @@ -296,9 +286,9 @@ MMRESULT WINAPI joyGetThreshold(UINT wID, LPUINT lpThreshold) { TRACE("(%04X, %p);\n", wID, lpThreshold);
- if (wID >= MAXJOYSTICK) return JOYERR_PARMS; + if (wID >= ARRAY_SIZE(joysticks)) return JOYERR_PARMS;
- *lpThreshold = JOY_Sticks[wID].threshold; + *lpThreshold = joysticks[wID].threshold; return JOYERR_NOERROR; }
@@ -309,13 +299,13 @@ MMRESULT WINAPI joyReleaseCapture(UINT wID) { TRACE("(%04X);\n", wID);
- if (wID >= MAXJOYSTICK) return JOYERR_PARMS; + if (wID >= ARRAY_SIZE(joysticks)) return JOYERR_PARMS; if (!JOY_LoadDriver(wID)) return MMSYSERR_NODRIVER; - if (JOY_Sticks[wID].hCapture) + if (joysticks[wID].hCapture) { - KillTimer(JOY_Sticks[wID].hCapture, JOY_Sticks[wID].wTimer); - JOY_Sticks[wID].hCapture = 0; - JOY_Sticks[wID].wTimer = 0; + KillTimer( joysticks[wID].hCapture, joysticks[wID].wTimer ); + joysticks[wID].hCapture = 0; + joysticks[wID].wTimer = 0; } else TRACE("Joystick is not captured, ignoring request.\n"); @@ -330,22 +320,17 @@ MMRESULT WINAPI joySetCapture(HWND hWnd, UINT wID, UINT wPeriod, BOOL bChanged) { TRACE("(%p, %04X, %d, %d);\n", hWnd, wID, wPeriod, bChanged);
- if (wID >= MAXJOYSTICK || hWnd == 0) return JOYERR_PARMS; + if (wID >= ARRAY_SIZE(joysticks) || hWnd == 0) return JOYERR_PARMS; if (wPeriod<JOY_PERIOD_MIN) wPeriod = JOY_PERIOD_MIN; else if(wPeriod>JOY_PERIOD_MAX) wPeriod = JOY_PERIOD_MAX; if (!JOY_LoadDriver(wID)) return MMSYSERR_NODRIVER;
- if (JOY_Sticks[wID].hCapture || !IsWindow(hWnd)) - return JOYERR_NOCANDO; /* FIXME: what should be returned ? */ + if (joysticks[wID].hCapture || !IsWindow( hWnd )) return JOYERR_NOCANDO; /* FIXME: what should be returned ? */ + if (joyGetPos( wID, &joysticks[wID].ji ) != JOYERR_NOERROR) return JOYERR_UNPLUGGED; + if ((joysticks[wID].wTimer = SetTimer( hWnd, 0, wPeriod, JOY_Timer )) == 0) return JOYERR_NOCANDO;
- if (joyGetPos(wID, &JOY_Sticks[wID].ji) != JOYERR_NOERROR) - return JOYERR_UNPLUGGED; - - if ((JOY_Sticks[wID].wTimer = SetTimer(hWnd, 0, wPeriod, JOY_Timer)) == 0) - return JOYERR_NOCANDO; - - JOY_Sticks[wID].hCapture = hWnd; - JOY_Sticks[wID].bChanged = bChanged; + joysticks[wID].hCapture = hWnd; + joysticks[wID].bChanged = bChanged;
return JOYERR_NOERROR; } @@ -357,9 +342,9 @@ MMRESULT WINAPI joySetThreshold(UINT wID, UINT wThreshold) { TRACE("(%04X, %d);\n", wID, wThreshold);
- if (wID >= MAXJOYSTICK || wThreshold > 65535) return MMSYSERR_INVALPARAM; + if (wID >= ARRAY_SIZE(joysticks) || wThreshold > 65535) return MMSYSERR_INVALPARAM;
- JOY_Sticks[wID].threshold = wThreshold; + joysticks[wID].threshold = wThreshold;
return JOYERR_NOERROR; }
Signed-off-by: Andrew Eikum aeikum@codeweavers.com
On Fri, Dec 03, 2021 at 12:19:05PM +0100, Rémi Bernon wrote:
And rename the array from JOY_Sticks to joysticks.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com
dlls/dinput8/tests/hid.c | 2 - dlls/winmm/joystick.c | 79 ++++++++++++++++------------------------ 2 files changed, 32 insertions(+), 49 deletions(-)
diff --git a/dlls/dinput8/tests/hid.c b/dlls/dinput8/tests/hid.c index 13b6e7bbec4..f82fa9a7cb0 100644 --- a/dlls/dinput8/tests/hid.c +++ b/dlls/dinput8/tests/hid.c @@ -9733,7 +9733,6 @@ static void test_winmm_joystick(void) cleanup_registry_keys();
ret = joyGetNumDevs();
todo_wine ok( ret == 16, "joyGetNumDevs returned %u\n", ret );
ret = joyGetDevCapsW( 0, (JOYCAPSW *)&caps, sizeof(JOYCAPSW) );
@@ -9777,7 +9776,6 @@ static void test_winmm_joystick(void) if (!dinput_driver_start( report_desc, sizeof(report_desc), &hid_caps, NULL, 0 )) goto done;
ret = joyGetNumDevs();
todo_wine ok( ret == 16, "joyGetNumDevs returned %u\n", ret );
ret = joyGetPosEx( 1, &infoex );
diff --git a/dlls/winmm/joystick.c b/dlls/winmm/joystick.c index 234dd4db594..604b0d7c0ba 100644 --- a/dlls/winmm/joystick.c +++ b/dlls/winmm/joystick.c @@ -40,7 +40,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(winmm);
-#define MAXJOYSTICK (JOYSTICKID2 + 30) #define JOY_PERIOD_MIN (10) /* min Capture time period */ #define JOY_PERIOD_MAX (1000) /* max Capture time period */
@@ -53,7 +52,7 @@ typedef struct tagWINE_JOYSTICK { HDRVR hDriver; } WINE_JOYSTICK;
-static WINE_JOYSTICK JOY_Sticks[MAXJOYSTICK]; +static WINE_JOYSTICK joysticks[16];
static BOOL compare_uint(unsigned int x, unsigned int y, unsigned int max_diff) { @@ -68,14 +67,12 @@ static BOOL JOY_LoadDriver(DWORD dwJoyID) { static BOOL winejoystick_missing = FALSE;
- if (dwJoyID >= MAXJOYSTICK || winejoystick_missing)
- return FALSE;
- if (JOY_Sticks[dwJoyID].hDriver)
- return TRUE;
- if (dwJoyID >= ARRAY_SIZE(joysticks) || winejoystick_missing) return FALSE;
- if (joysticks[dwJoyID].hDriver) return TRUE;
- JOY_Sticks[dwJoyID].hDriver = OpenDriverA("winejoystick.drv", 0, dwJoyID);
- joysticks[dwJoyID].hDriver = OpenDriverA( "winejoystick.drv", 0, dwJoyID );
- if (!JOY_Sticks[dwJoyID].hDriver)
- if (!joysticks[dwJoyID].hDriver) { WARN("OpenDriverA("winejoystick.drv") failed\n");
@@ -83,7 +80,7 @@ static BOOL JOY_LoadDriver(DWORD dwJoyID) winejoystick_missing = TRUE; }
- return (JOY_Sticks[dwJoyID].hDriver != 0);
- return (joysticks[dwJoyID].hDriver != 0);
}
/************************************************************************** @@ -98,10 +95,11 @@ static void CALLBACK JOY_Timer(HWND hWnd, UINT wMsg, UINT_PTR wTimer, DWORD dwTi LONG pos; unsigned buttonChange;
- for (i = 0; i < MAXJOYSTICK; i++) {
- joy = &JOY_Sticks[i];
- for (i = 0; i < ARRAY_SIZE(joysticks); i++)
- {
joy = &joysticks[i];
- if (joy->hCapture != hWnd) continue;
if (joy->hCapture != hWnd) continue;
res = joyGetPos(i, &ji); if (res != JOYERR_NOERROR) {
@@ -153,15 +151,7 @@ MMRESULT WINAPI joyConfigChanged(DWORD flags) */ UINT WINAPI DECLSPEC_HOTPATCH joyGetNumDevs(void) {
- UINT ret = 0;
- int i;
- for (i = 0; i < MAXJOYSTICK; i++) {
- if (JOY_LoadDriver(i)) {
ret += SendDriverMessage(JOY_Sticks[i].hDriver, JDD_GETNUMDEVS, 0, 0);
- }
- }
- return ret;
- return ARRAY_SIZE(joysticks);
}
/************************************************************************** @@ -178,13 +168,13 @@ MMRESULT WINAPI DECLSPEC_HOTPATCH joyGetDevCapsW( UINT_PTR id, JOYCAPSW *caps, U wcscpy( caps->szRegKey, L"DINPUT.DLL" ); if (id == ~(UINT_PTR)0) return JOYERR_NOERROR;
- if (id >= MAXJOYSTICK) return JOYERR_PARMS;
if (id >= ARRAY_SIZE(joysticks)) return JOYERR_PARMS; if (!JOY_LoadDriver( id )) return MMSYSERR_NODRIVER;
caps->wPeriodMin = JOY_PERIOD_MIN; /* FIXME */ caps->wPeriodMax = JOY_PERIOD_MAX; /* FIXME (same as MS Joystick Driver) */
- return SendDriverMessage( JOY_Sticks[id].hDriver, JDD_GETDEVCAPS, (LPARAM)caps, size );
- return SendDriverMessage( joysticks[id].hDriver, JDD_GETDEVCAPS, (LPARAM)caps, size );
}
/************************************************************************** @@ -252,7 +242,7 @@ MMRESULT WINAPI DECLSPEC_HOTPATCH joyGetPosEx(UINT wID, LPJOYINFOEX lpInfo) TRACE("(%d, %p);\n", wID, lpInfo);
if (!lpInfo) return MMSYSERR_INVALPARAM;
- if (wID >= MAXJOYSTICK || lpInfo->dwSize < sizeof(JOYINFOEX)) return JOYERR_PARMS;
if (wID >= ARRAY_SIZE(joysticks) || lpInfo->dwSize < sizeof(JOYINFOEX)) return JOYERR_PARMS; if (!JOY_LoadDriver(wID)) return MMSYSERR_NODRIVER;
lpInfo->dwXpos = 0;
@@ -267,7 +257,7 @@ MMRESULT WINAPI DECLSPEC_HOTPATCH joyGetPosEx(UINT wID, LPJOYINFOEX lpInfo) lpInfo->dwReserved1 = 0; lpInfo->dwReserved2 = 0;
- return SendDriverMessage(JOY_Sticks[wID].hDriver, JDD_GETPOSEX, (LPARAM)lpInfo, 0);
- return SendDriverMessage( joysticks[wID].hDriver, JDD_GETPOSEX, (LPARAM)lpInfo, 0 );
}
/************************************************************************** @@ -278,7 +268,7 @@ MMRESULT WINAPI joyGetPos(UINT wID, LPJOYINFO lpInfo) TRACE("(%d, %p);\n", wID, lpInfo);
if (!lpInfo) return MMSYSERR_INVALPARAM;
- if (wID >= MAXJOYSTICK) return JOYERR_PARMS;
if (wID >= ARRAY_SIZE(joysticks)) return JOYERR_PARMS; if (!JOY_LoadDriver(wID)) return MMSYSERR_NODRIVER;
lpInfo->wXpos = 0;
@@ -286,7 +276,7 @@ MMRESULT WINAPI joyGetPos(UINT wID, LPJOYINFO lpInfo) lpInfo->wZpos = 0; lpInfo->wButtons = 0;
- return SendDriverMessage(JOY_Sticks[wID].hDriver, JDD_GETPOS, (LPARAM)lpInfo, 0);
- return SendDriverMessage( joysticks[wID].hDriver, JDD_GETPOS, (LPARAM)lpInfo, 0 );
}
/************************************************************************** @@ -296,9 +286,9 @@ MMRESULT WINAPI joyGetThreshold(UINT wID, LPUINT lpThreshold) { TRACE("(%04X, %p);\n", wID, lpThreshold);
- if (wID >= MAXJOYSTICK) return JOYERR_PARMS;
- if (wID >= ARRAY_SIZE(joysticks)) return JOYERR_PARMS;
- *lpThreshold = JOY_Sticks[wID].threshold;
- *lpThreshold = joysticks[wID].threshold; return JOYERR_NOERROR;
}
@@ -309,13 +299,13 @@ MMRESULT WINAPI joyReleaseCapture(UINT wID) { TRACE("(%04X);\n", wID);
- if (wID >= MAXJOYSTICK) return JOYERR_PARMS;
- if (wID >= ARRAY_SIZE(joysticks)) return JOYERR_PARMS; if (!JOY_LoadDriver(wID)) return MMSYSERR_NODRIVER;
- if (JOY_Sticks[wID].hCapture)
- if (joysticks[wID].hCapture) {
KillTimer(JOY_Sticks[wID].hCapture, JOY_Sticks[wID].wTimer);
JOY_Sticks[wID].hCapture = 0;
JOY_Sticks[wID].wTimer = 0;
KillTimer( joysticks[wID].hCapture, joysticks[wID].wTimer );
joysticks[wID].hCapture = 0;
} else TRACE("Joystick is not captured, ignoring request.\n");joysticks[wID].wTimer = 0;
@@ -330,22 +320,17 @@ MMRESULT WINAPI joySetCapture(HWND hWnd, UINT wID, UINT wPeriod, BOOL bChanged) { TRACE("(%p, %04X, %d, %d);\n", hWnd, wID, wPeriod, bChanged);
- if (wID >= MAXJOYSTICK || hWnd == 0) return JOYERR_PARMS;
- if (wID >= ARRAY_SIZE(joysticks) || hWnd == 0) return JOYERR_PARMS; if (wPeriod<JOY_PERIOD_MIN) wPeriod = JOY_PERIOD_MIN; else if(wPeriod>JOY_PERIOD_MAX) wPeriod = JOY_PERIOD_MAX; if (!JOY_LoadDriver(wID)) return MMSYSERR_NODRIVER;
- if (JOY_Sticks[wID].hCapture || !IsWindow(hWnd))
- return JOYERR_NOCANDO; /* FIXME: what should be returned ? */
- if (joysticks[wID].hCapture || !IsWindow( hWnd )) return JOYERR_NOCANDO; /* FIXME: what should be returned ? */
- if (joyGetPos( wID, &joysticks[wID].ji ) != JOYERR_NOERROR) return JOYERR_UNPLUGGED;
- if ((joysticks[wID].wTimer = SetTimer( hWnd, 0, wPeriod, JOY_Timer )) == 0) return JOYERR_NOCANDO;
- if (joyGetPos(wID, &JOY_Sticks[wID].ji) != JOYERR_NOERROR)
- return JOYERR_UNPLUGGED;
- if ((JOY_Sticks[wID].wTimer = SetTimer(hWnd, 0, wPeriod, JOY_Timer)) == 0)
- return JOYERR_NOCANDO;
- JOY_Sticks[wID].hCapture = hWnd;
- JOY_Sticks[wID].bChanged = bChanged;
joysticks[wID].hCapture = hWnd;
joysticks[wID].bChanged = bChanged;
return JOYERR_NOERROR;
} @@ -357,9 +342,9 @@ MMRESULT WINAPI joySetThreshold(UINT wID, UINT wThreshold) { TRACE("(%04X, %d);\n", wID, wThreshold);
- if (wID >= MAXJOYSTICK || wThreshold > 65535) return MMSYSERR_INVALPARAM;
- if (wID >= ARRAY_SIZE(joysticks) || wThreshold > 65535) return MMSYSERR_INVALPARAM;
- JOY_Sticks[wID].threshold = wThreshold;
joysticks[wID].threshold = wThreshold;
return JOYERR_NOERROR;
}
2.34.0
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winmm/joystick.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-)
diff --git a/dlls/winmm/joystick.c b/dlls/winmm/joystick.c index 604b0d7c0ba..666b0e6c871 100644 --- a/dlls/winmm/joystick.c +++ b/dlls/winmm/joystick.c @@ -263,20 +263,26 @@ MMRESULT WINAPI DECLSPEC_HOTPATCH joyGetPosEx(UINT wID, LPJOYINFOEX lpInfo) /************************************************************************** * joyGetPos [WINMM.@] */ -MMRESULT WINAPI joyGetPos(UINT wID, LPJOYINFO lpInfo) +MMRESULT WINAPI joyGetPos( UINT id, JOYINFO *info ) { - TRACE("(%d, %p);\n", wID, lpInfo); + JOYINFOEX infoex = + { + .dwSize = sizeof(JOYINFOEX), + .dwFlags = JOY_RETURNX | JOY_RETURNY | JOY_RETURNZ | JOY_RETURNBUTTONS, + }; + MMRESULT res;
- if (!lpInfo) return MMSYSERR_INVALPARAM; - if (wID >= ARRAY_SIZE(joysticks)) return JOYERR_PARMS; - if (!JOY_LoadDriver(wID)) return MMSYSERR_NODRIVER; + TRACE( "id %u, info %p.\n", id, info );
- lpInfo->wXpos = 0; - lpInfo->wYpos = 0; - lpInfo->wZpos = 0; - lpInfo->wButtons = 0; + if (!info) return MMSYSERR_INVALPARAM; + if ((res = joyGetPosEx( id, &infoex ))) return res;
- return SendDriverMessage( joysticks[wID].hDriver, JDD_GETPOS, (LPARAM)lpInfo, 0 ); + info->wXpos = infoex.dwXpos; + info->wYpos = infoex.dwYpos; + info->wZpos = infoex.dwZpos; + info->wButtons = infoex.dwButtons; + + return JOYERR_NOERROR; }
/**************************************************************************
Signed-off-by: Andrew Eikum aeikum@codeweavers.com
On Fri, Dec 03, 2021 at 12:19:06PM +0100, Rémi Bernon wrote:
Signed-off-by: Rémi Bernon rbernon@codeweavers.com
dlls/winmm/joystick.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-)
diff --git a/dlls/winmm/joystick.c b/dlls/winmm/joystick.c index 604b0d7c0ba..666b0e6c871 100644 --- a/dlls/winmm/joystick.c +++ b/dlls/winmm/joystick.c @@ -263,20 +263,26 @@ MMRESULT WINAPI DECLSPEC_HOTPATCH joyGetPosEx(UINT wID, LPJOYINFOEX lpInfo) /**************************************************************************
joyGetPos [WINMM.@]
*/ -MMRESULT WINAPI joyGetPos(UINT wID, LPJOYINFO lpInfo) +MMRESULT WINAPI joyGetPos( UINT id, JOYINFO *info ) {
- TRACE("(%d, %p);\n", wID, lpInfo);
- JOYINFOEX infoex =
- {
.dwSize = sizeof(JOYINFOEX),
.dwFlags = JOY_RETURNX | JOY_RETURNY | JOY_RETURNZ | JOY_RETURNBUTTONS,
- };
- MMRESULT res;
- if (!lpInfo) return MMSYSERR_INVALPARAM;
- if (wID >= ARRAY_SIZE(joysticks)) return JOYERR_PARMS;
- if (!JOY_LoadDriver(wID)) return MMSYSERR_NODRIVER;
- TRACE( "id %u, info %p.\n", id, info );
- lpInfo->wXpos = 0;
- lpInfo->wYpos = 0;
- lpInfo->wZpos = 0;
- lpInfo->wButtons = 0;
- if (!info) return MMSYSERR_INVALPARAM;
- if ((res = joyGetPosEx( id, &infoex ))) return res;
- return SendDriverMessage( joysticks[wID].hDriver, JDD_GETPOS, (LPARAM)lpInfo, 0 );
- info->wXpos = infoex.dwXpos;
- info->wYpos = infoex.dwYpos;
- info->wZpos = infoex.dwZpos;
- info->wButtons = infoex.dwButtons;
- return JOYERR_NOERROR;
}
/**************************************************************************
2.34.0
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winmm/joystick.c | 202 ++++++++++++++++++++---------------------- 1 file changed, 98 insertions(+), 104 deletions(-)
diff --git a/dlls/winmm/joystick.c b/dlls/winmm/joystick.c index 666b0e6c871..842b521a586 100644 --- a/dlls/winmm/joystick.c +++ b/dlls/winmm/joystick.c @@ -44,12 +44,12 @@ WINE_DEFAULT_DEBUG_CHANNEL(winmm); #define JOY_PERIOD_MAX (1000) /* max Capture time period */
typedef struct tagWINE_JOYSTICK { - JOYINFO ji; - HWND hCapture; - UINT wTimer; - DWORD threshold; - BOOL bChanged; - HDRVR hDriver; + JOYINFO info; + HWND capture; + UINT timer; + DWORD threshold; + BOOL changed; + HDRVR driver; } WINE_JOYSTICK;
static WINE_JOYSTICK joysticks[16]; @@ -68,11 +68,11 @@ static BOOL JOY_LoadDriver(DWORD dwJoyID) static BOOL winejoystick_missing = FALSE;
if (dwJoyID >= ARRAY_SIZE(joysticks) || winejoystick_missing) return FALSE; - if (joysticks[dwJoyID].hDriver) return TRUE; + if (joysticks[dwJoyID].driver) return TRUE;
- joysticks[dwJoyID].hDriver = OpenDriverA( "winejoystick.drv", 0, dwJoyID ); + joysticks[dwJoyID].driver = OpenDriverA( "winejoystick.drv", 0, dwJoyID );
- if (!joysticks[dwJoyID].hDriver) + if (!joysticks[dwJoyID].driver) { WARN("OpenDriverA("winejoystick.drv") failed\n");
@@ -80,56 +80,50 @@ static BOOL JOY_LoadDriver(DWORD dwJoyID) winejoystick_missing = TRUE; }
- return (joysticks[dwJoyID].hDriver != 0); + return (joysticks[dwJoyID].driver != 0); }
-/************************************************************************** - * JOY_Timer [internal] - */ -static void CALLBACK JOY_Timer(HWND hWnd, UINT wMsg, UINT_PTR wTimer, DWORD dwTime) +static void CALLBACK joystick_timer( HWND hwnd, UINT msg, UINT_PTR timer, DWORD time ) { - int i; - WINE_JOYSTICK* joy; - MMRESULT res; - JOYINFO ji; - LONG pos; - unsigned buttonChange; + MMRESULT res; + JOYINFO info; + WORD change; + LONG pos; + int i;
for (i = 0; i < ARRAY_SIZE(joysticks); i++) { - joy = &joysticks[i]; + if (joysticks[i].capture != hwnd) continue; + if ((res = joyGetPos( i, &info ))) + { + WARN( "joyGetPos failed: %08x\n", res ); + continue; + }
- if (joy->hCapture != hWnd) continue; + pos = MAKELONG( info.wXpos, info.wYpos );
- res = joyGetPos(i, &ji); - if (res != JOYERR_NOERROR) { - WARN("joyGetPos failed: %08x\n", res); - continue; - } - - pos = MAKELONG(ji.wXpos, ji.wYpos); - - if (!joy->bChanged || - !compare_uint(joy->ji.wXpos, ji.wXpos, joy->threshold) || - !compare_uint(joy->ji.wYpos, ji.wYpos, joy->threshold)) { - SendMessageA(joy->hCapture, MM_JOY1MOVE + i, ji.wButtons, pos); - joy->ji.wXpos = ji.wXpos; - joy->ji.wYpos = ji.wYpos; - } - if (!joy->bChanged || - !compare_uint(joy->ji.wZpos, ji.wZpos, joy->threshold)) { - SendMessageA(joy->hCapture, MM_JOY1ZMOVE + i, ji.wButtons, pos); - joy->ji.wZpos = ji.wZpos; - } - if ((buttonChange = joy->ji.wButtons ^ ji.wButtons) != 0) { - if (ji.wButtons & buttonChange) - SendMessageA(joy->hCapture, MM_JOY1BUTTONDOWN + i, - (buttonChange << 8) | (ji.wButtons & buttonChange), pos); - if (joy->ji.wButtons & buttonChange) - SendMessageA(joy->hCapture, MM_JOY1BUTTONUP + i, - (buttonChange << 8) | (joy->ji.wButtons & buttonChange), pos); - joy->ji.wButtons = ji.wButtons; - } + if (!joysticks[i].changed || + !compare_uint( joysticks[i].info.wXpos, info.wXpos, joysticks[i].threshold ) || + !compare_uint( joysticks[i].info.wYpos, info.wYpos, joysticks[i].threshold )) + { + SendMessageA( hwnd, MM_JOY1MOVE + i, info.wButtons, pos ); + joysticks[i].info.wXpos = info.wXpos; + joysticks[i].info.wYpos = info.wYpos; + } + if (!joysticks[i].changed || + !compare_uint( joysticks[i].info.wZpos, info.wZpos, joysticks[i].threshold )) + { + SendMessageA( hwnd, MM_JOY1ZMOVE + i, info.wButtons, pos ); + joysticks[i].info.wZpos = info.wZpos; + } + if ((change = joysticks[i].info.wButtons ^ info.wButtons) != 0) + { + if (info.wButtons & change) + SendMessageA( hwnd, MM_JOY1BUTTONDOWN + i, (change << 8) | (info.wButtons & change), pos ); + if (joysticks[i].info.wButtons & change) + SendMessageA( hwnd, MM_JOY1BUTTONUP + i, (change << 8) | (joysticks[i].info.wButtons & change), pos ); + joysticks[i].info.wButtons = info.wButtons; + } } }
@@ -138,11 +132,8 @@ static void CALLBACK JOY_Timer(HWND hWnd, UINT wMsg, UINT_PTR wTimer, DWORD dwTi */ MMRESULT WINAPI joyConfigChanged(DWORD flags) { - FIXME("(%x) - stub\n", flags); - - if (flags) - return JOYERR_PARMS; - + FIXME( "flags %#x stub!\n", flags ); + if (flags) return JOYERR_PARMS; return JOYERR_NOERROR; }
@@ -174,7 +165,7 @@ MMRESULT WINAPI DECLSPEC_HOTPATCH joyGetDevCapsW( UINT_PTR id, JOYCAPSW *caps, U caps->wPeriodMin = JOY_PERIOD_MIN; /* FIXME */ caps->wPeriodMax = JOY_PERIOD_MAX; /* FIXME (same as MS Joystick Driver) */
- return SendDriverMessage( joysticks[id].hDriver, JDD_GETDEVCAPS, (LPARAM)caps, size ); + return SendDriverMessage( joysticks[id].driver, JDD_GETDEVCAPS, (LPARAM)caps, size ); }
/************************************************************************** @@ -237,27 +228,27 @@ MMRESULT WINAPI DECLSPEC_HOTPATCH joyGetDevCapsA( UINT_PTR id, JOYCAPSA *caps, U /************************************************************************** * joyGetPosEx [WINMM.@] */ -MMRESULT WINAPI DECLSPEC_HOTPATCH joyGetPosEx(UINT wID, LPJOYINFOEX lpInfo) +MMRESULT WINAPI DECLSPEC_HOTPATCH joyGetPosEx( UINT id, JOYINFOEX *info ) { - TRACE("(%d, %p);\n", wID, lpInfo); + TRACE( "id %u, info %p.\n", id, info );
- if (!lpInfo) return MMSYSERR_INVALPARAM; - if (wID >= ARRAY_SIZE(joysticks) || lpInfo->dwSize < sizeof(JOYINFOEX)) return JOYERR_PARMS; - if (!JOY_LoadDriver(wID)) return MMSYSERR_NODRIVER; + if (!info) return MMSYSERR_INVALPARAM; + if (id >= ARRAY_SIZE(joysticks) || info->dwSize < sizeof(JOYINFOEX)) return JOYERR_PARMS; + if (!JOY_LoadDriver( id )) return MMSYSERR_NODRIVER;
- lpInfo->dwXpos = 0; - lpInfo->dwYpos = 0; - lpInfo->dwZpos = 0; - lpInfo->dwRpos = 0; - lpInfo->dwUpos = 0; - lpInfo->dwVpos = 0; - lpInfo->dwButtons = 0; - lpInfo->dwButtonNumber = 0; - lpInfo->dwPOV = 0; - lpInfo->dwReserved1 = 0; - lpInfo->dwReserved2 = 0; + info->dwXpos = 0; + info->dwYpos = 0; + info->dwZpos = 0; + info->dwRpos = 0; + info->dwUpos = 0; + info->dwVpos = 0; + info->dwButtons = 0; + info->dwButtonNumber = 0; + info->dwPOV = 0; + info->dwReserved1 = 0; + info->dwReserved2 = 0;
- return SendDriverMessage( joysticks[wID].hDriver, JDD_GETPOSEX, (LPARAM)lpInfo, 0 ); + return SendDriverMessage( joysticks[id].driver, JDD_GETPOSEX, (LPARAM)info, 0 ); }
/************************************************************************** @@ -288,33 +279,34 @@ MMRESULT WINAPI joyGetPos( UINT id, JOYINFO *info ) /************************************************************************** * joyGetThreshold [WINMM.@] */ -MMRESULT WINAPI joyGetThreshold(UINT wID, LPUINT lpThreshold) +MMRESULT WINAPI joyGetThreshold( UINT id, UINT *threshold ) { - TRACE("(%04X, %p);\n", wID, lpThreshold); + TRACE( "id %u, threshold %p.\n", id, threshold );
- if (wID >= ARRAY_SIZE(joysticks)) return JOYERR_PARMS; + if (id >= ARRAY_SIZE(joysticks)) return JOYERR_PARMS;
- *lpThreshold = joysticks[wID].threshold; + *threshold = joysticks[id].threshold; return JOYERR_NOERROR; }
/************************************************************************** * joyReleaseCapture [WINMM.@] */ -MMRESULT WINAPI joyReleaseCapture(UINT wID) +MMRESULT WINAPI joyReleaseCapture( UINT id ) { - TRACE("(%04X);\n", wID); + TRACE( "id %u.\n", id );
- if (wID >= ARRAY_SIZE(joysticks)) return JOYERR_PARMS; - if (!JOY_LoadDriver(wID)) return MMSYSERR_NODRIVER; - if (joysticks[wID].hCapture) - { - KillTimer( joysticks[wID].hCapture, joysticks[wID].wTimer ); - joysticks[wID].hCapture = 0; - joysticks[wID].wTimer = 0; - } - else + if (id >= ARRAY_SIZE(joysticks)) return JOYERR_PARMS; + if (!JOY_LoadDriver( id )) return MMSYSERR_NODRIVER; + + if (!joysticks[id].capture) TRACE("Joystick is not captured, ignoring request.\n"); + else + { + KillTimer( joysticks[id].capture, joysticks[id].timer ); + joysticks[id].capture = 0; + joysticks[id].timer = 0; + }
return JOYERR_NOERROR; } @@ -322,21 +314,23 @@ MMRESULT WINAPI joyReleaseCapture(UINT wID) /************************************************************************** * joySetCapture [WINMM.@] */ -MMRESULT WINAPI joySetCapture(HWND hWnd, UINT wID, UINT wPeriod, BOOL bChanged) +MMRESULT WINAPI joySetCapture( HWND hwnd, UINT id, UINT period, BOOL changed ) { - TRACE("(%p, %04X, %d, %d);\n", hWnd, wID, wPeriod, bChanged); + TRACE( "hwnd %p, id %u, period %u, changed %u.\n", hwnd, id, period, changed );
- if (wID >= ARRAY_SIZE(joysticks) || hWnd == 0) return JOYERR_PARMS; - if (wPeriod<JOY_PERIOD_MIN) wPeriod = JOY_PERIOD_MIN; - else if(wPeriod>JOY_PERIOD_MAX) wPeriod = JOY_PERIOD_MAX; - if (!JOY_LoadDriver(wID)) return MMSYSERR_NODRIVER; + if (id >= ARRAY_SIZE(joysticks) || hwnd == 0) return JOYERR_PARMS; + if (period < JOY_PERIOD_MIN) period = JOY_PERIOD_MIN; + else if (period > JOY_PERIOD_MAX) period = JOY_PERIOD_MAX; + if (!JOY_LoadDriver( id )) return MMSYSERR_NODRIVER;
- if (joysticks[wID].hCapture || !IsWindow( hWnd )) return JOYERR_NOCANDO; /* FIXME: what should be returned ? */ - if (joyGetPos( wID, &joysticks[wID].ji ) != JOYERR_NOERROR) return JOYERR_UNPLUGGED; - if ((joysticks[wID].wTimer = SetTimer( hWnd, 0, wPeriod, JOY_Timer )) == 0) return JOYERR_NOCANDO; + if (joysticks[id].capture || !IsWindow( hwnd )) + return JOYERR_NOCANDO; /* FIXME: what should be returned ? */ + if (joyGetPos( id, &joysticks[id].info ) != JOYERR_NOERROR) return JOYERR_UNPLUGGED; + if ((joysticks[id].timer = SetTimer( hwnd, 0, period, joystick_timer )) == 0) + return JOYERR_NOCANDO;
- joysticks[wID].hCapture = hWnd; - joysticks[wID].bChanged = bChanged; + joysticks[id].capture = hwnd; + joysticks[id].changed = changed;
return JOYERR_NOERROR; } @@ -344,13 +338,13 @@ MMRESULT WINAPI joySetCapture(HWND hWnd, UINT wID, UINT wPeriod, BOOL bChanged) /************************************************************************** * joySetThreshold [WINMM.@] */ -MMRESULT WINAPI joySetThreshold(UINT wID, UINT wThreshold) +MMRESULT WINAPI joySetThreshold( UINT id, UINT threshold ) { - TRACE("(%04X, %d);\n", wID, wThreshold); + TRACE( "id %u, threshold %u.\n", id, threshold );
- if (wID >= ARRAY_SIZE(joysticks) || wThreshold > 65535) return MMSYSERR_INVALPARAM; + if (id >= ARRAY_SIZE(joysticks) || threshold > 65535) return MMSYSERR_INVALPARAM;
- joysticks[wID].threshold = wThreshold; + joysticks[id].threshold = threshold;
return JOYERR_NOERROR; }
Signed-off-by: Andrew Eikum aeikum@codeweavers.com
On Fri, Dec 03, 2021 at 12:19:07PM +0100, Rémi Bernon wrote:
Signed-off-by: Rémi Bernon rbernon@codeweavers.com
dlls/winmm/joystick.c | 202 ++++++++++++++++++++---------------------- 1 file changed, 98 insertions(+), 104 deletions(-)
diff --git a/dlls/winmm/joystick.c b/dlls/winmm/joystick.c index 666b0e6c871..842b521a586 100644 --- a/dlls/winmm/joystick.c +++ b/dlls/winmm/joystick.c @@ -44,12 +44,12 @@ WINE_DEFAULT_DEBUG_CHANNEL(winmm); #define JOY_PERIOD_MAX (1000) /* max Capture time period */
typedef struct tagWINE_JOYSTICK {
- JOYINFO ji;
- HWND hCapture;
- UINT wTimer;
- DWORD threshold;
- BOOL bChanged;
- HDRVR hDriver;
- JOYINFO info;
- HWND capture;
- UINT timer;
- DWORD threshold;
- BOOL changed;
- HDRVR driver;
} WINE_JOYSTICK;
static WINE_JOYSTICK joysticks[16]; @@ -68,11 +68,11 @@ static BOOL JOY_LoadDriver(DWORD dwJoyID) static BOOL winejoystick_missing = FALSE;
if (dwJoyID >= ARRAY_SIZE(joysticks) || winejoystick_missing) return FALSE;
- if (joysticks[dwJoyID].hDriver) return TRUE;
- if (joysticks[dwJoyID].driver) return TRUE;
- joysticks[dwJoyID].hDriver = OpenDriverA( "winejoystick.drv", 0, dwJoyID );
- joysticks[dwJoyID].driver = OpenDriverA( "winejoystick.drv", 0, dwJoyID );
- if (!joysticks[dwJoyID].hDriver)
- if (!joysticks[dwJoyID].driver) { WARN("OpenDriverA("winejoystick.drv") failed\n");
@@ -80,56 +80,50 @@ static BOOL JOY_LoadDriver(DWORD dwJoyID) winejoystick_missing = TRUE; }
- return (joysticks[dwJoyID].hDriver != 0);
- return (joysticks[dwJoyID].driver != 0);
}
-/**************************************************************************
JOY_Timer [internal]
- */
-static void CALLBACK JOY_Timer(HWND hWnd, UINT wMsg, UINT_PTR wTimer, DWORD dwTime) +static void CALLBACK joystick_timer( HWND hwnd, UINT msg, UINT_PTR timer, DWORD time ) {
- int i;
- WINE_JOYSTICK* joy;
- MMRESULT res;
- JOYINFO ji;
- LONG pos;
- unsigned buttonChange;
MMRESULT res;
JOYINFO info;
WORD change;
LONG pos;
int i;
for (i = 0; i < ARRAY_SIZE(joysticks); i++) {
joy = &joysticks[i];
if (joysticks[i].capture != hwnd) continue;
if ((res = joyGetPos( i, &info )))
{
WARN( "joyGetPos failed: %08x\n", res );
continue;
}
if (joy->hCapture != hWnd) continue;
pos = MAKELONG( info.wXpos, info.wYpos );
- res = joyGetPos(i, &ji);
- if (res != JOYERR_NOERROR) {
WARN("joyGetPos failed: %08x\n", res);
continue;
- }
- pos = MAKELONG(ji.wXpos, ji.wYpos);
- if (!joy->bChanged ||
!compare_uint(joy->ji.wXpos, ji.wXpos, joy->threshold) ||
!compare_uint(joy->ji.wYpos, ji.wYpos, joy->threshold)) {
SendMessageA(joy->hCapture, MM_JOY1MOVE + i, ji.wButtons, pos);
joy->ji.wXpos = ji.wXpos;
joy->ji.wYpos = ji.wYpos;
- }
- if (!joy->bChanged ||
!compare_uint(joy->ji.wZpos, ji.wZpos, joy->threshold)) {
SendMessageA(joy->hCapture, MM_JOY1ZMOVE + i, ji.wButtons, pos);
joy->ji.wZpos = ji.wZpos;
- }
- if ((buttonChange = joy->ji.wButtons ^ ji.wButtons) != 0) {
if (ji.wButtons & buttonChange)
SendMessageA(joy->hCapture, MM_JOY1BUTTONDOWN + i,
(buttonChange << 8) | (ji.wButtons & buttonChange), pos);
if (joy->ji.wButtons & buttonChange)
SendMessageA(joy->hCapture, MM_JOY1BUTTONUP + i,
(buttonChange << 8) | (joy->ji.wButtons & buttonChange), pos);
joy->ji.wButtons = ji.wButtons;
- }
if (!joysticks[i].changed ||
!compare_uint( joysticks[i].info.wXpos, info.wXpos, joysticks[i].threshold ) ||
!compare_uint( joysticks[i].info.wYpos, info.wYpos, joysticks[i].threshold ))
{
SendMessageA( hwnd, MM_JOY1MOVE + i, info.wButtons, pos );
joysticks[i].info.wXpos = info.wXpos;
joysticks[i].info.wYpos = info.wYpos;
}
if (!joysticks[i].changed ||
!compare_uint( joysticks[i].info.wZpos, info.wZpos, joysticks[i].threshold ))
{
SendMessageA( hwnd, MM_JOY1ZMOVE + i, info.wButtons, pos );
joysticks[i].info.wZpos = info.wZpos;
}
if ((change = joysticks[i].info.wButtons ^ info.wButtons) != 0)
{
if (info.wButtons & change)
SendMessageA( hwnd, MM_JOY1BUTTONDOWN + i, (change << 8) | (info.wButtons & change), pos );
if (joysticks[i].info.wButtons & change)
SendMessageA( hwnd, MM_JOY1BUTTONUP + i, (change << 8) | (joysticks[i].info.wButtons & change), pos );
joysticks[i].info.wButtons = info.wButtons;
}}
}
@@ -138,11 +132,8 @@ static void CALLBACK JOY_Timer(HWND hWnd, UINT wMsg, UINT_PTR wTimer, DWORD dwTi */ MMRESULT WINAPI joyConfigChanged(DWORD flags) {
- FIXME("(%x) - stub\n", flags);
- if (flags)
- return JOYERR_PARMS;
- FIXME( "flags %#x stub!\n", flags );
- if (flags) return JOYERR_PARMS; return JOYERR_NOERROR;
}
@@ -174,7 +165,7 @@ MMRESULT WINAPI DECLSPEC_HOTPATCH joyGetDevCapsW( UINT_PTR id, JOYCAPSW *caps, U caps->wPeriodMin = JOY_PERIOD_MIN; /* FIXME */ caps->wPeriodMax = JOY_PERIOD_MAX; /* FIXME (same as MS Joystick Driver) */
- return SendDriverMessage( joysticks[id].hDriver, JDD_GETDEVCAPS, (LPARAM)caps, size );
- return SendDriverMessage( joysticks[id].driver, JDD_GETDEVCAPS, (LPARAM)caps, size );
}
/************************************************************************** @@ -237,27 +228,27 @@ MMRESULT WINAPI DECLSPEC_HOTPATCH joyGetDevCapsA( UINT_PTR id, JOYCAPSA *caps, U /**************************************************************************
joyGetPosEx [WINMM.@]
*/ -MMRESULT WINAPI DECLSPEC_HOTPATCH joyGetPosEx(UINT wID, LPJOYINFOEX lpInfo) +MMRESULT WINAPI DECLSPEC_HOTPATCH joyGetPosEx( UINT id, JOYINFOEX *info ) {
- TRACE("(%d, %p);\n", wID, lpInfo);
- TRACE( "id %u, info %p.\n", id, info );
- if (!lpInfo) return MMSYSERR_INVALPARAM;
- if (wID >= ARRAY_SIZE(joysticks) || lpInfo->dwSize < sizeof(JOYINFOEX)) return JOYERR_PARMS;
- if (!JOY_LoadDriver(wID)) return MMSYSERR_NODRIVER;
- if (!info) return MMSYSERR_INVALPARAM;
- if (id >= ARRAY_SIZE(joysticks) || info->dwSize < sizeof(JOYINFOEX)) return JOYERR_PARMS;
- if (!JOY_LoadDriver( id )) return MMSYSERR_NODRIVER;
- lpInfo->dwXpos = 0;
- lpInfo->dwYpos = 0;
- lpInfo->dwZpos = 0;
- lpInfo->dwRpos = 0;
- lpInfo->dwUpos = 0;
- lpInfo->dwVpos = 0;
- lpInfo->dwButtons = 0;
- lpInfo->dwButtonNumber = 0;
- lpInfo->dwPOV = 0;
- lpInfo->dwReserved1 = 0;
- lpInfo->dwReserved2 = 0;
- info->dwXpos = 0;
- info->dwYpos = 0;
- info->dwZpos = 0;
- info->dwRpos = 0;
- info->dwUpos = 0;
- info->dwVpos = 0;
- info->dwButtons = 0;
- info->dwButtonNumber = 0;
- info->dwPOV = 0;
- info->dwReserved1 = 0;
- info->dwReserved2 = 0;
- return SendDriverMessage( joysticks[wID].hDriver, JDD_GETPOSEX, (LPARAM)lpInfo, 0 );
- return SendDriverMessage( joysticks[id].driver, JDD_GETPOSEX, (LPARAM)info, 0 );
}
/************************************************************************** @@ -288,33 +279,34 @@ MMRESULT WINAPI joyGetPos( UINT id, JOYINFO *info ) /**************************************************************************
joyGetThreshold [WINMM.@]
*/ -MMRESULT WINAPI joyGetThreshold(UINT wID, LPUINT lpThreshold) +MMRESULT WINAPI joyGetThreshold( UINT id, UINT *threshold ) {
- TRACE("(%04X, %p);\n", wID, lpThreshold);
- TRACE( "id %u, threshold %p.\n", id, threshold );
- if (wID >= ARRAY_SIZE(joysticks)) return JOYERR_PARMS;
- if (id >= ARRAY_SIZE(joysticks)) return JOYERR_PARMS;
- *lpThreshold = joysticks[wID].threshold;
- *threshold = joysticks[id].threshold; return JOYERR_NOERROR;
}
/**************************************************************************
joyReleaseCapture [WINMM.@]
*/ -MMRESULT WINAPI joyReleaseCapture(UINT wID) +MMRESULT WINAPI joyReleaseCapture( UINT id ) {
- TRACE("(%04X);\n", wID);
- TRACE( "id %u.\n", id );
- if (wID >= ARRAY_SIZE(joysticks)) return JOYERR_PARMS;
- if (!JOY_LoadDriver(wID)) return MMSYSERR_NODRIVER;
- if (joysticks[wID].hCapture)
- {
KillTimer( joysticks[wID].hCapture, joysticks[wID].wTimer );
joysticks[wID].hCapture = 0;
joysticks[wID].wTimer = 0;
- }
- else
if (id >= ARRAY_SIZE(joysticks)) return JOYERR_PARMS;
if (!JOY_LoadDriver( id )) return MMSYSERR_NODRIVER;
if (!joysticks[id].capture) TRACE("Joystick is not captured, ignoring request.\n");
else
{
KillTimer( joysticks[id].capture, joysticks[id].timer );
joysticks[id].capture = 0;
joysticks[id].timer = 0;
}
return JOYERR_NOERROR;
} @@ -322,21 +314,23 @@ MMRESULT WINAPI joyReleaseCapture(UINT wID) /**************************************************************************
joySetCapture [WINMM.@]
*/ -MMRESULT WINAPI joySetCapture(HWND hWnd, UINT wID, UINT wPeriod, BOOL bChanged) +MMRESULT WINAPI joySetCapture( HWND hwnd, UINT id, UINT period, BOOL changed ) {
- TRACE("(%p, %04X, %d, %d);\n", hWnd, wID, wPeriod, bChanged);
- TRACE( "hwnd %p, id %u, period %u, changed %u.\n", hwnd, id, period, changed );
- if (wID >= ARRAY_SIZE(joysticks) || hWnd == 0) return JOYERR_PARMS;
- if (wPeriod<JOY_PERIOD_MIN) wPeriod = JOY_PERIOD_MIN;
- else if(wPeriod>JOY_PERIOD_MAX) wPeriod = JOY_PERIOD_MAX;
- if (!JOY_LoadDriver(wID)) return MMSYSERR_NODRIVER;
- if (id >= ARRAY_SIZE(joysticks) || hwnd == 0) return JOYERR_PARMS;
- if (period < JOY_PERIOD_MIN) period = JOY_PERIOD_MIN;
- else if (period > JOY_PERIOD_MAX) period = JOY_PERIOD_MAX;
- if (!JOY_LoadDriver( id )) return MMSYSERR_NODRIVER;
- if (joysticks[wID].hCapture || !IsWindow( hWnd )) return JOYERR_NOCANDO; /* FIXME: what should be returned ? */
- if (joyGetPos( wID, &joysticks[wID].ji ) != JOYERR_NOERROR) return JOYERR_UNPLUGGED;
- if ((joysticks[wID].wTimer = SetTimer( hWnd, 0, wPeriod, JOY_Timer )) == 0) return JOYERR_NOCANDO;
- if (joysticks[id].capture || !IsWindow( hwnd ))
return JOYERR_NOCANDO; /* FIXME: what should be returned ? */
- if (joyGetPos( id, &joysticks[id].info ) != JOYERR_NOERROR) return JOYERR_UNPLUGGED;
- if ((joysticks[id].timer = SetTimer( hwnd, 0, period, joystick_timer )) == 0)
return JOYERR_NOCANDO;
- joysticks[wID].hCapture = hWnd;
- joysticks[wID].bChanged = bChanged;
joysticks[id].capture = hwnd;
joysticks[id].changed = changed;
return JOYERR_NOERROR;
} @@ -344,13 +338,13 @@ MMRESULT WINAPI joySetCapture(HWND hWnd, UINT wID, UINT wPeriod, BOOL bChanged) /**************************************************************************
joySetThreshold [WINMM.@]
*/ -MMRESULT WINAPI joySetThreshold(UINT wID, UINT wThreshold) +MMRESULT WINAPI joySetThreshold( UINT id, UINT threshold ) {
- TRACE("(%04X, %d);\n", wID, wThreshold);
- TRACE( "id %u, threshold %u.\n", id, threshold );
- if (wID >= ARRAY_SIZE(joysticks) || wThreshold > 65535) return MMSYSERR_INVALPARAM;
- if (id >= ARRAY_SIZE(joysticks) || threshold > 65535) return MMSYSERR_INVALPARAM;
- joysticks[wID].threshold = wThreshold;
joysticks[id].threshold = threshold;
return JOYERR_NOERROR;
}
2.34.0
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winmm/joystick.c | 46 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 8 deletions(-)
diff --git a/dlls/winmm/joystick.c b/dlls/winmm/joystick.c index 842b521a586..20a69e8119d 100644 --- a/dlls/winmm/joystick.c +++ b/dlls/winmm/joystick.c @@ -40,6 +40,15 @@
WINE_DEFAULT_DEBUG_CHANNEL(winmm);
+static CRITICAL_SECTION joystick_cs; +static CRITICAL_SECTION_DEBUG critsect_debug = +{ + 0, 0, &joystick_cs, + { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList }, + 0, 0, { (DWORD_PTR)(__FILE__ ": joystick_cs") } +}; +static CRITICAL_SECTION joystick_cs = { &critsect_debug, -1, 0, 0, 0, 0 }; + #define JOY_PERIOD_MIN (10) /* min Capture time period */ #define JOY_PERIOD_MAX (1000) /* max Capture time period */
@@ -91,6 +100,8 @@ static void CALLBACK joystick_timer( HWND hwnd, UINT msg, UINT_PTR timer, DWORD LONG pos; int i;
+ EnterCriticalSection( &joystick_cs ); + for (i = 0; i < ARRAY_SIZE(joysticks); i++) { if (joysticks[i].capture != hwnd) continue; @@ -125,6 +136,8 @@ static void CALLBACK joystick_timer( HWND hwnd, UINT msg, UINT_PTR timer, DWORD joysticks[i].info.wButtons = info.wButtons; } } + + LeaveCriticalSection( &joystick_cs ); }
/************************************************************************** @@ -285,7 +298,10 @@ MMRESULT WINAPI joyGetThreshold( UINT id, UINT *threshold )
if (id >= ARRAY_SIZE(joysticks)) return JOYERR_PARMS;
+ EnterCriticalSection( &joystick_cs ); *threshold = joysticks[id].threshold; + LeaveCriticalSection( &joystick_cs ); + return JOYERR_NOERROR; }
@@ -299,6 +315,8 @@ MMRESULT WINAPI joyReleaseCapture( UINT id ) if (id >= ARRAY_SIZE(joysticks)) return JOYERR_PARMS; if (!JOY_LoadDriver( id )) return MMSYSERR_NODRIVER;
+ EnterCriticalSection( &joystick_cs ); + if (!joysticks[id].capture) TRACE("Joystick is not captured, ignoring request.\n"); else @@ -308,6 +326,8 @@ MMRESULT WINAPI joyReleaseCapture( UINT id ) joysticks[id].timer = 0; }
+ LeaveCriticalSection( &joystick_cs ); + return JOYERR_NOERROR; }
@@ -316,6 +336,8 @@ MMRESULT WINAPI joyReleaseCapture( UINT id ) */ MMRESULT WINAPI joySetCapture( HWND hwnd, UINT id, UINT period, BOOL changed ) { + MMRESULT res = JOYERR_NOERROR; + TRACE( "hwnd %p, id %u, period %u, changed %u.\n", hwnd, id, period, changed );
if (id >= ARRAY_SIZE(joysticks) || hwnd == 0) return JOYERR_PARMS; @@ -323,16 +345,22 @@ MMRESULT WINAPI joySetCapture( HWND hwnd, UINT id, UINT period, BOOL changed ) else if (period > JOY_PERIOD_MAX) period = JOY_PERIOD_MAX; if (!JOY_LoadDriver( id )) return MMSYSERR_NODRIVER;
+ EnterCriticalSection( &joystick_cs ); + if (joysticks[id].capture || !IsWindow( hwnd )) - return JOYERR_NOCANDO; /* FIXME: what should be returned ? */ - if (joyGetPos( id, &joysticks[id].info ) != JOYERR_NOERROR) return JOYERR_UNPLUGGED; - if ((joysticks[id].timer = SetTimer( hwnd, 0, period, joystick_timer )) == 0) - return JOYERR_NOCANDO; + res = JOYERR_NOCANDO; /* FIXME: what should be returned ? */ + else if (joyGetPos( id, &joysticks[id].info ) != JOYERR_NOERROR) + res = JOYERR_UNPLUGGED; + else if ((joysticks[id].timer = SetTimer( hwnd, 0, period, joystick_timer )) == 0) + res = JOYERR_NOCANDO; + else + { + joysticks[id].capture = hwnd; + joysticks[id].changed = changed; + }
- joysticks[id].capture = hwnd; - joysticks[id].changed = changed; - - return JOYERR_NOERROR; + LeaveCriticalSection( &joystick_cs ); + return res; }
/************************************************************************** @@ -344,7 +372,9 @@ MMRESULT WINAPI joySetThreshold( UINT id, UINT threshold )
if (id >= ARRAY_SIZE(joysticks) || threshold > 65535) return MMSYSERR_INVALPARAM;
+ EnterCriticalSection( &joystick_cs ); joysticks[id].threshold = threshold; + LeaveCriticalSection( &joystick_cs );
return JOYERR_NOERROR; }
Signed-off-by: Andrew Eikum aeikum@codeweavers.com
On Fri, Dec 03, 2021 at 12:19:08PM +0100, Rémi Bernon wrote:
Signed-off-by: Rémi Bernon rbernon@codeweavers.com
dlls/winmm/joystick.c | 46 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 8 deletions(-)
diff --git a/dlls/winmm/joystick.c b/dlls/winmm/joystick.c index 842b521a586..20a69e8119d 100644 --- a/dlls/winmm/joystick.c +++ b/dlls/winmm/joystick.c @@ -40,6 +40,15 @@
WINE_DEFAULT_DEBUG_CHANNEL(winmm);
+static CRITICAL_SECTION joystick_cs; +static CRITICAL_SECTION_DEBUG critsect_debug = +{
- 0, 0, &joystick_cs,
- { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
0, 0, { (DWORD_PTR)(__FILE__ ": joystick_cs") }
+}; +static CRITICAL_SECTION joystick_cs = { &critsect_debug, -1, 0, 0, 0, 0 };
#define JOY_PERIOD_MIN (10) /* min Capture time period */ #define JOY_PERIOD_MAX (1000) /* max Capture time period */
@@ -91,6 +100,8 @@ static void CALLBACK joystick_timer( HWND hwnd, UINT msg, UINT_PTR timer, DWORD LONG pos; int i;
- EnterCriticalSection( &joystick_cs );
- for (i = 0; i < ARRAY_SIZE(joysticks); i++) { if (joysticks[i].capture != hwnd) continue;
@@ -125,6 +136,8 @@ static void CALLBACK joystick_timer( HWND hwnd, UINT msg, UINT_PTR timer, DWORD joysticks[i].info.wButtons = info.wButtons; } }
- LeaveCriticalSection( &joystick_cs );
}
/************************************************************************** @@ -285,7 +298,10 @@ MMRESULT WINAPI joyGetThreshold( UINT id, UINT *threshold )
if (id >= ARRAY_SIZE(joysticks)) return JOYERR_PARMS;
- EnterCriticalSection( &joystick_cs ); *threshold = joysticks[id].threshold;
- LeaveCriticalSection( &joystick_cs );
- return JOYERR_NOERROR;
}
@@ -299,6 +315,8 @@ MMRESULT WINAPI joyReleaseCapture( UINT id ) if (id >= ARRAY_SIZE(joysticks)) return JOYERR_PARMS; if (!JOY_LoadDriver( id )) return MMSYSERR_NODRIVER;
- EnterCriticalSection( &joystick_cs );
- if (!joysticks[id].capture) TRACE("Joystick is not captured, ignoring request.\n"); else
@@ -308,6 +326,8 @@ MMRESULT WINAPI joyReleaseCapture( UINT id ) joysticks[id].timer = 0; }
- LeaveCriticalSection( &joystick_cs );
- return JOYERR_NOERROR;
}
@@ -316,6 +336,8 @@ MMRESULT WINAPI joyReleaseCapture( UINT id ) */ MMRESULT WINAPI joySetCapture( HWND hwnd, UINT id, UINT period, BOOL changed ) {
MMRESULT res = JOYERR_NOERROR;
TRACE( "hwnd %p, id %u, period %u, changed %u.\n", hwnd, id, period, changed );
if (id >= ARRAY_SIZE(joysticks) || hwnd == 0) return JOYERR_PARMS;
@@ -323,16 +345,22 @@ MMRESULT WINAPI joySetCapture( HWND hwnd, UINT id, UINT period, BOOL changed ) else if (period > JOY_PERIOD_MAX) period = JOY_PERIOD_MAX; if (!JOY_LoadDriver( id )) return MMSYSERR_NODRIVER;
- EnterCriticalSection( &joystick_cs );
- if (joysticks[id].capture || !IsWindow( hwnd ))
return JOYERR_NOCANDO; /* FIXME: what should be returned ? */
- if (joyGetPos( id, &joysticks[id].info ) != JOYERR_NOERROR) return JOYERR_UNPLUGGED;
- if ((joysticks[id].timer = SetTimer( hwnd, 0, period, joystick_timer )) == 0)
return JOYERR_NOCANDO;
res = JOYERR_NOCANDO; /* FIXME: what should be returned ? */
- else if (joyGetPos( id, &joysticks[id].info ) != JOYERR_NOERROR)
res = JOYERR_UNPLUGGED;
- else if ((joysticks[id].timer = SetTimer( hwnd, 0, period, joystick_timer )) == 0)
res = JOYERR_NOCANDO;
- else
- {
joysticks[id].capture = hwnd;
joysticks[id].changed = changed;
- }
- joysticks[id].capture = hwnd;
- joysticks[id].changed = changed;
- return JOYERR_NOERROR;
- LeaveCriticalSection( &joystick_cs );
- return res;
}
/************************************************************************** @@ -344,7 +372,9 @@ MMRESULT WINAPI joySetThreshold( UINT id, UINT threshold )
if (id >= ARRAY_SIZE(joysticks) || threshold > 65535) return MMSYSERR_INVALPARAM;
EnterCriticalSection( &joystick_cs ); joysticks[id].threshold = threshold;
LeaveCriticalSection( &joystick_cs );
return JOYERR_NOERROR;
}
2.34.0
Based on a patch from Zebediah Figura zfigura@codeweavers.com.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput8/tests/hid.c | 51 ------ dlls/winmm/Makefile.in | 2 +- dlls/winmm/joystick.c | 355 +++++++++++++++++++++++++++++++++------ dlls/winmm/winemm.h | 3 + dlls/winmm/winmm.c | 2 + 5 files changed, 308 insertions(+), 105 deletions(-)
diff --git a/dlls/dinput8/tests/hid.c b/dlls/dinput8/tests/hid.c index f82fa9a7cb0..c7bf549deb1 100644 --- a/dlls/dinput8/tests/hid.c +++ b/dlls/dinput8/tests/hid.c @@ -9736,10 +9736,6 @@ static void test_winmm_joystick(void) ok( ret == 16, "joyGetNumDevs returned %u\n", ret );
ret = joyGetDevCapsW( 0, (JOYCAPSW *)&caps, sizeof(JOYCAPSW) ); - /* FIXME: Marvin somehow manages to get a device, ignore it */ - if (!strcmp( winetest_platform, "wine") && ret == 0 && - !wcscmp( caps.szPname, L"QEMU Virtio Tablet" )) - return; ok( ret == JOYERR_PARMS, "joyGetDevCapsW returned %u\n", ret );
memset( &caps, 0xcd, sizeof(caps) ); @@ -9783,7 +9779,6 @@ static void test_winmm_joystick(void) ret = joyGetPosEx( 0, &infoex ); /* first call for an index sometimes fail */ if (ret == JOYERR_PARMS) ret = joyGetPosEx( 0, &infoex ); - todo_wine ok( ret == 0, "joyGetPosEx returned %u\n", ret );
ret = joyGetDevCapsW( 1, (JOYCAPSW *)&caps, sizeof(JOYCAPSW) ); @@ -9791,43 +9786,29 @@ static void test_winmm_joystick(void)
memset( &caps, 0xcd, sizeof(caps) ); ret = joyGetDevCapsW( 0, (JOYCAPSW *)&caps, sizeof(caps) ); - todo_wine ok( ret == 0, "joyGetDevCapsW returned %u\n", ret ); - todo_wine check_member( caps, expect_caps, "%#x", wMid ); - todo_wine check_member( caps, expect_caps, "%#x", wPid ); todo_wine check_member_wstr( caps, expect_caps, szPname ); check_member( caps, expect_caps, "%#x", wXmin ); - todo_wine check_member( caps, expect_caps, "%#x", wXmax ); check_member( caps, expect_caps, "%#x", wYmin ); - todo_wine check_member( caps, expect_caps, "%#x", wYmax ); check_member( caps, expect_caps, "%#x", wZmin ); - todo_wine check_member( caps, expect_caps, "%#x", wZmax ); - todo_wine check_member( caps, expect_caps, "%#x", wNumButtons ); check_member( caps, expect_caps, "%#x", wPeriodMin ); check_member( caps, expect_caps, "%#x", wPeriodMax ); check_member( caps, expect_caps, "%#x", wRmin ); - todo_wine check_member( caps, expect_caps, "%#x", wRmax ); check_member( caps, expect_caps, "%#x", wUmin ); - todo_wine check_member( caps, expect_caps, "%#x", wUmax ); check_member( caps, expect_caps, "%#x", wVmin ); - todo_wine check_member( caps, expect_caps, "%#x", wVmax ); - todo_wine check_member( caps, expect_caps, "%#x", wCaps ); - todo_wine check_member( caps, expect_caps, "%#x", wMaxAxes ); - todo_wine check_member( caps, expect_caps, "%#x", wNumAxes ); - todo_wine check_member( caps, expect_caps, "%#x", wMaxButtons ); check_member_wstr( caps, expect_caps, szRegKey ); check_member_wstr( caps, expect_caps, szOEMVxD ); @@ -9836,7 +9817,6 @@ static void test_winmm_joystick(void) check_member_guid( caps, expect_caps, NameGuid );
ret = joyGetDevCapsW( 0, (JOYCAPSW *)&caps, sizeof(JOYCAPSW) ); - todo_wine ok( ret == 0, "joyGetDevCapsW returned %u\n", ret ); ret = joyGetDevCapsW( 0, NULL, sizeof(JOYCAPSW) ); ok( ret == MMSYSERR_INVALPARAM, "joyGetDevCapsW returned %u\n", ret ); @@ -9858,29 +9838,19 @@ static void test_winmm_joystick(void) infoex.dwSize = sizeof(JOYINFOEX); infoex.dwFlags = JOY_RETURNALL; ret = joyGetPosEx( 0, &infoex ); - todo_wine ok( ret == 0, "joyGetPosEx returned %u\n", ret ); check_member( infoex, expect_infoex[0], "%#x", dwSize ); check_member( infoex, expect_infoex[0], "%#x", dwFlags ); - todo_wine check_member( infoex, expect_infoex[0], "%#x", dwXpos ); - todo_wine check_member( infoex, expect_infoex[0], "%#x", dwYpos ); - todo_wine check_member( infoex, expect_infoex[0], "%#x", dwZpos ); - todo_wine check_member( infoex, expect_infoex[0], "%#x", dwRpos ); - todo_wine check_member( infoex, expect_infoex[0], "%#x", dwUpos ); - todo_wine check_member( infoex, expect_infoex[0], "%#x", dwVpos ); check_member( infoex, expect_infoex[0], "%#x", dwButtons ); check_member( infoex, expect_infoex[0], "%#x", dwButtonNumber ); - todo_wine check_member( infoex, expect_infoex[0], "%#x", dwPOV ); - todo_wine check_member( infoex, expect_infoex[0], "%#x", dwReserved1 ); - todo_wine check_member( infoex, expect_infoex[0], "%#x", dwReserved2 );
infoex.dwSize = sizeof(JOYINFOEX) - 4; @@ -9893,13 +9863,9 @@ static void test_winmm_joystick(void) ok( ret == JOYERR_PARMS, "joyGetPos returned %u\n", ret ); memset( &info, 0xcd, sizeof(info) ); ret = joyGetPos( 0, &info ); - todo_wine ok( ret == 0, "joyGetPos returned %u\n", ret ); - todo_wine check_member( info, expect_info, "%#x", wXpos ); - todo_wine check_member( info, expect_info, "%#x", wYpos ); - todo_wine check_member( info, expect_info, "%#x", wZpos ); check_member( info, expect_info, "%#x", wButtons );
@@ -9933,24 +9899,16 @@ static void test_winmm_joystick(void) infoex.dwSize = sizeof(JOYINFOEX); infoex.dwFlags = JOY_RETURNALL; ret = joyGetPosEx( 0, &infoex ); - todo_wine ok( ret == 0, "joyGetPosEx returned %u\n", ret ); check_member( infoex, expect_infoex[1], "%#x", dwSize ); check_member( infoex, expect_infoex[1], "%#x", dwFlags ); check_member( infoex, expect_infoex[1], "%#x", dwXpos ); - todo_wine check_member( infoex, expect_infoex[1], "%#x", dwYpos ); - todo_wine check_member( infoex, expect_infoex[1], "%#x", dwZpos ); - todo_wine check_member( infoex, expect_infoex[1], "%#x", dwRpos ); - todo_wine check_member( infoex, expect_infoex[1], "%#x", dwUpos ); - todo_wine check_member( infoex, expect_infoex[1], "%#x", dwVpos ); - todo_wine check_member( infoex, expect_infoex[1], "%#x", dwButtons ); - todo_wine check_member( infoex, expect_infoex[1], "%#x", dwButtonNumber ); check_member( infoex, expect_infoex[1], "%#x", dwPOV );
@@ -9963,26 +9921,17 @@ static void test_winmm_joystick(void) infoex.dwSize = sizeof(JOYINFOEX); infoex.dwFlags = JOY_RETURNALL; ret = joyGetPosEx( 0, &infoex ); - todo_wine ok( ret == 0, "joyGetPosEx returned %u\n", ret ); check_member( infoex, expect_infoex[2], "%#x", dwSize ); check_member( infoex, expect_infoex[2], "%#x", dwFlags ); - todo_wine check_member( infoex, expect_infoex[2], "%#x", dwXpos ); - todo_wine check_member( infoex, expect_infoex[2], "%#x", dwYpos ); - todo_wine check_member( infoex, expect_infoex[2], "%#x", dwZpos ); check_member( infoex, expect_infoex[2], "%#x", dwRpos ); - todo_wine check_member( infoex, expect_infoex[2], "%#x", dwUpos ); - todo_wine check_member( infoex, expect_infoex[2], "%#x", dwVpos ); - todo_wine check_member( infoex, expect_infoex[2], "%#x", dwButtons ); - todo_wine check_member( infoex, expect_infoex[2], "%#x", dwButtonNumber ); - todo_wine check_member( infoex, expect_infoex[2], "%#x", dwPOV );
ret = IDirectInputDevice8_Release( device ); diff --git a/dlls/winmm/Makefile.in b/dlls/winmm/Makefile.in index 3036526c14e..5439ae21678 100644 --- a/dlls/winmm/Makefile.in +++ b/dlls/winmm/Makefile.in @@ -1,7 +1,7 @@ EXTRADEFS = -D_WINMM_ MODULE = winmm.dll IMPORTLIB = winmm -IMPORTS = uuid user32 advapi32 ole32 msacm32 +IMPORTS = uuid user32 advapi32 ole32 msacm32 dinput8
C_SRCS = \ driver.c \ diff --git a/dlls/winmm/joystick.c b/dlls/winmm/joystick.c index 20a69e8119d..5f5683e3e35 100644 --- a/dlls/winmm/joystick.c +++ b/dlls/winmm/joystick.c @@ -1,10 +1,11 @@ -/* -*- tab-width: 8; c-basic-offset: 4 -*- */ /* * joystick functions * * Copyright 1997 Andreas Mohr - * 2000 Wolfgang Schwotzer - * Eric Pouech + * Copyright 2000 Wolfgang Schwotzer + * Copyright 2000 Eric Pouech + * Copyright 2020 Zebediah Figura for CodeWeavers + * Copyright 2021 Rémi Bernon for CodeWeavers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -22,6 +23,7 @@ */
#include <stdarg.h> +#include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -30,11 +32,11 @@ #include "windef.h" #include "winbase.h" #include "mmsystem.h" -#include "wingdi.h" -#include "winuser.h" -#include "winnls.h"
-#include "mmddk.h" +#include "initguid.h" +#include "dinput.h" + +#include "winemm.h"
#include "wine/debug.h"
@@ -49,19 +51,185 @@ static CRITICAL_SECTION_DEBUG critsect_debug = }; static CRITICAL_SECTION joystick_cs = { &critsect_debug, -1, 0, 0, 0, 0 };
+struct joystick_state +{ + LONG x; + LONG y; + LONG z; + LONG u; + LONG v; + LONG r; + LONG pov; + BYTE buttons[32]; +}; + +static const DIOBJECTDATAFORMAT object_formats[] = +{ + { &GUID_XAxis, offsetof(struct joystick_state, x), DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE, DIDOI_ASPECTPOSITION }, + { &GUID_YAxis, offsetof(struct joystick_state, y), DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE, DIDOI_ASPECTPOSITION }, + { &GUID_ZAxis, offsetof(struct joystick_state, z), DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE, DIDOI_ASPECTPOSITION }, + { &GUID_RzAxis, offsetof(struct joystick_state, r), DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE, DIDOI_ASPECTPOSITION }, + { &GUID_Slider, offsetof(struct joystick_state, u), DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE, DIDOI_ASPECTPOSITION }, + { &GUID_RxAxis, offsetof(struct joystick_state, v), DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE, DIDOI_ASPECTPOSITION }, + { &GUID_POV, offsetof(struct joystick_state, pov), DIDFT_OPTIONAL|DIDFT_POV|DIDFT_ANYINSTANCE, 0 }, + { NULL, offsetof(struct joystick_state, buttons[0]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 }, + { NULL, offsetof(struct joystick_state, buttons[1]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 }, + { NULL, offsetof(struct joystick_state, buttons[2]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 }, + { NULL, offsetof(struct joystick_state, buttons[3]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 }, + { NULL, offsetof(struct joystick_state, buttons[4]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 }, + { NULL, offsetof(struct joystick_state, buttons[5]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 }, + { NULL, offsetof(struct joystick_state, buttons[6]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 }, + { NULL, offsetof(struct joystick_state, buttons[7]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 }, + { NULL, offsetof(struct joystick_state, buttons[8]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 }, + { NULL, offsetof(struct joystick_state, buttons[9]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 }, + { NULL, offsetof(struct joystick_state, buttons[10]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 }, + { NULL, offsetof(struct joystick_state, buttons[11]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 }, + { NULL, offsetof(struct joystick_state, buttons[12]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 }, + { NULL, offsetof(struct joystick_state, buttons[13]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 }, + { NULL, offsetof(struct joystick_state, buttons[14]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 }, + { NULL, offsetof(struct joystick_state, buttons[15]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 }, + { NULL, offsetof(struct joystick_state, buttons[16]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 }, + { NULL, offsetof(struct joystick_state, buttons[17]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 }, + { NULL, offsetof(struct joystick_state, buttons[18]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 }, + { NULL, offsetof(struct joystick_state, buttons[19]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 }, + { NULL, offsetof(struct joystick_state, buttons[20]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 }, + { NULL, offsetof(struct joystick_state, buttons[21]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 }, + { NULL, offsetof(struct joystick_state, buttons[22]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 }, + { NULL, offsetof(struct joystick_state, buttons[23]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 }, + { NULL, offsetof(struct joystick_state, buttons[24]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 }, + { NULL, offsetof(struct joystick_state, buttons[25]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 }, + { NULL, offsetof(struct joystick_state, buttons[26]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 }, + { NULL, offsetof(struct joystick_state, buttons[27]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 }, + { NULL, offsetof(struct joystick_state, buttons[28]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 }, + { NULL, offsetof(struct joystick_state, buttons[29]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 }, + { NULL, offsetof(struct joystick_state, buttons[30]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 }, + { NULL, offsetof(struct joystick_state, buttons[31]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 }, +}; + +static const DIDATAFORMAT data_format = +{ + .dwSize = sizeof(DIDATAFORMAT), + .dwObjSize = sizeof(DIOBJECTDATAFORMAT), + .dwFlags = DIDF_ABSAXIS, + .dwDataSize = sizeof(struct joystick_state), + .dwNumObjs = ARRAY_SIZE(object_formats), + .rgodf = (DIOBJECTDATAFORMAT *)object_formats, +}; + #define JOY_PERIOD_MIN (10) /* min Capture time period */ #define JOY_PERIOD_MAX (1000) /* max Capture time period */
-typedef struct tagWINE_JOYSTICK { +struct joystick +{ + DIDEVICEINSTANCEW instance; + IDirectInputDevice8W *device; + struct joystick_state state; + HANDLE event; + JOYINFO info; HWND capture; UINT timer; DWORD threshold; BOOL changed; - HDRVR driver; -} WINE_JOYSTICK; + ULONG last_check; +};
-static WINE_JOYSTICK joysticks[16]; +static DIDEVICEINSTANCEW instances[16]; +static struct joystick joysticks[16]; +static IDirectInput8W *dinput; + +static BOOL CALLBACK enum_instances( const DIDEVICEINSTANCEW *instance, void *context ) +{ + ULONG index = *(ULONG *)context; + BYTE type = instance->dwDevType; + + if (type == DI8DEVTYPE_MOUSE) return DIENUM_CONTINUE; + if (type == DI8DEVTYPE_KEYBOARD) return DIENUM_CONTINUE; + + instances[index++] = *instance; + if (index >= ARRAY_SIZE(instances)) return DIENUM_STOP; + *(ULONG *)context = index; + return DIENUM_CONTINUE; +} + +void joystick_load( HINSTANCE instance ) +{ + HRESULT hr = DirectInput8Create( instance, DIRECTINPUT_VERSION, &IID_IDirectInput8W, + (void **)&dinput, NULL ); + if (FAILED(hr)) WARN( "could not create dinput instance, hr %#x\n", hr ); +} + +void joystick_unload() +{ + int i; + + if (!dinput) return; + + for (i = 0; i < ARRAY_SIZE(joysticks); i++) + { + if (!joysticks[i].device) continue; + IDirectInputDevice8_Release( joysticks[i].device ); + CloseHandle( joysticks[i].event ); + } + + IDirectInput8_Release( dinput ); +} + +static void find_joysticks(void) +{ + IDirectInputDevice8W *device; + HANDLE event; + DWORD index; + HRESULT hr; + + if (!dinput) return; + + index = 0; + IDirectInput8_EnumDevices( dinput, DI8DEVCLASS_ALL, enum_instances, &index, DIEDFL_ATTACHEDONLY ); + TRACE( "found %u device instances\n", index ); + + while (index--) + { + if (!memcmp( &joysticks[index].instance, &instances[index], sizeof(DIDEVICEINSTANCEW) )) + continue; + + if (joysticks[index].device) + { + IDirectInputDevice8_Release( joysticks[index].device ); + CloseHandle( joysticks[index].event ); + } + + if (!(event = CreateEventW( NULL, FALSE, FALSE, NULL ))) + WARN( "could not event for device, error %u\n", GetLastError() ); + else if (FAILED(hr = IDirectInput8_CreateDevice( dinput, &instances[index].guidInstance, &device, NULL ))) + WARN( "could not create device %s instance, hr %#x\n", + debugstr_guid( &instances[index].guidInstance ), hr ); + else if (FAILED(hr = IDirectInputDevice8_SetEventNotification( device, event ))) + WARN( "SetEventNotification device %p hr %#x\n", device, hr ); + else if (FAILED(hr = IDirectInputDevice8_SetCooperativeLevel( device, NULL, DISCL_NONEXCLUSIVE|DISCL_BACKGROUND ))) + WARN( "SetCooperativeLevel device %p hr %#x\n", device, hr ); + else if (FAILED(hr = IDirectInputDevice8_SetDataFormat( device, &data_format ))) + WARN( "SetDataFormat device %p hr %#x\n", device, hr ); + else if (FAILED(hr = IDirectInputDevice8_Acquire( device ))) + WARN( "Acquire device %p hr %#x\n", device, hr ); + else + { + TRACE( "opened device %p event %p\n", device, event ); + + memset( &joysticks[index], 0, sizeof(struct joystick) ); + joysticks[index].instance = instances[index]; + joysticks[index].device = device; + joysticks[index].event = event; + continue; + } + + CloseHandle( event ); + if (device) IDirectInputDevice8_Release( device ); + memmove( joysticks + index, joysticks + index + 1, + (ARRAY_SIZE(joysticks) - index - 1) * sizeof(struct joystick) ); + memset( &joysticks[ARRAY_SIZE(joysticks) - 1], 0, sizeof(struct joystick) ); + } +}
static BOOL compare_uint(unsigned int x, unsigned int y, unsigned int max_diff) { @@ -69,29 +237,6 @@ static BOOL compare_uint(unsigned int x, unsigned int y, unsigned int max_diff) return diff <= max_diff; }
-/************************************************************************** - * JOY_LoadDriver [internal] - */ -static BOOL JOY_LoadDriver(DWORD dwJoyID) -{ - static BOOL winejoystick_missing = FALSE; - - if (dwJoyID >= ARRAY_SIZE(joysticks) || winejoystick_missing) return FALSE; - if (joysticks[dwJoyID].driver) return TRUE; - - joysticks[dwJoyID].driver = OpenDriverA( "winejoystick.drv", 0, dwJoyID ); - - if (!joysticks[dwJoyID].driver) - { - WARN("OpenDriverA("winejoystick.drv") failed\n"); - - /* The default driver is missing, don't attempt to load it again */ - winejoystick_missing = TRUE; - } - - return (joysticks[dwJoyID].driver != 0); -} - static void CALLBACK joystick_timer( HWND hwnd, UINT msg, UINT_PTR timer, DWORD time ) { MMRESULT res; @@ -163,6 +308,22 @@ UINT WINAPI DECLSPEC_HOTPATCH joyGetNumDevs(void) */ MMRESULT WINAPI DECLSPEC_HOTPATCH joyGetDevCapsW( UINT_PTR id, JOYCAPSW *caps, UINT size ) { + DIDEVICEOBJECTINSTANCEW instance = {.dwSize = sizeof(DIDEVICEOBJECTINSTANCEW)}; + DIDEVCAPS dicaps = {.dwSize = sizeof(DIDEVCAPS)}; + DIPROPDWORD diprop = + { + .diph = + { + .dwSize = sizeof(DIPROPDWORD), + .dwHeaderSize = sizeof(DIPROPHEADER), + .dwHow = DIPH_DEVICE, + }, + }; + MMRESULT res = JOYERR_NOERROR; + IDirectInputDevice8W *device; + ULONG ticks = GetTickCount(); + HRESULT hr; + TRACE( "id %d, caps %p, size %u.\n", (int)id, caps, size );
if (!caps) return MMSYSERR_INVALPARAM; @@ -173,12 +334,67 @@ MMRESULT WINAPI DECLSPEC_HOTPATCH joyGetDevCapsW( UINT_PTR id, JOYCAPSW *caps, U if (id == ~(UINT_PTR)0) return JOYERR_NOERROR;
if (id >= ARRAY_SIZE(joysticks)) return JOYERR_PARMS; - if (!JOY_LoadDriver( id )) return MMSYSERR_NODRIVER;
- caps->wPeriodMin = JOY_PERIOD_MIN; /* FIXME */ - caps->wPeriodMax = JOY_PERIOD_MAX; /* FIXME (same as MS Joystick Driver) */ + EnterCriticalSection( &joystick_cs );
- return SendDriverMessage( joysticks[id].driver, JDD_GETDEVCAPS, (LPARAM)caps, size ); + if (!(device = joysticks[id].device) && (ticks - joysticks[id].last_check) >= 2000) + { + joysticks[id].last_check = ticks; + find_joysticks(); + } + + if (!(device = joysticks[id].device)) res = JOYERR_PARMS; + else if (FAILED(hr = IDirectInputDevice8_GetCapabilities( device, &dicaps ))) + { + WARN( "GetCapabilities device %p returned %#x\n", device, hr ); + res = JOYERR_PARMS; + } + else + { + hr = IDirectInputDevice8_GetProperty( device, DIPROP_VIDPID, &diprop.diph ); + if (FAILED(hr)) WARN( "GetProperty device %p returned %#x\n", device, hr ); + else + { + caps->wMid = LOWORD(diprop.dwData); + caps->wPid = HIWORD(diprop.dwData); + } + + wcscpy( caps->szPname, L"Wine joystick driver" ); + caps->wXmin = 0; + caps->wXmax = 0xffff; + caps->wYmin = 0; + caps->wYmax = 0xffff; + caps->wZmin = 0; + caps->wZmax = 0xffff; + caps->wNumButtons = dicaps.dwButtons; + caps->wPeriodMin = JOY_PERIOD_MIN; + caps->wPeriodMax = JOY_PERIOD_MAX; + caps->wRmin = 0; + caps->wRmax = 0xffff; + caps->wUmin = 0; + caps->wUmax = 0xffff; + caps->wVmin = 0; + caps->wVmax = 0xffff; + caps->wCaps = 0; + caps->wMaxAxes = 6; + caps->wNumAxes = min( dicaps.dwAxes, caps->wMaxAxes ); + caps->wMaxButtons = 32; + + hr = IDirectInputDevice8_GetObjectInfo( device, &instance, offsetof(struct joystick_state, z), DIPH_BYOFFSET ); + if (SUCCEEDED(hr)) caps->wCaps |= JOYCAPS_HASZ; + hr = IDirectInputDevice8_GetObjectInfo( device, &instance, offsetof(struct joystick_state, r), DIPH_BYOFFSET ); + if (SUCCEEDED(hr)) caps->wCaps |= JOYCAPS_HASR; + hr = IDirectInputDevice8_GetObjectInfo( device, &instance, offsetof(struct joystick_state, u), DIPH_BYOFFSET ); + if (SUCCEEDED(hr)) caps->wCaps |= JOYCAPS_HASU; + hr = IDirectInputDevice8_GetObjectInfo( device, &instance, offsetof(struct joystick_state, v), DIPH_BYOFFSET ); + if (SUCCEEDED(hr)) caps->wCaps |= JOYCAPS_HASV; + hr = IDirectInputDevice8_GetObjectInfo( device, &instance, offsetof(struct joystick_state, pov), DIPH_BYOFFSET ); + if (SUCCEEDED(hr)) caps->wCaps |= JOYCAPS_HASPOV|JOYCAPS_POV4DIR; + } + + LeaveCriticalSection( &joystick_cs ); + + return res; }
/************************************************************************** @@ -243,25 +459,60 @@ MMRESULT WINAPI DECLSPEC_HOTPATCH joyGetDevCapsA( UINT_PTR id, JOYCAPSA *caps, U */ MMRESULT WINAPI DECLSPEC_HOTPATCH joyGetPosEx( UINT id, JOYINFOEX *info ) { + DWORD i, ticks = GetTickCount(); + MMRESULT res = JOYERR_NOERROR; + IDirectInputDevice8W *device; + struct joystick_state state; + HRESULT hr; + TRACE( "id %u, info %p.\n", id, info );
if (!info) return MMSYSERR_INVALPARAM; if (id >= ARRAY_SIZE(joysticks) || info->dwSize < sizeof(JOYINFOEX)) return JOYERR_PARMS; - if (!JOY_LoadDriver( id )) return MMSYSERR_NODRIVER;
- info->dwXpos = 0; - info->dwYpos = 0; - info->dwZpos = 0; - info->dwRpos = 0; - info->dwUpos = 0; - info->dwVpos = 0; - info->dwButtons = 0; - info->dwButtonNumber = 0; - info->dwPOV = 0; - info->dwReserved1 = 0; - info->dwReserved2 = 0; + EnterCriticalSection( &joystick_cs );
- return SendDriverMessage( joysticks[id].driver, JDD_GETPOSEX, (LPARAM)info, 0 ); + if (!(device = joysticks[id].device) && (ticks - joysticks[id].last_check) >= 2000) + { + joysticks[id].last_check = ticks; + find_joysticks(); + } + + if (!(device = joysticks[id].device)) + res = JOYERR_PARMS; + else if (FAILED(hr = IDirectInputDevice8_GetDeviceState( device, sizeof(struct joystick_state), &state ))) + { + WARN( "GetDeviceState device %p returned %#x\n", device, hr ); + res = JOYERR_PARMS; + } + else + { + if (info->dwFlags & JOY_RETURNX) info->dwXpos = state.x; + if (info->dwFlags & JOY_RETURNY) info->dwYpos = state.y; + if (info->dwFlags & JOY_RETURNZ) info->dwZpos = state.z; + if (info->dwFlags & JOY_RETURNR) info->dwRpos = state.r; + if (info->dwFlags & JOY_RETURNU) info->dwUpos = state.u; + if (info->dwFlags & JOY_RETURNV) info->dwVpos = state.v; + if (info->dwFlags & JOY_RETURNPOV) + { + if (state.pov == ~0) info->dwPOV = 0xffff; + else info->dwPOV = state.pov; + } + if (info->dwFlags & JOY_RETURNBUTTONS) + { + info->dwButtonNumber = info->dwButtons = 0; + for (i = 0; i < ARRAY_SIZE(state.buttons); ++i) + { + if (!state.buttons[i]) continue; + info->dwButtonNumber++; + info->dwButtons |= 1 << i; + } + } + } + + LeaveCriticalSection( &joystick_cs ); + + return res; }
/************************************************************************** @@ -313,7 +564,6 @@ MMRESULT WINAPI joyReleaseCapture( UINT id ) TRACE( "id %u.\n", id );
if (id >= ARRAY_SIZE(joysticks)) return JOYERR_PARMS; - if (!JOY_LoadDriver( id )) return MMSYSERR_NODRIVER;
EnterCriticalSection( &joystick_cs );
@@ -343,7 +593,6 @@ MMRESULT WINAPI joySetCapture( HWND hwnd, UINT id, UINT period, BOOL changed ) if (id >= ARRAY_SIZE(joysticks) || hwnd == 0) return JOYERR_PARMS; if (period < JOY_PERIOD_MIN) period = JOY_PERIOD_MIN; else if (period > JOY_PERIOD_MAX) period = JOY_PERIOD_MAX; - if (!JOY_LoadDriver( id )) return MMSYSERR_NODRIVER;
EnterCriticalSection( &joystick_cs );
diff --git a/dlls/winmm/winemm.h b/dlls/winmm/winemm.h index d7bab0f531d..3459c2a85ef 100644 --- a/dlls/winmm/winemm.h +++ b/dlls/winmm/winemm.h @@ -153,6 +153,9 @@ MMRESULT WINMM_CheckCallback(DWORD_PTR dwCallback, DWORD fdwOpen, BOOL mixer) DE
void WINMM_DeleteWaveform(void) DECLSPEC_HIDDEN;
+void joystick_load( HMODULE instance ) DECLSPEC_HIDDEN; +void joystick_unload( void ) DECLSPEC_HIDDEN; + /* Global variables */ extern CRITICAL_SECTION WINMM_cs DECLSPEC_HIDDEN; extern HINSTANCE hWinMM32Instance DECLSPEC_HIDDEN; diff --git a/dlls/winmm/winmm.c b/dlls/winmm/winmm.c index eea29ea61e5..aab8bfb51a9 100644 --- a/dlls/winmm/winmm.c +++ b/dlls/winmm/winmm.c @@ -145,11 +145,13 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID fImpLoad) if (!WINMM_CreateIData(hInstDLL)) return FALSE;
+ joystick_load( hInstDLL ); break; case DLL_PROCESS_DETACH: if(fImpLoad) break;
+ joystick_unload(); MCI_SendCommand(MCI_ALL_DEVICE_ID, MCI_CLOSE, MCI_WAIT, 0L); MMDRV_Exit(); DRIVER_UnloadAll();
Signed-off-by: Andrew Eikum aeikum@codeweavers.com
On Fri, Dec 03, 2021 at 12:19:09PM +0100, Rémi Bernon wrote:
Based on a patch from Zebediah Figura zfigura@codeweavers.com.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com
dlls/dinput8/tests/hid.c | 51 ------ dlls/winmm/Makefile.in | 2 +- dlls/winmm/joystick.c | 355 +++++++++++++++++++++++++++++++++------ dlls/winmm/winemm.h | 3 + dlls/winmm/winmm.c | 2 + 5 files changed, 308 insertions(+), 105 deletions(-)
diff --git a/dlls/dinput8/tests/hid.c b/dlls/dinput8/tests/hid.c index f82fa9a7cb0..c7bf549deb1 100644 --- a/dlls/dinput8/tests/hid.c +++ b/dlls/dinput8/tests/hid.c @@ -9736,10 +9736,6 @@ static void test_winmm_joystick(void) ok( ret == 16, "joyGetNumDevs returned %u\n", ret );
ret = joyGetDevCapsW( 0, (JOYCAPSW *)&caps, sizeof(JOYCAPSW) );
/* FIXME: Marvin somehow manages to get a device, ignore it */
if (!strcmp( winetest_platform, "wine") && ret == 0 &&
!wcscmp( caps.szPname, L"QEMU Virtio Tablet" ))
return;
ok( ret == JOYERR_PARMS, "joyGetDevCapsW returned %u\n", ret );
memset( &caps, 0xcd, sizeof(caps) );
@@ -9783,7 +9779,6 @@ static void test_winmm_joystick(void) ret = joyGetPosEx( 0, &infoex ); /* first call for an index sometimes fail */ if (ret == JOYERR_PARMS) ret = joyGetPosEx( 0, &infoex );
todo_wine ok( ret == 0, "joyGetPosEx returned %u\n", ret );
ret = joyGetDevCapsW( 1, (JOYCAPSW *)&caps, sizeof(JOYCAPSW) );
@@ -9791,43 +9786,29 @@ static void test_winmm_joystick(void)
memset( &caps, 0xcd, sizeof(caps) ); ret = joyGetDevCapsW( 0, (JOYCAPSW *)&caps, sizeof(caps) );
- todo_wine ok( ret == 0, "joyGetDevCapsW returned %u\n", ret );
- todo_wine check_member( caps, expect_caps, "%#x", wMid );
- todo_wine check_member( caps, expect_caps, "%#x", wPid ); todo_wine check_member_wstr( caps, expect_caps, szPname ); check_member( caps, expect_caps, "%#x", wXmin );
- todo_wine check_member( caps, expect_caps, "%#x", wXmax ); check_member( caps, expect_caps, "%#x", wYmin );
- todo_wine check_member( caps, expect_caps, "%#x", wYmax ); check_member( caps, expect_caps, "%#x", wZmin );
- todo_wine check_member( caps, expect_caps, "%#x", wZmax );
- todo_wine check_member( caps, expect_caps, "%#x", wNumButtons ); check_member( caps, expect_caps, "%#x", wPeriodMin ); check_member( caps, expect_caps, "%#x", wPeriodMax ); check_member( caps, expect_caps, "%#x", wRmin );
- todo_wine check_member( caps, expect_caps, "%#x", wRmax ); check_member( caps, expect_caps, "%#x", wUmin );
- todo_wine check_member( caps, expect_caps, "%#x", wUmax ); check_member( caps, expect_caps, "%#x", wVmin );
- todo_wine check_member( caps, expect_caps, "%#x", wVmax );
- todo_wine check_member( caps, expect_caps, "%#x", wCaps );
- todo_wine check_member( caps, expect_caps, "%#x", wMaxAxes );
- todo_wine check_member( caps, expect_caps, "%#x", wNumAxes );
- todo_wine check_member( caps, expect_caps, "%#x", wMaxButtons ); check_member_wstr( caps, expect_caps, szRegKey ); check_member_wstr( caps, expect_caps, szOEMVxD );
@@ -9836,7 +9817,6 @@ static void test_winmm_joystick(void) check_member_guid( caps, expect_caps, NameGuid );
ret = joyGetDevCapsW( 0, (JOYCAPSW *)&caps, sizeof(JOYCAPSW) );
- todo_wine ok( ret == 0, "joyGetDevCapsW returned %u\n", ret ); ret = joyGetDevCapsW( 0, NULL, sizeof(JOYCAPSW) ); ok( ret == MMSYSERR_INVALPARAM, "joyGetDevCapsW returned %u\n", ret );
@@ -9858,29 +9838,19 @@ static void test_winmm_joystick(void) infoex.dwSize = sizeof(JOYINFOEX); infoex.dwFlags = JOY_RETURNALL; ret = joyGetPosEx( 0, &infoex );
todo_wine ok( ret == 0, "joyGetPosEx returned %u\n", ret ); check_member( infoex, expect_infoex[0], "%#x", dwSize ); check_member( infoex, expect_infoex[0], "%#x", dwFlags );
todo_wine check_member( infoex, expect_infoex[0], "%#x", dwXpos );
todo_wine check_member( infoex, expect_infoex[0], "%#x", dwYpos );
todo_wine check_member( infoex, expect_infoex[0], "%#x", dwZpos );
todo_wine check_member( infoex, expect_infoex[0], "%#x", dwRpos );
todo_wine check_member( infoex, expect_infoex[0], "%#x", dwUpos );
todo_wine check_member( infoex, expect_infoex[0], "%#x", dwVpos ); check_member( infoex, expect_infoex[0], "%#x", dwButtons ); check_member( infoex, expect_infoex[0], "%#x", dwButtonNumber );
todo_wine check_member( infoex, expect_infoex[0], "%#x", dwPOV );
todo_wine check_member( infoex, expect_infoex[0], "%#x", dwReserved1 );
todo_wine check_member( infoex, expect_infoex[0], "%#x", dwReserved2 );
infoex.dwSize = sizeof(JOYINFOEX) - 4;
@@ -9893,13 +9863,9 @@ static void test_winmm_joystick(void) ok( ret == JOYERR_PARMS, "joyGetPos returned %u\n", ret ); memset( &info, 0xcd, sizeof(info) ); ret = joyGetPos( 0, &info );
- todo_wine ok( ret == 0, "joyGetPos returned %u\n", ret );
- todo_wine check_member( info, expect_info, "%#x", wXpos );
- todo_wine check_member( info, expect_info, "%#x", wYpos );
- todo_wine check_member( info, expect_info, "%#x", wZpos ); check_member( info, expect_info, "%#x", wButtons );
@@ -9933,24 +9899,16 @@ static void test_winmm_joystick(void) infoex.dwSize = sizeof(JOYINFOEX); infoex.dwFlags = JOY_RETURNALL; ret = joyGetPosEx( 0, &infoex );
- todo_wine ok( ret == 0, "joyGetPosEx returned %u\n", ret ); check_member( infoex, expect_infoex[1], "%#x", dwSize ); check_member( infoex, expect_infoex[1], "%#x", dwFlags ); check_member( infoex, expect_infoex[1], "%#x", dwXpos );
- todo_wine check_member( infoex, expect_infoex[1], "%#x", dwYpos );
- todo_wine check_member( infoex, expect_infoex[1], "%#x", dwZpos );
- todo_wine check_member( infoex, expect_infoex[1], "%#x", dwRpos );
- todo_wine check_member( infoex, expect_infoex[1], "%#x", dwUpos );
- todo_wine check_member( infoex, expect_infoex[1], "%#x", dwVpos );
- todo_wine check_member( infoex, expect_infoex[1], "%#x", dwButtons );
- todo_wine check_member( infoex, expect_infoex[1], "%#x", dwButtonNumber ); check_member( infoex, expect_infoex[1], "%#x", dwPOV );
@@ -9963,26 +9921,17 @@ static void test_winmm_joystick(void) infoex.dwSize = sizeof(JOYINFOEX); infoex.dwFlags = JOY_RETURNALL; ret = joyGetPosEx( 0, &infoex );
todo_wine ok( ret == 0, "joyGetPosEx returned %u\n", ret ); check_member( infoex, expect_infoex[2], "%#x", dwSize ); check_member( infoex, expect_infoex[2], "%#x", dwFlags );
todo_wine check_member( infoex, expect_infoex[2], "%#x", dwXpos );
todo_wine check_member( infoex, expect_infoex[2], "%#x", dwYpos );
todo_wine check_member( infoex, expect_infoex[2], "%#x", dwZpos ); check_member( infoex, expect_infoex[2], "%#x", dwRpos );
todo_wine check_member( infoex, expect_infoex[2], "%#x", dwUpos );
todo_wine check_member( infoex, expect_infoex[2], "%#x", dwVpos );
todo_wine check_member( infoex, expect_infoex[2], "%#x", dwButtons );
todo_wine check_member( infoex, expect_infoex[2], "%#x", dwButtonNumber );
todo_wine check_member( infoex, expect_infoex[2], "%#x", dwPOV );
ret = IDirectInputDevice8_Release( device );
diff --git a/dlls/winmm/Makefile.in b/dlls/winmm/Makefile.in index 3036526c14e..5439ae21678 100644 --- a/dlls/winmm/Makefile.in +++ b/dlls/winmm/Makefile.in @@ -1,7 +1,7 @@ EXTRADEFS = -D_WINMM_ MODULE = winmm.dll IMPORTLIB = winmm -IMPORTS = uuid user32 advapi32 ole32 msacm32 +IMPORTS = uuid user32 advapi32 ole32 msacm32 dinput8
C_SRCS = \ driver.c \ diff --git a/dlls/winmm/joystick.c b/dlls/winmm/joystick.c index 20a69e8119d..5f5683e3e35 100644 --- a/dlls/winmm/joystick.c +++ b/dlls/winmm/joystick.c @@ -1,10 +1,11 @@ -/* -*- tab-width: 8; c-basic-offset: 4 -*- */ /*
- joystick functions
- Copyright 1997 Andreas Mohr
2000 Wolfgang Schwotzer
Eric Pouech
- Copyright 2000 Wolfgang Schwotzer
- Copyright 2000 Eric Pouech
- Copyright 2020 Zebediah Figura for CodeWeavers
- Copyright 2021 Rémi Bernon for CodeWeavers
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
@@ -22,6 +23,7 @@ */
#include <stdarg.h> +#include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -30,11 +32,11 @@ #include "windef.h" #include "winbase.h" #include "mmsystem.h" -#include "wingdi.h" -#include "winuser.h" -#include "winnls.h"
-#include "mmddk.h" +#include "initguid.h" +#include "dinput.h"
+#include "winemm.h"
#include "wine/debug.h"
@@ -49,19 +51,185 @@ static CRITICAL_SECTION_DEBUG critsect_debug = }; static CRITICAL_SECTION joystick_cs = { &critsect_debug, -1, 0, 0, 0, 0 };
+struct joystick_state +{
- LONG x;
- LONG y;
- LONG z;
- LONG u;
- LONG v;
- LONG r;
- LONG pov;
- BYTE buttons[32];
+};
+static const DIOBJECTDATAFORMAT object_formats[] = +{
- { &GUID_XAxis, offsetof(struct joystick_state, x), DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE, DIDOI_ASPECTPOSITION },
- { &GUID_YAxis, offsetof(struct joystick_state, y), DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE, DIDOI_ASPECTPOSITION },
- { &GUID_ZAxis, offsetof(struct joystick_state, z), DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE, DIDOI_ASPECTPOSITION },
- { &GUID_RzAxis, offsetof(struct joystick_state, r), DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE, DIDOI_ASPECTPOSITION },
- { &GUID_Slider, offsetof(struct joystick_state, u), DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE, DIDOI_ASPECTPOSITION },
- { &GUID_RxAxis, offsetof(struct joystick_state, v), DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE, DIDOI_ASPECTPOSITION },
- { &GUID_POV, offsetof(struct joystick_state, pov), DIDFT_OPTIONAL|DIDFT_POV|DIDFT_ANYINSTANCE, 0 },
- { NULL, offsetof(struct joystick_state, buttons[0]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
- { NULL, offsetof(struct joystick_state, buttons[1]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
- { NULL, offsetof(struct joystick_state, buttons[2]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
- { NULL, offsetof(struct joystick_state, buttons[3]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
- { NULL, offsetof(struct joystick_state, buttons[4]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
- { NULL, offsetof(struct joystick_state, buttons[5]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
- { NULL, offsetof(struct joystick_state, buttons[6]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
- { NULL, offsetof(struct joystick_state, buttons[7]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
- { NULL, offsetof(struct joystick_state, buttons[8]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
- { NULL, offsetof(struct joystick_state, buttons[9]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
- { NULL, offsetof(struct joystick_state, buttons[10]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
- { NULL, offsetof(struct joystick_state, buttons[11]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
- { NULL, offsetof(struct joystick_state, buttons[12]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
- { NULL, offsetof(struct joystick_state, buttons[13]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
- { NULL, offsetof(struct joystick_state, buttons[14]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
- { NULL, offsetof(struct joystick_state, buttons[15]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
- { NULL, offsetof(struct joystick_state, buttons[16]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
- { NULL, offsetof(struct joystick_state, buttons[17]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
- { NULL, offsetof(struct joystick_state, buttons[18]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
- { NULL, offsetof(struct joystick_state, buttons[19]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
- { NULL, offsetof(struct joystick_state, buttons[20]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
- { NULL, offsetof(struct joystick_state, buttons[21]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
- { NULL, offsetof(struct joystick_state, buttons[22]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
- { NULL, offsetof(struct joystick_state, buttons[23]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
- { NULL, offsetof(struct joystick_state, buttons[24]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
- { NULL, offsetof(struct joystick_state, buttons[25]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
- { NULL, offsetof(struct joystick_state, buttons[26]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
- { NULL, offsetof(struct joystick_state, buttons[27]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
- { NULL, offsetof(struct joystick_state, buttons[28]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
- { NULL, offsetof(struct joystick_state, buttons[29]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
- { NULL, offsetof(struct joystick_state, buttons[30]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
- { NULL, offsetof(struct joystick_state, buttons[31]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
+};
+static const DIDATAFORMAT data_format = +{
- .dwSize = sizeof(DIDATAFORMAT),
- .dwObjSize = sizeof(DIOBJECTDATAFORMAT),
- .dwFlags = DIDF_ABSAXIS,
- .dwDataSize = sizeof(struct joystick_state),
- .dwNumObjs = ARRAY_SIZE(object_formats),
- .rgodf = (DIOBJECTDATAFORMAT *)object_formats,
+};
#define JOY_PERIOD_MIN (10) /* min Capture time period */ #define JOY_PERIOD_MAX (1000) /* max Capture time period */
-typedef struct tagWINE_JOYSTICK { +struct joystick +{
- DIDEVICEINSTANCEW instance;
- IDirectInputDevice8W *device;
- struct joystick_state state;
- HANDLE event;
- JOYINFO info; HWND capture; UINT timer; DWORD threshold; BOOL changed;
- HDRVR driver;
-} WINE_JOYSTICK;
- ULONG last_check;
+};
-static WINE_JOYSTICK joysticks[16]; +static DIDEVICEINSTANCEW instances[16]; +static struct joystick joysticks[16]; +static IDirectInput8W *dinput;
+static BOOL CALLBACK enum_instances( const DIDEVICEINSTANCEW *instance, void *context ) +{
- ULONG index = *(ULONG *)context;
- BYTE type = instance->dwDevType;
- if (type == DI8DEVTYPE_MOUSE) return DIENUM_CONTINUE;
- if (type == DI8DEVTYPE_KEYBOARD) return DIENUM_CONTINUE;
- instances[index++] = *instance;
- if (index >= ARRAY_SIZE(instances)) return DIENUM_STOP;
- *(ULONG *)context = index;
- return DIENUM_CONTINUE;
+}
+void joystick_load( HINSTANCE instance ) +{
- HRESULT hr = DirectInput8Create( instance, DIRECTINPUT_VERSION, &IID_IDirectInput8W,
(void **)&dinput, NULL );
- if (FAILED(hr)) WARN( "could not create dinput instance, hr %#x\n", hr );
+}
+void joystick_unload() +{
- int i;
- if (!dinput) return;
- for (i = 0; i < ARRAY_SIZE(joysticks); i++)
- {
if (!joysticks[i].device) continue;
IDirectInputDevice8_Release( joysticks[i].device );
CloseHandle( joysticks[i].event );
- }
- IDirectInput8_Release( dinput );
+}
+static void find_joysticks(void) +{
- IDirectInputDevice8W *device;
- HANDLE event;
- DWORD index;
- HRESULT hr;
- if (!dinput) return;
- index = 0;
- IDirectInput8_EnumDevices( dinput, DI8DEVCLASS_ALL, enum_instances, &index, DIEDFL_ATTACHEDONLY );
- TRACE( "found %u device instances\n", index );
- while (index--)
- {
if (!memcmp( &joysticks[index].instance, &instances[index], sizeof(DIDEVICEINSTANCEW) ))
continue;
if (joysticks[index].device)
{
IDirectInputDevice8_Release( joysticks[index].device );
CloseHandle( joysticks[index].event );
}
if (!(event = CreateEventW( NULL, FALSE, FALSE, NULL )))
WARN( "could not event for device, error %u\n", GetLastError() );
else if (FAILED(hr = IDirectInput8_CreateDevice( dinput, &instances[index].guidInstance, &device, NULL )))
WARN( "could not create device %s instance, hr %#x\n",
debugstr_guid( &instances[index].guidInstance ), hr );
else if (FAILED(hr = IDirectInputDevice8_SetEventNotification( device, event )))
WARN( "SetEventNotification device %p hr %#x\n", device, hr );
else if (FAILED(hr = IDirectInputDevice8_SetCooperativeLevel( device, NULL, DISCL_NONEXCLUSIVE|DISCL_BACKGROUND )))
WARN( "SetCooperativeLevel device %p hr %#x\n", device, hr );
else if (FAILED(hr = IDirectInputDevice8_SetDataFormat( device, &data_format )))
WARN( "SetDataFormat device %p hr %#x\n", device, hr );
else if (FAILED(hr = IDirectInputDevice8_Acquire( device )))
WARN( "Acquire device %p hr %#x\n", device, hr );
else
{
TRACE( "opened device %p event %p\n", device, event );
memset( &joysticks[index], 0, sizeof(struct joystick) );
joysticks[index].instance = instances[index];
joysticks[index].device = device;
joysticks[index].event = event;
continue;
}
CloseHandle( event );
if (device) IDirectInputDevice8_Release( device );
memmove( joysticks + index, joysticks + index + 1,
(ARRAY_SIZE(joysticks) - index - 1) * sizeof(struct joystick) );
memset( &joysticks[ARRAY_SIZE(joysticks) - 1], 0, sizeof(struct joystick) );
- }
+}
static BOOL compare_uint(unsigned int x, unsigned int y, unsigned int max_diff) { @@ -69,29 +237,6 @@ static BOOL compare_uint(unsigned int x, unsigned int y, unsigned int max_diff) return diff <= max_diff; }
-/**************************************************************************
JOY_LoadDriver [internal]
- */
-static BOOL JOY_LoadDriver(DWORD dwJoyID) -{
- static BOOL winejoystick_missing = FALSE;
- if (dwJoyID >= ARRAY_SIZE(joysticks) || winejoystick_missing) return FALSE;
- if (joysticks[dwJoyID].driver) return TRUE;
- joysticks[dwJoyID].driver = OpenDriverA( "winejoystick.drv", 0, dwJoyID );
- if (!joysticks[dwJoyID].driver)
- {
WARN("OpenDriverA(\"winejoystick.drv\") failed\n");
/* The default driver is missing, don't attempt to load it again */
winejoystick_missing = TRUE;
- }
- return (joysticks[dwJoyID].driver != 0);
-}
static void CALLBACK joystick_timer( HWND hwnd, UINT msg, UINT_PTR timer, DWORD time ) { MMRESULT res; @@ -163,6 +308,22 @@ UINT WINAPI DECLSPEC_HOTPATCH joyGetNumDevs(void) */ MMRESULT WINAPI DECLSPEC_HOTPATCH joyGetDevCapsW( UINT_PTR id, JOYCAPSW *caps, UINT size ) {
DIDEVICEOBJECTINSTANCEW instance = {.dwSize = sizeof(DIDEVICEOBJECTINSTANCEW)};
DIDEVCAPS dicaps = {.dwSize = sizeof(DIDEVCAPS)};
DIPROPDWORD diprop =
{
.diph =
{
.dwSize = sizeof(DIPROPDWORD),
.dwHeaderSize = sizeof(DIPROPHEADER),
.dwHow = DIPH_DEVICE,
},
};
MMRESULT res = JOYERR_NOERROR;
IDirectInputDevice8W *device;
ULONG ticks = GetTickCount();
HRESULT hr;
TRACE( "id %d, caps %p, size %u.\n", (int)id, caps, size );
if (!caps) return MMSYSERR_INVALPARAM;
@@ -173,12 +334,67 @@ MMRESULT WINAPI DECLSPEC_HOTPATCH joyGetDevCapsW( UINT_PTR id, JOYCAPSW *caps, U if (id == ~(UINT_PTR)0) return JOYERR_NOERROR;
if (id >= ARRAY_SIZE(joysticks)) return JOYERR_PARMS;
if (!JOY_LoadDriver( id )) return MMSYSERR_NODRIVER;
caps->wPeriodMin = JOY_PERIOD_MIN; /* FIXME */
caps->wPeriodMax = JOY_PERIOD_MAX; /* FIXME (same as MS Joystick Driver) */
- EnterCriticalSection( &joystick_cs );
- return SendDriverMessage( joysticks[id].driver, JDD_GETDEVCAPS, (LPARAM)caps, size );
- if (!(device = joysticks[id].device) && (ticks - joysticks[id].last_check) >= 2000)
- {
joysticks[id].last_check = ticks;
find_joysticks();
- }
- if (!(device = joysticks[id].device)) res = JOYERR_PARMS;
- else if (FAILED(hr = IDirectInputDevice8_GetCapabilities( device, &dicaps )))
- {
WARN( "GetCapabilities device %p returned %#x\n", device, hr );
res = JOYERR_PARMS;
- }
- else
- {
hr = IDirectInputDevice8_GetProperty( device, DIPROP_VIDPID, &diprop.diph );
if (FAILED(hr)) WARN( "GetProperty device %p returned %#x\n", device, hr );
else
{
caps->wMid = LOWORD(diprop.dwData);
caps->wPid = HIWORD(diprop.dwData);
}
wcscpy( caps->szPname, L"Wine joystick driver" );
caps->wXmin = 0;
caps->wXmax = 0xffff;
caps->wYmin = 0;
caps->wYmax = 0xffff;
caps->wZmin = 0;
caps->wZmax = 0xffff;
caps->wNumButtons = dicaps.dwButtons;
caps->wPeriodMin = JOY_PERIOD_MIN;
caps->wPeriodMax = JOY_PERIOD_MAX;
caps->wRmin = 0;
caps->wRmax = 0xffff;
caps->wUmin = 0;
caps->wUmax = 0xffff;
caps->wVmin = 0;
caps->wVmax = 0xffff;
caps->wCaps = 0;
caps->wMaxAxes = 6;
caps->wNumAxes = min( dicaps.dwAxes, caps->wMaxAxes );
caps->wMaxButtons = 32;
hr = IDirectInputDevice8_GetObjectInfo( device, &instance, offsetof(struct joystick_state, z), DIPH_BYOFFSET );
if (SUCCEEDED(hr)) caps->wCaps |= JOYCAPS_HASZ;
hr = IDirectInputDevice8_GetObjectInfo( device, &instance, offsetof(struct joystick_state, r), DIPH_BYOFFSET );
if (SUCCEEDED(hr)) caps->wCaps |= JOYCAPS_HASR;
hr = IDirectInputDevice8_GetObjectInfo( device, &instance, offsetof(struct joystick_state, u), DIPH_BYOFFSET );
if (SUCCEEDED(hr)) caps->wCaps |= JOYCAPS_HASU;
hr = IDirectInputDevice8_GetObjectInfo( device, &instance, offsetof(struct joystick_state, v), DIPH_BYOFFSET );
if (SUCCEEDED(hr)) caps->wCaps |= JOYCAPS_HASV;
hr = IDirectInputDevice8_GetObjectInfo( device, &instance, offsetof(struct joystick_state, pov), DIPH_BYOFFSET );
if (SUCCEEDED(hr)) caps->wCaps |= JOYCAPS_HASPOV|JOYCAPS_POV4DIR;
- }
- LeaveCriticalSection( &joystick_cs );
- return res;
}
/************************************************************************** @@ -243,25 +459,60 @@ MMRESULT WINAPI DECLSPEC_HOTPATCH joyGetDevCapsA( UINT_PTR id, JOYCAPSA *caps, U */ MMRESULT WINAPI DECLSPEC_HOTPATCH joyGetPosEx( UINT id, JOYINFOEX *info ) {
DWORD i, ticks = GetTickCount();
MMRESULT res = JOYERR_NOERROR;
IDirectInputDevice8W *device;
struct joystick_state state;
HRESULT hr;
TRACE( "id %u, info %p.\n", id, info );
if (!info) return MMSYSERR_INVALPARAM; if (id >= ARRAY_SIZE(joysticks) || info->dwSize < sizeof(JOYINFOEX)) return JOYERR_PARMS;
if (!JOY_LoadDriver( id )) return MMSYSERR_NODRIVER;
info->dwXpos = 0;
info->dwYpos = 0;
info->dwZpos = 0;
info->dwRpos = 0;
info->dwUpos = 0;
info->dwVpos = 0;
info->dwButtons = 0;
info->dwButtonNumber = 0;
info->dwPOV = 0;
info->dwReserved1 = 0;
info->dwReserved2 = 0;
- EnterCriticalSection( &joystick_cs );
- return SendDriverMessage( joysticks[id].driver, JDD_GETPOSEX, (LPARAM)info, 0 );
- if (!(device = joysticks[id].device) && (ticks - joysticks[id].last_check) >= 2000)
- {
joysticks[id].last_check = ticks;
find_joysticks();
- }
- if (!(device = joysticks[id].device))
res = JOYERR_PARMS;
- else if (FAILED(hr = IDirectInputDevice8_GetDeviceState( device, sizeof(struct joystick_state), &state )))
- {
WARN( "GetDeviceState device %p returned %#x\n", device, hr );
res = JOYERR_PARMS;
- }
- else
- {
if (info->dwFlags & JOY_RETURNX) info->dwXpos = state.x;
if (info->dwFlags & JOY_RETURNY) info->dwYpos = state.y;
if (info->dwFlags & JOY_RETURNZ) info->dwZpos = state.z;
if (info->dwFlags & JOY_RETURNR) info->dwRpos = state.r;
if (info->dwFlags & JOY_RETURNU) info->dwUpos = state.u;
if (info->dwFlags & JOY_RETURNV) info->dwVpos = state.v;
if (info->dwFlags & JOY_RETURNPOV)
{
if (state.pov == ~0) info->dwPOV = 0xffff;
else info->dwPOV = state.pov;
}
if (info->dwFlags & JOY_RETURNBUTTONS)
{
info->dwButtonNumber = info->dwButtons = 0;
for (i = 0; i < ARRAY_SIZE(state.buttons); ++i)
{
if (!state.buttons[i]) continue;
info->dwButtonNumber++;
info->dwButtons |= 1 << i;
}
}
- }
- LeaveCriticalSection( &joystick_cs );
- return res;
}
/************************************************************************** @@ -313,7 +564,6 @@ MMRESULT WINAPI joyReleaseCapture( UINT id ) TRACE( "id %u.\n", id );
if (id >= ARRAY_SIZE(joysticks)) return JOYERR_PARMS;
if (!JOY_LoadDriver( id )) return MMSYSERR_NODRIVER;
EnterCriticalSection( &joystick_cs );
@@ -343,7 +593,6 @@ MMRESULT WINAPI joySetCapture( HWND hwnd, UINT id, UINT period, BOOL changed ) if (id >= ARRAY_SIZE(joysticks) || hwnd == 0) return JOYERR_PARMS; if (period < JOY_PERIOD_MIN) period = JOY_PERIOD_MIN; else if (period > JOY_PERIOD_MAX) period = JOY_PERIOD_MAX;
if (!JOY_LoadDriver( id )) return MMSYSERR_NODRIVER;
EnterCriticalSection( &joystick_cs );
diff --git a/dlls/winmm/winemm.h b/dlls/winmm/winemm.h index d7bab0f531d..3459c2a85ef 100644 --- a/dlls/winmm/winemm.h +++ b/dlls/winmm/winemm.h @@ -153,6 +153,9 @@ MMRESULT WINMM_CheckCallback(DWORD_PTR dwCallback, DWORD fdwOpen, BOOL mixer) DE
void WINMM_DeleteWaveform(void) DECLSPEC_HIDDEN;
+void joystick_load( HMODULE instance ) DECLSPEC_HIDDEN; +void joystick_unload( void ) DECLSPEC_HIDDEN;
/* Global variables */ extern CRITICAL_SECTION WINMM_cs DECLSPEC_HIDDEN; extern HINSTANCE hWinMM32Instance DECLSPEC_HIDDEN; diff --git a/dlls/winmm/winmm.c b/dlls/winmm/winmm.c index eea29ea61e5..aab8bfb51a9 100644 --- a/dlls/winmm/winmm.c +++ b/dlls/winmm/winmm.c @@ -145,11 +145,13 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID fImpLoad) if (!WINMM_CreateIData(hInstDLL)) return FALSE;
joystick_load( hInstDLL ); break;
case DLL_PROCESS_DETACH: if(fImpLoad) break;
joystick_unload(); MCI_SendCommand(MCI_ALL_DEVICE_ID, MCI_CLOSE, MCI_WAIT, 0L); MMDRV_Exit(); DRIVER_UnloadAll();
-- 2.34.0
Rémi Bernon rbernon@codeweavers.com writes:
Based on a patch from Zebediah Figura zfigura@codeweavers.com.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com
dlls/dinput8/tests/hid.c | 51 ------ dlls/winmm/Makefile.in | 2 +- dlls/winmm/joystick.c | 355 +++++++++++++++++++++++++++++++++------ dlls/winmm/winemm.h | 3 + dlls/winmm/winmm.c | 2 + 5 files changed, 308 insertions(+), 105 deletions(-)
This is causing a deadlock in the tests:
tools/runtest -q -P wine -T . -M dplayx.dll -p dlls/dplayx/tests/dplayx_test.exe dplayx && touch dlls/dplayx/tests/dplayx.ok dplayx.c:6945: Tests skipped: Run in interactive mode to run all dplayx tests. 00fc:err:sync:RtlpWaitForCriticalSection section 7BC64440 "dlls/ntdll/loader.c: loader_section" wait timed out in thread 00fc, blocked by 0024, retrying (60 sec) 00fc:err:sync:RtlpWaitForCriticalSection section 7BC64440 "dlls/ntdll/loader.c: loader_section" wait timed out in thread 00fc, blocked by 0024, retrying (60 sec) ...
On 12/9/21 17:11, Alexandre Julliard wrote:
Rémi Bernon rbernon@codeweavers.com writes:
Based on a patch from Zebediah Figura zfigura@codeweavers.com.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com
dlls/dinput8/tests/hid.c | 51 ------ dlls/winmm/Makefile.in | 2 +- dlls/winmm/joystick.c | 355 +++++++++++++++++++++++++++++++++------ dlls/winmm/winemm.h | 3 + dlls/winmm/winmm.c | 2 + 5 files changed, 308 insertions(+), 105 deletions(-)
This is causing a deadlock in the tests:
tools/runtest -q -P wine -T . -M dplayx.dll -p dlls/dplayx/tests/dplayx_test.exe dplayx && touch dlls/dplayx/tests/dplayx.ok dplayx.c:6945: Tests skipped: Run in interactive mode to run all dplayx tests. 00fc:err:sync:RtlpWaitForCriticalSection section 7BC64440 "dlls/ntdll/loader.c: loader_section" wait timed out in thread 00fc, blocked by 0024, retrying (60 sec) 00fc:err:sync:RtlpWaitForCriticalSection section 7BC64440 "dlls/ntdll/loader.c: loader_section" wait timed out in thread 00fc, blocked by 0024, retrying (60 sec) ...
Crap, sorry, looks like this will require some changes in dinput internal thread shutdown. Maybe the first patches are fine, and hopefully I'll have something for tomorrow?
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- configure.ac | 2 - dlls/winejoystick.drv/Makefile.in | 10 - dlls/winejoystick.drv/joystick.c | 52 -- dlls/winejoystick.drv/joystick.h | 34 - dlls/winejoystick.drv/joystick_linux.c | 462 ---------- dlls/winejoystick.drv/joystick_osx.c | 935 -------------------- dlls/winejoystick.drv/winejoystick.drv.spec | 1 - tools/winapi/win32.api | 13 - 8 files changed, 1509 deletions(-) delete mode 100644 dlls/winejoystick.drv/Makefile.in delete mode 100644 dlls/winejoystick.drv/joystick.c delete mode 100644 dlls/winejoystick.drv/joystick.h delete mode 100644 dlls/winejoystick.drv/joystick_linux.c delete mode 100644 dlls/winejoystick.drv/joystick_osx.c delete mode 100644 dlls/winejoystick.drv/winejoystick.drv.spec
diff --git a/configure.ac b/configure.ac index 2fe4b186fd6..328f80f17c9 100644 --- a/configure.ac +++ b/configure.ac @@ -899,7 +899,6 @@ esac enable_winecoreaudio_drv=${enable_winecoreaudio_drv:-no} enable_wineandroid_drv=${enable_wineandroid_drv:-no} enable_winemac_drv=${enable_winemac_drv:-no} -test "$ac_cv_header_linux_joystick_h" = "yes" -o "$ac_cv_header_IOKit_hid_IOHIDLib_h" = "yes" || enable_winejoystick_drv=${enable_winejoystick_drv:-no}
dnl Check for cross compiler to build test programs AC_SUBST(CROSSTARGET) @@ -3488,7 +3487,6 @@ WINE_CONFIG_MAKEFILE(dlls/winecrt0) WINE_CONFIG_MAKEFILE(dlls/wined3d) WINE_CONFIG_MAKEFILE(dlls/winegstreamer) WINE_CONFIG_MAKEFILE(dlls/winehid.sys) -WINE_CONFIG_MAKEFILE(dlls/winejoystick.drv) WINE_CONFIG_MAKEFILE(dlls/winemac.drv) WINE_CONFIG_MAKEFILE(dlls/winemapi) WINE_CONFIG_MAKEFILE(dlls/wineoss.drv) diff --git a/dlls/winejoystick.drv/Makefile.in b/dlls/winejoystick.drv/Makefile.in deleted file mode 100644 index 52564855994..00000000000 --- a/dlls/winejoystick.drv/Makefile.in +++ /dev/null @@ -1,10 +0,0 @@ -MODULE = winejoystick.drv -IMPORTS = winmm user32 -EXTRALIBS = $(IOKIT_LIBS) - -EXTRADLLFLAGS = -mcygwin - -C_SRCS = \ - joystick.c \ - joystick_linux.c \ - joystick_osx.c diff --git a/dlls/winejoystick.drv/joystick.c b/dlls/winejoystick.drv/joystick.c deleted file mode 100644 index 3e140b91175..00000000000 --- a/dlls/winejoystick.drv/joystick.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * WinMM joystick driver common code - * - * Copyright 1997 Andreas Mohr - * Copyright 2000 Wolfgang Schwotzer - * Copyright 2002 David Hagood - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "joystick.h" - - -/************************************************************************** - * DriverProc (JOYSTICK.@) - */ -LRESULT CALLBACK JSTCK_DriverProc(DWORD_PTR dwDevID, HDRVR hDriv, UINT wMsg, LPARAM dwParam1, LPARAM dwParam2) -{ - switch(wMsg) { - case DRV_LOAD: return 1; - case DRV_FREE: return 1; - case DRV_OPEN: return driver_open((LPSTR)dwParam1, dwParam2); - case DRV_CLOSE: return driver_close(dwDevID); - case DRV_ENABLE: return 1; - case DRV_DISABLE: return 1; - case DRV_QUERYCONFIGURE: return 1; - case DRV_CONFIGURE: MessageBoxA(0, "JoyStick MultiMedia Driver !", "JoyStick Driver", MB_OK); return 1; - case DRV_INSTALL: return DRVCNF_RESTART; - case DRV_REMOVE: return DRVCNF_RESTART; - - case JDD_GETNUMDEVS: return 1; - case JDD_GETDEVCAPS: return driver_joyGetDevCaps(dwDevID, (LPJOYCAPSW)dwParam1, dwParam2); - case JDD_GETPOS: return driver_joyGetPos(dwDevID, (LPJOYINFO)dwParam1); - case JDD_SETCALIBRATION: - case JDD_CONFIGCHANGED: return JOYERR_NOCANDO; - case JDD_GETPOSEX: return driver_joyGetPosEx(dwDevID, (LPJOYINFOEX)dwParam1); - default: - return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2); - } -} diff --git a/dlls/winejoystick.drv/joystick.h b/dlls/winejoystick.drv/joystick.h deleted file mode 100644 index 1ec1edb8133..00000000000 --- a/dlls/winejoystick.drv/joystick.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * WinMM joystick driver header - * - * Copyright 2015 Ken Thomases for CodeWeavers Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - - -#include <stdarg.h> - -#include "windef.h" -#include "winbase.h" -#include "mmddk.h" -#include "winuser.h" - - -LRESULT driver_open(LPSTR str, DWORD index) DECLSPEC_HIDDEN; -LRESULT driver_close(DWORD_PTR device_id) DECLSPEC_HIDDEN; -LRESULT driver_joyGetDevCaps(DWORD_PTR device_id, JOYCAPSW* caps, DWORD size) DECLSPEC_HIDDEN; -LRESULT driver_joyGetPosEx(DWORD_PTR device_id, JOYINFOEX* info) DECLSPEC_HIDDEN; -LRESULT driver_joyGetPos(DWORD_PTR device_id, JOYINFO* info) DECLSPEC_HIDDEN; diff --git a/dlls/winejoystick.drv/joystick_linux.c b/dlls/winejoystick.drv/joystick_linux.c deleted file mode 100644 index 7fd2c95aff1..00000000000 --- a/dlls/winejoystick.drv/joystick_linux.c +++ /dev/null @@ -1,462 +0,0 @@ -/* - * joystick functions - * - * Copyright 1997 Andreas Mohr - * Copyright 2000 Wolfgang Schwotzer - * Copyright 2002 David Hagood - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - * - * NOTES: - * - * - nearly all joystick functions can be regarded as obsolete, - * as Linux (2.1.x) now supports extended joysticks with a completely - * new joystick driver interface - * New driver's documentation says: - * "For backward compatibility the old interface is still included, - * but will be dropped in the future." - * Thus we should implement the new interface and at most keep the old - * routines for backward compatibility. - * - better support of enhanced joysticks (Linux 2.2 interface is available) - * - support more joystick drivers (like the XInput extension) - * - should load joystick DLL as any other driver (instead of hardcoding) - * the driver's name, and load it as any low lever driver. - */ - -#include "config.h" - -#ifdef HAVE_LINUX_22_JOYSTICK_API - -#ifdef HAVE_UNISTD_H -# include <unistd.h> -#endif -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <fcntl.h> -#ifdef HAVE_SYS_IOCTL_H -#include <sys/ioctl.h> -#endif -#ifdef HAVE_LINUX_IOCTL_H -#include <linux/ioctl.h> -#endif -#include <linux/joystick.h> -#ifdef SW_MAX -#undef SW_MAX -#endif -#define JOYDEV_NEW "/dev/input/js%d" -#define JOYDEV_OLD "/dev/js%d" -#include <errno.h> - -#include "joystick.h" - -#include "wingdi.h" -#include "winnls.h" -#include "wine/debug.h" - -WINE_DEFAULT_DEBUG_CHANNEL(joystick); - -#define MAXJOYSTICK (JOYSTICKID2 + 30) - -typedef struct tagWINE_JSTCK { - int joyIntf; - BOOL in_use; - /* Some extra info we need to make this actually work under the - Linux 2.2 event api. - First of all, we cannot keep closing and reopening the device file - - that blows away the state of the stick device, and we lose events. So, we - need to open the low-level device once, and close it when we are done. - - Secondly, the event API only gives us what's changed. However, Windows apps - want the whole state every time, so we have to cache the data. - */ - - int dev; /* Linux level device file descriptor */ - int x; - int y; - int z; - int r; - int u; - int v; - int pov_x; - int pov_y; - int buttons; - char axesMap[ABS_MAX + 1]; -} WINE_JSTCK; - -static WINE_JSTCK JSTCK_Data[MAXJOYSTICK]; - -/************************************************************************** - * JSTCK_drvGet [internal] - */ -static WINE_JSTCK *JSTCK_drvGet(DWORD_PTR dwDevID) -{ - int p; - - if ((dwDevID - (DWORD_PTR)JSTCK_Data) % sizeof(JSTCK_Data[0]) != 0) - return NULL; - p = (dwDevID - (DWORD_PTR)JSTCK_Data) / sizeof(JSTCK_Data[0]); - if (p < 0 || p >= MAXJOYSTICK || !((WINE_JSTCK*)dwDevID)->in_use) - return NULL; - - return (WINE_JSTCK*)dwDevID; -} - -/************************************************************************** - * driver_open - */ -LRESULT driver_open(LPSTR str, DWORD dwIntf) -{ - if (dwIntf >= MAXJOYSTICK || JSTCK_Data[dwIntf].in_use) - return 0; - - JSTCK_Data[dwIntf].joyIntf = dwIntf; - JSTCK_Data[dwIntf].dev = -1; - JSTCK_Data[dwIntf].in_use = TRUE; - return (LRESULT)&JSTCK_Data[dwIntf]; -} - -/************************************************************************** - * driver_close - */ -LRESULT driver_close(DWORD_PTR dwDevID) -{ - WINE_JSTCK* jstck = JSTCK_drvGet(dwDevID); - - if (jstck == NULL) - return 0; - jstck->in_use = FALSE; - if (jstck->dev > 0) - { - close(jstck->dev); - jstck->dev = 0; - } - return 1; -} - -struct js_status -{ - int buttons; - int x; - int y; -}; - -/************************************************************************** - * JSTCK_OpenDevice [internal] - */ -static int JSTCK_OpenDevice(WINE_JSTCK* jstick) -{ - char buf[20]; - int flags, fd, found_ix, i; - static DWORD last_attempt; - DWORD now; - - if (jstick->dev > 0) - return jstick->dev; - - now = GetTickCount(); - if (now - last_attempt < 2000) - return -1; - last_attempt = now; - - flags = O_RDONLY | O_NONBLOCK; - - /* The first joystick may not be at /dev/input/js0, find the correct - * first or second device. For example the driver for XBOX 360 wireless - * receiver creates entries starting at 20. - */ - for (found_ix = i = 0; i < MAXJOYSTICK; i++) { - sprintf(buf, JOYDEV_NEW, i); - if ((fd = open(buf, flags)) < 0) { - sprintf(buf, JOYDEV_OLD, i); - if ((fd = open(buf, flags)) < 0) - continue; - } - - if (found_ix++ == jstick->joyIntf) - { - TRACE("Found joystick[%d] at %s\n", jstick->joyIntf, buf); - jstick->dev = fd; - last_attempt = 0; - break; - } - - close(fd); - } - - if (jstick->dev > 0) - ioctl(jstick->dev, JSIOCGAXMAP, jstick->axesMap); - - return jstick->dev; -} - - -/************************************************************************** - * JoyGetDevCaps [MMSYSTEM.102] - */ -LRESULT driver_joyGetDevCaps(DWORD_PTR dwDevID, LPJOYCAPSW lpCaps, DWORD dwSize) -{ - WINE_JSTCK* jstck; - int dev; - char nrOfAxes; - char nrOfButtons; - char identString[MAXPNAMELEN]; - int i; - int driverVersion; - - if ((jstck = JSTCK_drvGet(dwDevID)) == NULL) - return MMSYSERR_NODRIVER; - - if ((dev = JSTCK_OpenDevice(jstck)) < 0) return JOYERR_PARMS; - ioctl(dev, JSIOCGAXES, &nrOfAxes); - ioctl(dev, JSIOCGBUTTONS, &nrOfButtons); - ioctl(dev, JSIOCGVERSION, &driverVersion); - ioctl(dev, JSIOCGNAME(sizeof(identString)), identString); - TRACE("Driver: 0x%06x, Name: %s, #Axes: %d, #Buttons: %d\n", - driverVersion, identString, nrOfAxes, nrOfButtons); - lpCaps->wMid = MM_MICROSOFT; - lpCaps->wPid = MM_PC_JOYSTICK; - MultiByteToWideChar(CP_UNIXCP, 0, identString, -1, lpCaps->szPname, MAXPNAMELEN); - lpCaps->szPname[MAXPNAMELEN-1] = '\0'; - lpCaps->wXmin = 0; - lpCaps->wXmax = 0xFFFF; - lpCaps->wYmin = 0; - lpCaps->wYmax = 0xFFFF; - lpCaps->wZmin = 0; - lpCaps->wZmax = (nrOfAxes >= 3) ? 0xFFFF : 0; -#ifdef BODGE_THE_HAT - /* Half-Life won't allow you to map an axis event to things like - "next weapon" and "use". Linux reports the hat on my stick as - axis U and V. So, IFF BODGE_THE_HAT is defined, lie through our - teeth and say we have 32 buttons, and we will map the axes to - the high buttons. Really, perhaps this should be a registry entry, - or even a parameter to the Linux joystick driver (which would completely - remove the need for this.) - */ - lpCaps->wNumButtons = 32; -#else - lpCaps->wNumButtons = nrOfButtons; -#endif - if (dwSize == sizeof(JOYCAPSW)) { - /* complete 95 structure */ - lpCaps->wRmin = 0; - lpCaps->wRmax = 0xFFFF; - lpCaps->wUmin = 0; - lpCaps->wUmax = 0xFFFF; - lpCaps->wVmin = 0; - lpCaps->wVmax = 0xFFFF; - lpCaps->wMaxAxes = 6; /* same as MS Joystick Driver */ - lpCaps->wNumAxes = 0; /* nr of axes in use */ - lpCaps->wMaxButtons = 32; /* same as MS Joystick Driver */ - lpCaps->szRegKey[0] = 0; - lpCaps->szOEMVxD[0] = 0; - lpCaps->wCaps = 0; - for (i = 0; i < nrOfAxes; i++) { - switch (jstck->axesMap[i]) { - case 0: /* X */ - case 1: /* Y */ - case 8: /* Wheel */ - case 9: /* Gas */ - lpCaps->wNumAxes++; - break; - case 2: /* Z */ - case 6: /* Throttle */ - case 10: /* Brake */ - lpCaps->wNumAxes++; - lpCaps->wCaps |= JOYCAPS_HASZ; - break; - case 5: /* Rz */ - case 7: /* Rudder */ - lpCaps->wNumAxes++; - lpCaps->wCaps |= JOYCAPS_HASR; - break; - case 3: /* Rx */ - lpCaps->wNumAxes++; - lpCaps->wCaps |= JOYCAPS_HASU; - break; - case 4: /* Ry */ - lpCaps->wNumAxes++; - lpCaps->wCaps |= JOYCAPS_HASV; - break; - case 16: /* Hat 0 X */ - case 17: /* Hat 0 Y */ - lpCaps->wCaps |= JOYCAPS_HASPOV | JOYCAPS_POV4DIR; - /* TODO: JOYCAPS_POVCTS handling */ - break; - default: - WARN("Unknown axis %hhu(%u). Skipped.\n", jstck->axesMap[i], i); - } - } - } - - return JOYERR_NOERROR; -} - -/************************************************************************** - * driver_joyGetPos - */ -LRESULT driver_joyGetPosEx(DWORD_PTR dwDevID, LPJOYINFOEX lpInfo) -{ - WINE_JSTCK* jstck; - int dev; - struct js_event ev; - - if ((jstck = JSTCK_drvGet(dwDevID)) == NULL) - return MMSYSERR_NODRIVER; - - if ((dev = JSTCK_OpenDevice(jstck)) < 0) return JOYERR_PARMS; - - while ((read(dev, &ev, sizeof(struct js_event))) > 0) { - if (ev.type == (JS_EVENT_AXIS)) { - switch (jstck->axesMap[ev.number]) { - case 0: /* X */ - case 8: /* Wheel */ - jstck->x = ev.value; - break; - case 1: /* Y */ - case 9: /* Gas */ - jstck->y = ev.value; - break; - case 2: /* Z */ - case 6: /* Throttle */ - case 10: /* Brake */ - jstck->z = ev.value; - break; - case 5: /* Rz */ - case 7: /* Rudder */ - jstck->r = ev.value; - break; - case 3: /* Rx */ - jstck->u = ev.value; - break; - case 4: /* Ry */ - jstck->v = ev.value; - break; - case 16: /* Hat 0 X */ - jstck->pov_x = ev.value; - break; - case 17: /* Hat 0 Y */ - jstck->pov_y = ev.value; - break; - default: - FIXME("Unknown joystick event '%d'\n", ev.number); - } - } else if (ev.type == (JS_EVENT_BUTTON)) { - if (ev.value) { - jstck->buttons |= (1 << ev.number); - /* FIXME: what to do for this field when - * multiple buttons are depressed ? - */ - if (lpInfo->dwFlags & JOY_RETURNBUTTONS) - lpInfo->dwButtonNumber = ev.number + 1; - } - else - jstck->buttons &= ~(1 << ev.number); - } - } - /* EAGAIN is returned when the queue is empty */ - if (errno != EAGAIN) { - /* FIXME: error should not be ignored */ - ERR("Error while reading joystick state (%s)\n", strerror(errno)); - } - /* Now, copy the cached values into Window's structure... */ - if (lpInfo->dwFlags & JOY_RETURNBUTTONS) - lpInfo->dwButtons = jstck->buttons; - if (lpInfo->dwFlags & JOY_RETURNX) - lpInfo->dwXpos = jstck->x + 32767; - if (lpInfo->dwFlags & JOY_RETURNY) - lpInfo->dwYpos = jstck->y + 32767; - if (lpInfo->dwFlags & JOY_RETURNZ) - lpInfo->dwZpos = jstck->z + 32767; - if (lpInfo->dwFlags & JOY_RETURNR) - lpInfo->dwRpos = jstck->r + 32767; -# ifdef BODGE_THE_HAT - else if (lpInfo->dwFlags & JOY_RETURNBUTTONS) - { - if (jstck->r > 0) - lpInfo->dwButtons |= 1<<7; - else if (jstck->r < 0) - lpInfo->dwButtons |= 1<<8; - } -# endif - if (lpInfo->dwFlags & JOY_RETURNU) - lpInfo->dwUpos = jstck->u + 32767; -# ifdef BODGE_THE_HAT - else if (lpInfo->dwFlags & JOY_RETURNBUTTONS) - { - if (jstck->u > 0) - lpInfo->dwButtons |= 1<<9; - else if (jstck->u < 0) - lpInfo->dwButtons |= 1<<10; - } -# endif - if (lpInfo->dwFlags & JOY_RETURNV) - lpInfo->dwVpos = jstck->v + 32767; - if (lpInfo->dwFlags & JOY_RETURNPOV) { - if (jstck->pov_y > 0) { - if (jstck->pov_x < 0) - lpInfo->dwPOV = 22500; /* SW */ - else if (jstck->pov_x > 0) - lpInfo->dwPOV = 13500; /* SE */ - else - lpInfo->dwPOV = 18000; /* S, JOY_POVBACKWARD */ - } else if (jstck->pov_y < 0) { - if (jstck->pov_x < 0) - lpInfo->dwPOV = 31500; /* NW */ - else if (jstck->pov_x > 0) - lpInfo->dwPOV = 4500; /* NE */ - else - lpInfo->dwPOV = 0; /* N, JOY_POVFORWARD */ - } else if (jstck->pov_x < 0) - lpInfo->dwPOV = 27000; /* W, JOY_POVLEFT */ - else if (jstck->pov_x > 0) - lpInfo->dwPOV = 9000; /* E, JOY_POVRIGHT */ - else - lpInfo->dwPOV = JOY_POVCENTERED; /* Center */ - } - - TRACE("x: %d, y: %d, z: %d, r: %d, u: %d, v: %d, buttons: 0x%04x, flags: 0x%04x (fd %d)\n", - lpInfo->dwXpos, lpInfo->dwYpos, lpInfo->dwZpos, - lpInfo->dwRpos, lpInfo->dwUpos, lpInfo->dwVpos, - lpInfo->dwButtons, lpInfo->dwFlags, dev - ); - - return JOYERR_NOERROR; -} - -/************************************************************************** - * driver_joyGetPos - */ -LRESULT driver_joyGetPos(DWORD_PTR dwDevID, LPJOYINFO lpInfo) -{ - JOYINFOEX ji; - LONG ret; - - memset(&ji, 0, sizeof(ji)); - - ji.dwSize = sizeof(ji); - ji.dwFlags = JOY_RETURNX | JOY_RETURNY | JOY_RETURNZ | JOY_RETURNBUTTONS; - ret = driver_joyGetPosEx(dwDevID, &ji); - if (ret == JOYERR_NOERROR) { - lpInfo->wXpos = ji.dwXpos; - lpInfo->wYpos = ji.dwYpos; - lpInfo->wZpos = ji.dwZpos; - lpInfo->wButtons = ji.dwButtons; - } - - return ret; -} - -#endif /* HAVE_LINUX_JOYSTICK_H */ diff --git a/dlls/winejoystick.drv/joystick_osx.c b/dlls/winejoystick.drv/joystick_osx.c deleted file mode 100644 index 6f53477937f..00000000000 --- a/dlls/winejoystick.drv/joystick_osx.c +++ /dev/null @@ -1,935 +0,0 @@ -/* - * WinMM joystick driver OS X implementation - * - * Copyright 1997 Andreas Mohr - * Copyright 1998 Marcus Meissner - * Copyright 1998,1999 Lionel Ulmer - * Copyright 2000 Wolfgang Schwotzer - * Copyright 2000-2001 TransGaming Technologies Inc. - * Copyright 2002 David Hagood - * Copyright 2009 CodeWeavers, Aric Stewart - * Copyright 2015 Ken Thomases for CodeWeavers Inc. - * Copyright 2016 David Lawrie - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "config.h" - -#if defined(HAVE_IOKIT_HID_IOHIDLIB_H) - -#define DWORD UInt32 -#define LPDWORD UInt32* -#define LONG SInt32 -#define LPLONG SInt32* -#define E_PENDING __carbon_E_PENDING -#define ULONG __carbon_ULONG -#define E_INVALIDARG __carbon_E_INVALIDARG -#define E_OUTOFMEMORY __carbon_E_OUTOFMEMORY -#define E_HANDLE __carbon_E_HANDLE -#define E_ACCESSDENIED __carbon_E_ACCESSDENIED -#define E_UNEXPECTED __carbon_E_UNEXPECTED -#define E_FAIL __carbon_E_FAIL -#define E_ABORT __carbon_E_ABORT -#define E_POINTER __carbon_E_POINTER -#define E_NOINTERFACE __carbon_E_NOINTERFACE -#define E_NOTIMPL __carbon_E_NOTIMPL -#define S_FALSE __carbon_S_FALSE -#define S_OK __carbon_S_OK -#define HRESULT_FACILITY __carbon_HRESULT_FACILITY -#define IS_ERROR __carbon_IS_ERROR -#define FAILED __carbon_FAILED -#define SUCCEEDED __carbon_SUCCEEDED -#define MAKE_HRESULT __carbon_MAKE_HRESULT -#define HRESULT __carbon_HRESULT -#define STDMETHODCALLTYPE __carbon_STDMETHODCALLTYPE -#include <IOKit/IOKitLib.h> -#include <IOKit/hid/IOHIDLib.h> -#undef ULONG -#undef E_INVALIDARG -#undef E_OUTOFMEMORY -#undef E_HANDLE -#undef E_ACCESSDENIED -#undef E_UNEXPECTED -#undef E_FAIL -#undef E_ABORT -#undef E_POINTER -#undef E_NOINTERFACE -#undef E_NOTIMPL -#undef S_FALSE -#undef S_OK -#undef HRESULT_FACILITY -#undef IS_ERROR -#undef FAILED -#undef SUCCEEDED -#undef MAKE_HRESULT -#undef HRESULT -#undef STDMETHODCALLTYPE -#undef DWORD -#undef LPDWORD -#undef LONG -#undef LPLONG -#undef E_PENDING - -#include "joystick.h" - -#include "wine/debug.h" - - -WINE_DEFAULT_DEBUG_CHANNEL(joystick); - - -#define MAXJOYSTICK (JOYSTICKID2 + 30) - - -enum { - AXIS_X, /* Winmm X */ - AXIS_Y, /* Winmm Y */ - AXIS_Z, /* Winmm Z */ - AXIS_RX, /* Winmm V */ - AXIS_RY, /* Winmm U */ - AXIS_RZ, /* Winmm R */ - NUM_AXES -}; - -struct axis { - IOHIDElementRef element; - CFIndex min_value, max_value; -}; - -typedef struct { - BOOL in_use; - IOHIDElementRef element; - struct axis axes[NUM_AXES]; - CFMutableArrayRef buttons; - IOHIDElementRef hatswitch; -} joystick_t; - - -static joystick_t joysticks[MAXJOYSTICK]; -static CFMutableArrayRef device_main_elements = NULL; - -static long get_device_property_long(IOHIDDeviceRef device, CFStringRef key) -{ - CFTypeRef ref; - long result = 0; - - if (device) - { - assert(IOHIDDeviceGetTypeID() == CFGetTypeID(device)); - - ref = IOHIDDeviceGetProperty(device, key); - - if (ref && CFNumberGetTypeID() == CFGetTypeID(ref)) - CFNumberGetValue((CFNumberRef)ref, kCFNumberLongType, &result); - } - - return result; -} - -static CFStringRef copy_device_name(IOHIDDeviceRef device) -{ - CFStringRef name; - - if (device) - { - CFTypeRef ref_name; - - assert(IOHIDDeviceGetTypeID() == CFGetTypeID(device)); - - ref_name = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey)); - - if (ref_name && CFStringGetTypeID() == CFGetTypeID(ref_name)) - name = CFStringCreateCopy(kCFAllocatorDefault, ref_name); - else - { - long vendID, prodID; - - vendID = get_device_property_long(device, CFSTR(kIOHIDVendorIDKey)); - prodID = get_device_property_long(device, CFSTR(kIOHIDProductIDKey)); - name = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("0x%04lx 0x%04lx"), vendID, prodID); - } - } - else - { - ERR("NULL device\n"); - name = CFStringCreateCopy(kCFAllocatorDefault, CFSTR("")); - } - - return name; -} - -static long get_device_location_ID(IOHIDDeviceRef device) -{ - return get_device_property_long(device, CFSTR(kIOHIDLocationIDKey)); -} - -static const char* debugstr_cf(CFTypeRef t) -{ - CFStringRef s; - const char* ret; - - if (!t) return "(null)"; - - if (CFGetTypeID(t) == CFStringGetTypeID()) - s = t; - else - s = CFCopyDescription(t); - ret = CFStringGetCStringPtr(s, kCFStringEncodingUTF8); - if (ret) ret = debugstr_a(ret); - if (!ret) - { - const UniChar* u = CFStringGetCharactersPtr(s); - if (u) - ret = debugstr_wn((const WCHAR*)u, CFStringGetLength(s)); - } - if (!ret) - { - UniChar buf[200]; - int len = min(CFStringGetLength(s), ARRAY_SIZE(buf)); - CFStringGetCharacters(s, CFRangeMake(0, len), buf); - ret = debugstr_wn(buf, len); - } - if (s != t) CFRelease(s); - return ret; -} - -static const char* debugstr_device(IOHIDDeviceRef device) -{ - return wine_dbg_sprintf("<IOHIDDevice %p product %s IOHIDLocationID %lu>", device, - debugstr_cf(IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey))), - get_device_location_ID(device)); -} - -static const char* debugstr_element(IOHIDElementRef element) -{ - return wine_dbg_sprintf("<IOHIDElement %p type %d usage %u/%u device %p>", element, - IOHIDElementGetType(element), IOHIDElementGetUsagePage(element), - IOHIDElementGetUsage(element), IOHIDElementGetDevice(element)); -} - -static int axis_for_usage_GD(int usage) -{ - switch (usage) - { - case kHIDUsage_GD_X: return AXIS_X; - case kHIDUsage_GD_Y: return AXIS_Y; - case kHIDUsage_GD_Z: return AXIS_Z; - case kHIDUsage_GD_Rx: return AXIS_RX; - case kHIDUsage_GD_Ry: return AXIS_RY; - case kHIDUsage_GD_Rz: return AXIS_RZ; - } - - return -1; -} - -static int axis_for_usage_Sim(int usage) -{ - switch (usage) - { - case kHIDUsage_Sim_Rudder: return AXIS_RZ; - case kHIDUsage_Sim_Throttle: return AXIS_Z; - case kHIDUsage_Sim_Steering: return AXIS_X; - case kHIDUsage_Sim_Accelerator: return AXIS_Y; - case kHIDUsage_Sim_Brake: return AXIS_RZ; - } - - return -1; -} - -/************************************************************************** - * joystick_from_id - */ -static joystick_t* joystick_from_id(DWORD_PTR device_id) -{ - int index; - - if ((device_id - (DWORD_PTR)joysticks) % sizeof(joysticks[0]) != 0) - return NULL; - index = (device_id - (DWORD_PTR)joysticks) / sizeof(joysticks[0]); - if (index < 0 || index >= MAXJOYSTICK || !((joystick_t*)device_id)->in_use) - return NULL; - - return (joystick_t*)device_id; -} - -/************************************************************************** - * create_osx_device_match - */ -static CFDictionaryRef create_osx_device_match(int usage) -{ - CFDictionaryRef result = NULL; - int number; - CFStringRef keys[] = { CFSTR(kIOHIDDeviceUsagePageKey), CFSTR(kIOHIDDeviceUsageKey) }; - CFNumberRef values[2]; - int i; - - TRACE("usage %d\n", usage); - - number = kHIDPage_GenericDesktop; - values[0] = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &number); - values[1] = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usage); - - if (values[0] && values[1]) - { - result = CFDictionaryCreate(NULL, (const void**)keys, (const void**)values, ARRAY_SIZE(values), - &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - - if (!result) - ERR("CFDictionaryCreate failed.\n"); - } - else - ERR("CFNumberCreate failed.\n"); - - for (i = 0; i < ARRAY_SIZE(values); i++) - if (values[i]) CFRelease(values[i]); - - return result; -} - -/************************************************************************** - * find_top_level - */ -static CFIndex find_top_level(IOHIDDeviceRef hid_device, CFMutableArrayRef main_elements) -{ - CFArrayRef elements; - CFIndex total = 0; - - TRACE("hid_device %s\n", debugstr_device(hid_device)); - - if (!hid_device) - return 0; - - elements = IOHIDDeviceCopyMatchingElements(hid_device, NULL, 0); - - if (elements) - { - CFIndex i, count = CFArrayGetCount(elements); - for (i = 0; i < count; i++) - { - IOHIDElementRef element = (IOHIDElementRef)CFArrayGetValueAtIndex(elements, i); - int type = IOHIDElementGetType(element); - - TRACE("element %s\n", debugstr_element(element)); - - /* Check for top-level gaming device collections */ - if (type == kIOHIDElementTypeCollection && IOHIDElementGetParent(element) == 0) - { - int usage_page = IOHIDElementGetUsagePage(element); - int usage = IOHIDElementGetUsage(element); - - if (usage_page == kHIDPage_GenericDesktop && - (usage == kHIDUsage_GD_Joystick || usage == kHIDUsage_GD_GamePad || usage == kHIDUsage_GD_MultiAxisController)) - { - CFArrayAppendValue(main_elements, element); - total++; - } - } - } - CFRelease(elements); - } - - TRACE("-> total %d\n", (int)total); - return total; -} -/************************************************************************** - * device_name_comparator - * - * Virtual joysticks may not have a kIOHIDLocationIDKey and will default to location ID of 0, this orders virtual joysticks by their name - */ -static CFComparisonResult device_name_comparator(IOHIDDeviceRef device1, IOHIDDeviceRef device2) -{ - CFStringRef name1 = copy_device_name(device1), name2 = copy_device_name(device2); - CFComparisonResult result = CFStringCompare(name1, name2, (kCFCompareForcedOrdering | kCFCompareNumerically)); - CFRelease(name1); - CFRelease(name2); - return result; -} - -/************************************************************************** - * device_location_name_comparator - * - * Helper to sort device array first by location ID, since location IDs are consistent across boots & launches, then by product name - */ -static CFComparisonResult device_location_name_comparator(const void *val1, const void *val2, void *context) -{ - IOHIDDeviceRef device1 = (IOHIDDeviceRef)val1, device2 = (IOHIDDeviceRef)val2; - long loc1 = get_device_location_ID(device1), loc2 = get_device_location_ID(device2); - - if (loc1 < loc2) - return kCFCompareLessThan; - else if (loc1 > loc2) - return kCFCompareGreaterThan; - return device_name_comparator(device1, device2); -} - -/************************************************************************** - * copy_set_to_array - * - * Helper to copy the CFSet to a CFArray - */ -static void copy_set_to_array(const void *value, void *context) -{ - CFArrayAppendValue(context, value); -} - -/************************************************************************** - * find_osx_devices - */ -static int find_osx_devices(void) -{ - IOHIDManagerRef hid_manager; - int usages[] = { kHIDUsage_GD_Joystick, kHIDUsage_GD_GamePad, kHIDUsage_GD_MultiAxisController }; - int i; - CFDictionaryRef matching_dicts[ARRAY_SIZE(usages)]; - CFArrayRef matching; - CFSetRef devset; - - TRACE("()\n"); - - hid_manager = IOHIDManagerCreate(kCFAllocatorDefault, 0L); - if (IOHIDManagerOpen(hid_manager, 0) != kIOReturnSuccess) - { - ERR("Couldn't open IOHIDManager.\n"); - CFRelease(hid_manager); - return 0; - } - - for (i = 0; i < ARRAY_SIZE(matching_dicts); i++) - { - matching_dicts[i] = create_osx_device_match(usages[i]); - if (!matching_dicts[i]) - { - while (i > 0) - CFRelease(matching_dicts[--i]); - goto fail; - } - } - - matching = CFArrayCreate(NULL, (const void**)matching_dicts, ARRAY_SIZE(matching_dicts), - &kCFTypeArrayCallBacks); - - for (i = 0; i < ARRAY_SIZE(matching_dicts); i++) - CFRelease(matching_dicts[i]); - - IOHIDManagerSetDeviceMatchingMultiple(hid_manager, matching); - CFRelease(matching); - devset = IOHIDManagerCopyDevices(hid_manager); - if (devset) - { - CFIndex num_devices, num_main_elements; - CFMutableArrayRef devices; - - num_devices = CFSetGetCount(devset); - devices = CFArrayCreateMutable(kCFAllocatorDefault, num_devices, &kCFTypeArrayCallBacks); - CFSetApplyFunction(devset, copy_set_to_array, (void *)devices); - CFArraySortValues(devices, CFRangeMake(0, num_devices), device_location_name_comparator, NULL); - - CFRelease(devset); - if (!devices) - goto fail; - - device_main_elements = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); - if (!device_main_elements) - { - CFRelease(devices); - goto fail; - } - - num_main_elements = 0; - for (i = 0; i < num_devices; i++) - { - IOHIDDeviceRef hid_device = (IOHIDDeviceRef)CFArrayGetValueAtIndex(devices, i); - TRACE("hid_device %s\n", debugstr_device(hid_device)); - num_main_elements += find_top_level(hid_device, device_main_elements); - } - - CFRelease(devices); - - TRACE("found %i device(s), %i collection(s)\n",(int)num_devices,(int)num_main_elements); - return (int)num_main_elements; - } - -fail: - IOHIDManagerClose(hid_manager, 0); - CFRelease(hid_manager); - return 0; -} - -/************************************************************************** - * collect_joystick_elements - */ -static void collect_joystick_elements(joystick_t* joystick, IOHIDElementRef collection) -{ - CFIndex i, count; - CFArrayRef children = IOHIDElementGetChildren(collection); - - TRACE("collection %s\n", debugstr_element(collection)); - - count = CFArrayGetCount(children); - for (i = 0; i < count; i++) - { - IOHIDElementRef child; - int type; - uint32_t usage_page; - - child = (IOHIDElementRef)CFArrayGetValueAtIndex(children, i); - TRACE("child %s\n", debugstr_element(child)); - type = IOHIDElementGetType(child); - usage_page = IOHIDElementGetUsagePage(child); - - switch (type) - { - case kIOHIDElementTypeCollection: - collect_joystick_elements(joystick, child); - break; - case kIOHIDElementTypeInput_Button: - { - TRACE("kIOHIDElementTypeInput_Button usage_page %d\n", usage_page); - - /* avoid strange elements found on the 360 controller */ - if (usage_page == kHIDPage_Button) - CFArrayAppendValue(joystick->buttons, child); - break; - } - case kIOHIDElementTypeInput_Axis: - case kIOHIDElementTypeInput_Misc: - { - uint32_t usage = IOHIDElementGetUsage( child ); - switch (usage_page) - { - case kHIDPage_GenericDesktop: - { - switch(usage) - { - case kHIDUsage_GD_Hatswitch: - { - TRACE("kIOHIDElementTypeInput_Axis/Misc / kHIDUsage_GD_Hatswitch\n"); - if (joystick->hatswitch) - TRACE(" ignoring additional hatswitch\n"); - else - joystick->hatswitch = (IOHIDElementRef)CFRetain(child); - break; - } - case kHIDUsage_GD_X: - case kHIDUsage_GD_Y: - case kHIDUsage_GD_Z: - case kHIDUsage_GD_Rx: - case kHIDUsage_GD_Ry: - case kHIDUsage_GD_Rz: - { - int axis = axis_for_usage_GD(usage); - TRACE("kIOHIDElementTypeInput_Axis/Misc / kHIDUsage_GD_<axis> (%d) axis %d\n", usage, axis); - if (axis < 0 || joystick->axes[axis].element) - TRACE(" ignoring\n"); - else - { - joystick->axes[axis].element = (IOHIDElementRef)CFRetain(child); - joystick->axes[axis].min_value = IOHIDElementGetLogicalMin(child); - joystick->axes[axis].max_value = IOHIDElementGetLogicalMax(child); - } - break; - } - case kHIDUsage_GD_Slider: - case kHIDUsage_GD_Dial: - case kHIDUsage_GD_Wheel: - { - /* if one axis is taken, fall to the next until axes are filled */ - int possible_axes[3] = {AXIS_Z,AXIS_RY,AXIS_RX}; - int axis = 0; - while(axis < 3 && joystick->axes[possible_axes[axis]].element) - axis++; - if (axis == 3) - TRACE("kIOHIDElementTypeInput_Axis/Misc / kHIDUsage_GD_<axis> (%d)\n ignoring\n", usage); - else - { - TRACE("kIOHIDElementTypeInput_Axis/Misc / kHIDUsage_GD_<axis> (%d) axis %d\n", usage, possible_axes[axis]); - joystick->axes[possible_axes[axis]].element = (IOHIDElementRef)CFRetain(child); - joystick->axes[possible_axes[axis]].min_value = IOHIDElementGetLogicalMin(child); - joystick->axes[possible_axes[axis]].max_value = IOHIDElementGetLogicalMax(child); - } - break; - } - default: - FIXME("kIOHIDElementTypeInput_Axis/Misc / Unhandled GD Page usage %d\n", usage); - break; - } - break; - } - case kHIDPage_Simulation: - { - switch(usage) - { - case kHIDUsage_Sim_Rudder: - case kHIDUsage_Sim_Throttle: - case kHIDUsage_Sim_Steering: - case kHIDUsage_Sim_Accelerator: - case kHIDUsage_Sim_Brake: - { - int axis = axis_for_usage_Sim(usage); - TRACE("kIOHIDElementTypeInput_Axis/Misc / kHIDUsage_Sim_<axis> (%d) axis %d\n", usage, axis); - if (axis < 0 || joystick->axes[axis].element) - TRACE(" ignoring\n"); - else - { - joystick->axes[axis].element = (IOHIDElementRef)CFRetain(child); - joystick->axes[axis].min_value = IOHIDElementGetLogicalMin(child); - joystick->axes[axis].max_value = IOHIDElementGetLogicalMax(child); - } - break; - } - default: - FIXME("kIOHIDElementTypeInput_Axis/Misc / Unhandled Sim Page usage %d\n", usage); - break; - } - break; - } - default: - FIXME("kIOHIDElementTypeInput_Axis/Misc / Unhandled Usage Page %d\n", usage_page); - break; - } - break; - } - case kIOHIDElementTypeFeature: - /* Describes input and output elements not intended for consumption by the end user. Ignoring. */ - break; - default: - FIXME("Unhandled type %i\n",type); - break; - } - } -} - -/************************************************************************** - * button_usage_comparator - */ -static CFComparisonResult button_usage_comparator(const void *val1, const void *val2, void *context) -{ - IOHIDElementRef element1 = (IOHIDElementRef)val1, element2 = (IOHIDElementRef)val2; - int usage1 = IOHIDElementGetUsage(element1), usage2 = IOHIDElementGetUsage(element2); - - if (usage1 < usage2) - return kCFCompareLessThan; - if (usage1 > usage2) - return kCFCompareGreaterThan; - return kCFCompareEqualTo; -} - -/************************************************************************** - * driver_open - */ -LRESULT driver_open(LPSTR str, DWORD index) -{ - if (index >= MAXJOYSTICK || joysticks[index].in_use) - return 0; - - joysticks[index].in_use = TRUE; - return (LRESULT)&joysticks[index]; -} - -/************************************************************************** - * driver_close - */ -LRESULT driver_close(DWORD_PTR device_id) -{ - joystick_t* joystick = joystick_from_id(device_id); - int i; - - if (joystick == NULL) - return 0; - - CFRelease(joystick->element); - for (i = 0; i < NUM_AXES; i++) - { - if (joystick->axes[i].element) - CFRelease(joystick->axes[i].element); - } - if (joystick->buttons) - CFRelease(joystick->buttons); - if (joystick->hatswitch) - CFRelease(joystick->hatswitch); - - memset(joystick, 0, sizeof(*joystick)); - return 1; -} - -/************************************************************************** - * open_joystick - */ -static BOOL open_joystick(joystick_t* joystick) -{ - CFIndex index; - CFRange range; - - if (joystick->element) - return TRUE; - - if (!device_main_elements) - { - find_osx_devices(); - if (!device_main_elements) - return FALSE; - } - - index = joystick - joysticks; - if (index >= CFArrayGetCount(device_main_elements)) - return FALSE; - - joystick->element = (IOHIDElementRef)CFArrayGetValueAtIndex(device_main_elements, index); - joystick->buttons = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); - collect_joystick_elements(joystick, joystick->element); - - /* Sort buttons into correct order */ - range.location = 0; - range.length = CFArrayGetCount(joystick->buttons); - CFArraySortValues(joystick->buttons, range, button_usage_comparator, NULL); - if (range.length > 32) - { - /* Delete any buttons beyond the first 32 */ - range.location = 32; - range.length -= 32; - CFArrayReplaceValues(joystick->buttons, range, NULL, 0); - } - - return TRUE; -} - - -/************************************************************************** - * driver_joyGetDevCaps - */ -LRESULT driver_joyGetDevCaps(DWORD_PTR device_id, JOYCAPSW* caps, DWORD size) -{ - joystick_t* joystick; - IOHIDDeviceRef device; - - if ((joystick = joystick_from_id(device_id)) == NULL) - return MMSYSERR_NODRIVER; - - if (!open_joystick(joystick)) - return JOYERR_PARMS; - - caps->szPname[0] = 0; - - device = IOHIDElementGetDevice(joystick->element); - if (device) - { - CFStringRef product_name = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey)); - if (product_name) - { - CFRange range; - - range.location = 0; - range.length = min(MAXPNAMELEN - 1, CFStringGetLength(product_name)); - CFStringGetCharacters(product_name, range, (UniChar*)caps->szPname); - caps->szPname[range.length] = 0; - } - } - - caps->wMid = MM_MICROSOFT; - caps->wPid = MM_PC_JOYSTICK; - caps->wXmin = 0; - caps->wXmax = 0xFFFF; - caps->wYmin = 0; - caps->wYmax = 0xFFFF; - caps->wZmin = 0; - caps->wZmax = joystick->axes[AXIS_Z].element ? 0xFFFF : 0; - caps->wNumButtons = CFArrayGetCount(joystick->buttons); - if (size == sizeof(JOYCAPSW)) - { - int i; - - /* complete 95 structure */ - caps->wRmin = 0; - caps->wRmax = 0xFFFF; - caps->wUmin = 0; - caps->wUmax = 0xFFFF; - caps->wVmin = 0; - caps->wVmax = 0xFFFF; - caps->wMaxAxes = 6; /* same as MS Joystick Driver */ - caps->wNumAxes = 0; - caps->wMaxButtons = 32; /* same as MS Joystick Driver */ - caps->szRegKey[0] = 0; - caps->szOEMVxD[0] = 0; - caps->wCaps = 0; - - for (i = 0; i < NUM_AXES; i++) - { - if (joystick->axes[i].element) - { - caps->wNumAxes++; - switch (i) - { - case AXIS_Z: caps->wCaps |= JOYCAPS_HASZ; break; - case AXIS_RX: caps->wCaps |= JOYCAPS_HASV; break; - case AXIS_RY: caps->wCaps |= JOYCAPS_HASU; break; - case AXIS_RZ: caps->wCaps |= JOYCAPS_HASR; break; - } - } - } - - if (joystick->hatswitch) - caps->wCaps |= JOYCAPS_HASPOV | JOYCAPS_POV4DIR; - } - - TRACE("name %s buttons %u axes %d caps 0x%08x\n", debugstr_w(caps->szPname), caps->wNumButtons, caps->wNumAxes, caps->wCaps); - - return JOYERR_NOERROR; -} - -/* - * Helper to get the value from an element - */ -static LRESULT driver_getElementValue(IOHIDDeviceRef device, IOHIDElementRef element, IOHIDValueRef *pValueRef) -{ - IOReturn ret; - ret = IOHIDDeviceGetValue(device, element, pValueRef); - switch (ret) - { - case kIOReturnSuccess: - return JOYERR_NOERROR; - case kIOReturnNotAttached: - return JOYERR_UNPLUGGED; - default: - ERR("IOHIDDeviceGetValue returned 0x%x\n",ret); - return JOYERR_NOCANDO; - } -} - -/************************************************************************** - * driver_joyGetPosEx - */ -LRESULT driver_joyGetPosEx(DWORD_PTR device_id, JOYINFOEX* info) -{ - static const struct { - DWORD flag; - off_t offset; - } axis_map[NUM_AXES] = { - { JOY_RETURNX, FIELD_OFFSET(JOYINFOEX, dwXpos) }, - { JOY_RETURNY, FIELD_OFFSET(JOYINFOEX, dwYpos) }, - { JOY_RETURNZ, FIELD_OFFSET(JOYINFOEX, dwZpos) }, - { JOY_RETURNV, FIELD_OFFSET(JOYINFOEX, dwVpos) }, - { JOY_RETURNU, FIELD_OFFSET(JOYINFOEX, dwUpos) }, - { JOY_RETURNR, FIELD_OFFSET(JOYINFOEX, dwRpos) }, - }; - - joystick_t* joystick; - IOHIDDeviceRef device; - CFIndex i, count; - IOHIDValueRef valueRef; - long value; - LRESULT rc; - - if ((joystick = joystick_from_id(device_id)) == NULL) - return MMSYSERR_NODRIVER; - - if (!open_joystick(joystick)) - return JOYERR_PARMS; - - device = IOHIDElementGetDevice(joystick->element); - - if (info->dwFlags & JOY_RETURNBUTTONS) - { - info->dwButtons = 0; - info->dwButtonNumber = 0; - - count = CFArrayGetCount(joystick->buttons); - for (i = 0; i < count; i++) - { - IOHIDElementRef button = (IOHIDElementRef)CFArrayGetValueAtIndex(joystick->buttons, i); - rc = driver_getElementValue(device, button, &valueRef); - if (rc != JOYERR_NOERROR) - return rc; - value = IOHIDValueGetIntegerValue(valueRef); - if (value) - { - info->dwButtons |= 1 << i; - info->dwButtonNumber++; - } - } - } - - for (i = 0; i < NUM_AXES; i++) - { - if (info->dwFlags & axis_map[i].flag) - { - DWORD* field = (DWORD*)((char*)info + axis_map[i].offset); - if (joystick->axes[i].element) - { - rc = driver_getElementValue(device, joystick->axes[i].element, &valueRef); - if (rc != JOYERR_NOERROR) - return rc; - value = IOHIDValueGetIntegerValue(valueRef) - joystick->axes[i].min_value; - *field = MulDiv(value, 0xFFFF, joystick->axes[i].max_value - joystick->axes[i].min_value); - } - else - { - *field = 0; - info->dwFlags &= ~axis_map[i].flag; - } - } - } - - if (info->dwFlags & JOY_RETURNPOV) - { - if (joystick->hatswitch) - { - rc = driver_getElementValue(device, joystick->hatswitch, &valueRef); - if (rc != JOYERR_NOERROR) - return rc; - value = IOHIDValueGetIntegerValue(valueRef); - if (value >= 8) - info->dwPOV = JOY_POVCENTERED; - else - info->dwPOV = value * 4500; - } - else - { - info->dwPOV = JOY_POVCENTERED; - info->dwFlags &= ~JOY_RETURNPOV; - } - } - - TRACE("x: %d, y: %d, z: %d, r: %d, u: %d, v: %d, buttons: 0x%04x, pov %d, flags: 0x%04x\n", - info->dwXpos, info->dwYpos, info->dwZpos, info->dwRpos, info->dwUpos, info->dwVpos, info->dwButtons, info->dwPOV, info->dwFlags); - - return JOYERR_NOERROR; -} - -/************************************************************************** - * driver_joyGetPos - */ -LRESULT driver_joyGetPos(DWORD_PTR device_id, JOYINFO* info) -{ - JOYINFOEX ji; - LONG ret; - - memset(&ji, 0, sizeof(ji)); - - ji.dwSize = sizeof(ji); - ji.dwFlags = JOY_RETURNX | JOY_RETURNY | JOY_RETURNZ | JOY_RETURNBUTTONS; - ret = driver_joyGetPosEx(device_id, &ji); - if (ret == JOYERR_NOERROR) - { - info->wXpos = ji.dwXpos; - info->wYpos = ji.dwYpos; - info->wZpos = ji.dwZpos; - info->wButtons = ji.dwButtons; - } - - return ret; -} - -#endif /* HAVE_IOKIT_HID_IOHIDLIB_H */ diff --git a/dlls/winejoystick.drv/winejoystick.drv.spec b/dlls/winejoystick.drv/winejoystick.drv.spec deleted file mode 100644 index 29932efde7c..00000000000 --- a/dlls/winejoystick.drv/winejoystick.drv.spec +++ /dev/null @@ -1 +0,0 @@ -@ stdcall -private DriverProc(long long long long long) JSTCK_DriverProc diff --git a/tools/winapi/win32.api b/tools/winapi/win32.api index d9b77dbce39..5f3dd85cc93 100644 --- a/tools/winapi/win32.api +++ b/tools/winapi/win32.api @@ -5615,19 +5615,6 @@ IUnknown * IWineD3D * IWineD3DClipper *
-%%winejoystick.drv - -%long - -HDRVR -LPARAM -LRESULT -UINT - -%long --pointer - -DWORD_PTR - %%l3codeca.acm
%long
Signed-off-by: Andrew Eikum aeikum@codeweavers.com
On Fri, Dec 03, 2021 at 12:19:10PM +0100, Rémi Bernon wrote:
Signed-off-by: Rémi Bernon rbernon@codeweavers.com
configure.ac | 2 - dlls/winejoystick.drv/Makefile.in | 10 - dlls/winejoystick.drv/joystick.c | 52 -- dlls/winejoystick.drv/joystick.h | 34 - dlls/winejoystick.drv/joystick_linux.c | 462 ---------- dlls/winejoystick.drv/joystick_osx.c | 935 -------------------- dlls/winejoystick.drv/winejoystick.drv.spec | 1 - tools/winapi/win32.api | 13 - 8 files changed, 1509 deletions(-) delete mode 100644 dlls/winejoystick.drv/Makefile.in delete mode 100644 dlls/winejoystick.drv/joystick.c delete mode 100644 dlls/winejoystick.drv/joystick.h delete mode 100644 dlls/winejoystick.drv/joystick_linux.c delete mode 100644 dlls/winejoystick.drv/joystick_osx.c delete mode 100644 dlls/winejoystick.drv/winejoystick.drv.spec
diff --git a/configure.ac b/configure.ac index 2fe4b186fd6..328f80f17c9 100644 --- a/configure.ac +++ b/configure.ac @@ -899,7 +899,6 @@ esac enable_winecoreaudio_drv=${enable_winecoreaudio_drv:-no} enable_wineandroid_drv=${enable_wineandroid_drv:-no} enable_winemac_drv=${enable_winemac_drv:-no} -test "$ac_cv_header_linux_joystick_h" = "yes" -o "$ac_cv_header_IOKit_hid_IOHIDLib_h" = "yes" || enable_winejoystick_drv=${enable_winejoystick_drv:-no}
dnl Check for cross compiler to build test programs AC_SUBST(CROSSTARGET) @@ -3488,7 +3487,6 @@ WINE_CONFIG_MAKEFILE(dlls/winecrt0) WINE_CONFIG_MAKEFILE(dlls/wined3d) WINE_CONFIG_MAKEFILE(dlls/winegstreamer) WINE_CONFIG_MAKEFILE(dlls/winehid.sys) -WINE_CONFIG_MAKEFILE(dlls/winejoystick.drv) WINE_CONFIG_MAKEFILE(dlls/winemac.drv) WINE_CONFIG_MAKEFILE(dlls/winemapi) WINE_CONFIG_MAKEFILE(dlls/wineoss.drv) diff --git a/dlls/winejoystick.drv/Makefile.in b/dlls/winejoystick.drv/Makefile.in deleted file mode 100644 index 52564855994..00000000000 --- a/dlls/winejoystick.drv/Makefile.in +++ /dev/null @@ -1,10 +0,0 @@ -MODULE = winejoystick.drv -IMPORTS = winmm user32 -EXTRALIBS = $(IOKIT_LIBS)
-EXTRADLLFLAGS = -mcygwin
-C_SRCS = \
- joystick.c \
- joystick_linux.c \
- joystick_osx.c
diff --git a/dlls/winejoystick.drv/joystick.c b/dlls/winejoystick.drv/joystick.c deleted file mode 100644 index 3e140b91175..00000000000 --- a/dlls/winejoystick.drv/joystick.c +++ /dev/null @@ -1,52 +0,0 @@ -/*
- WinMM joystick driver common code
- Copyright 1997 Andreas Mohr
- Copyright 2000 Wolfgang Schwotzer
- Copyright 2002 David Hagood
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-#include "joystick.h"
-/**************************************************************************
DriverProc (JOYSTICK.@)
- */
-LRESULT CALLBACK JSTCK_DriverProc(DWORD_PTR dwDevID, HDRVR hDriv, UINT wMsg, LPARAM dwParam1, LPARAM dwParam2) -{
- switch(wMsg) {
- case DRV_LOAD: return 1;
- case DRV_FREE: return 1;
- case DRV_OPEN: return driver_open((LPSTR)dwParam1, dwParam2);
- case DRV_CLOSE: return driver_close(dwDevID);
- case DRV_ENABLE: return 1;
- case DRV_DISABLE: return 1;
- case DRV_QUERYCONFIGURE: return 1;
- case DRV_CONFIGURE: MessageBoxA(0, "JoyStick MultiMedia Driver !", "JoyStick Driver", MB_OK); return 1;
- case DRV_INSTALL: return DRVCNF_RESTART;
- case DRV_REMOVE: return DRVCNF_RESTART;
- case JDD_GETNUMDEVS: return 1;
- case JDD_GETDEVCAPS: return driver_joyGetDevCaps(dwDevID, (LPJOYCAPSW)dwParam1, dwParam2);
- case JDD_GETPOS: return driver_joyGetPos(dwDevID, (LPJOYINFO)dwParam1);
- case JDD_SETCALIBRATION:
- case JDD_CONFIGCHANGED: return JOYERR_NOCANDO;
- case JDD_GETPOSEX: return driver_joyGetPosEx(dwDevID, (LPJOYINFOEX)dwParam1);
- default:
return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
- }
-} diff --git a/dlls/winejoystick.drv/joystick.h b/dlls/winejoystick.drv/joystick.h deleted file mode 100644 index 1ec1edb8133..00000000000 --- a/dlls/winejoystick.drv/joystick.h +++ /dev/null @@ -1,34 +0,0 @@ -/*
- WinMM joystick driver header
- Copyright 2015 Ken Thomases for CodeWeavers Inc.
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-#include <stdarg.h>
-#include "windef.h" -#include "winbase.h" -#include "mmddk.h" -#include "winuser.h"
-LRESULT driver_open(LPSTR str, DWORD index) DECLSPEC_HIDDEN; -LRESULT driver_close(DWORD_PTR device_id) DECLSPEC_HIDDEN; -LRESULT driver_joyGetDevCaps(DWORD_PTR device_id, JOYCAPSW* caps, DWORD size) DECLSPEC_HIDDEN; -LRESULT driver_joyGetPosEx(DWORD_PTR device_id, JOYINFOEX* info) DECLSPEC_HIDDEN; -LRESULT driver_joyGetPos(DWORD_PTR device_id, JOYINFO* info) DECLSPEC_HIDDEN; diff --git a/dlls/winejoystick.drv/joystick_linux.c b/dlls/winejoystick.drv/joystick_linux.c deleted file mode 100644 index 7fd2c95aff1..00000000000 --- a/dlls/winejoystick.drv/joystick_linux.c +++ /dev/null @@ -1,462 +0,0 @@ -/*
- joystick functions
- Copyright 1997 Andreas Mohr
- Copyright 2000 Wolfgang Schwotzer
- Copyright 2002 David Hagood
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- NOTES:
- nearly all joystick functions can be regarded as obsolete,
- as Linux (2.1.x) now supports extended joysticks with a completely
- new joystick driver interface
- New driver's documentation says:
"For backward compatibility the old interface is still included,
but will be dropped in the future."
- Thus we should implement the new interface and at most keep the old
- routines for backward compatibility.
- better support of enhanced joysticks (Linux 2.2 interface is available)
- support more joystick drivers (like the XInput extension)
- should load joystick DLL as any other driver (instead of hardcoding)
- the driver's name, and load it as any low lever driver.
- */
-#include "config.h"
-#ifdef HAVE_LINUX_22_JOYSTICK_API
-#ifdef HAVE_UNISTD_H -# include <unistd.h> -#endif -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <fcntl.h> -#ifdef HAVE_SYS_IOCTL_H -#include <sys/ioctl.h> -#endif -#ifdef HAVE_LINUX_IOCTL_H -#include <linux/ioctl.h> -#endif -#include <linux/joystick.h> -#ifdef SW_MAX -#undef SW_MAX -#endif -#define JOYDEV_NEW "/dev/input/js%d" -#define JOYDEV_OLD "/dev/js%d" -#include <errno.h>
-#include "joystick.h"
-#include "wingdi.h" -#include "winnls.h" -#include "wine/debug.h"
-WINE_DEFAULT_DEBUG_CHANNEL(joystick);
-#define MAXJOYSTICK (JOYSTICKID2 + 30)
-typedef struct tagWINE_JSTCK {
- int joyIntf;
- BOOL in_use;
- /* Some extra info we need to make this actually work under the
Linux 2.2 event api.
First of all, we cannot keep closing and reopening the device file -
that blows away the state of the stick device, and we lose events. So, we
need to open the low-level device once, and close it when we are done.
Secondly, the event API only gives us what's changed. However, Windows apps
want the whole state every time, so we have to cache the data.
- */
- int dev; /* Linux level device file descriptor */
- int x;
- int y;
- int z;
- int r;
- int u;
- int v;
- int pov_x;
- int pov_y;
- int buttons;
- char axesMap[ABS_MAX + 1];
-} WINE_JSTCK;
-static WINE_JSTCK JSTCK_Data[MAXJOYSTICK];
-/**************************************************************************
JSTCK_drvGet [internal]
- */
-static WINE_JSTCK *JSTCK_drvGet(DWORD_PTR dwDevID) -{
- int p;
- if ((dwDevID - (DWORD_PTR)JSTCK_Data) % sizeof(JSTCK_Data[0]) != 0)
- return NULL;
- p = (dwDevID - (DWORD_PTR)JSTCK_Data) / sizeof(JSTCK_Data[0]);
- if (p < 0 || p >= MAXJOYSTICK || !((WINE_JSTCK*)dwDevID)->in_use)
- return NULL;
- return (WINE_JSTCK*)dwDevID;
-}
-/**************************************************************************
driver_open
- */
-LRESULT driver_open(LPSTR str, DWORD dwIntf) -{
- if (dwIntf >= MAXJOYSTICK || JSTCK_Data[dwIntf].in_use)
- return 0;
- JSTCK_Data[dwIntf].joyIntf = dwIntf;
- JSTCK_Data[dwIntf].dev = -1;
- JSTCK_Data[dwIntf].in_use = TRUE;
- return (LRESULT)&JSTCK_Data[dwIntf];
-}
-/**************************************************************************
driver_close
- */
-LRESULT driver_close(DWORD_PTR dwDevID) -{
- WINE_JSTCK* jstck = JSTCK_drvGet(dwDevID);
- if (jstck == NULL)
- return 0;
- jstck->in_use = FALSE;
- if (jstck->dev > 0)
- {
close(jstck->dev);
jstck->dev = 0;
- }
- return 1;
-}
-struct js_status -{
- int buttons;
- int x;
- int y;
-};
-/**************************************************************************
JSTCK_OpenDevice [internal]
- */
-static int JSTCK_OpenDevice(WINE_JSTCK* jstick) -{
- char buf[20];
- int flags, fd, found_ix, i;
- static DWORD last_attempt;
- DWORD now;
- if (jstick->dev > 0)
return jstick->dev;
- now = GetTickCount();
- if (now - last_attempt < 2000)
return -1;
- last_attempt = now;
- flags = O_RDONLY | O_NONBLOCK;
- /* The first joystick may not be at /dev/input/js0, find the correct
* first or second device. For example the driver for XBOX 360 wireless
* receiver creates entries starting at 20.
*/
- for (found_ix = i = 0; i < MAXJOYSTICK; i++) {
sprintf(buf, JOYDEV_NEW, i);
if ((fd = open(buf, flags)) < 0) {
sprintf(buf, JOYDEV_OLD, i);
if ((fd = open(buf, flags)) < 0)
continue;
}
if (found_ix++ == jstick->joyIntf)
{
TRACE("Found joystick[%d] at %s\n", jstick->joyIntf, buf);
jstick->dev = fd;
last_attempt = 0;
break;
}
close(fd);
- }
- if (jstick->dev > 0)
ioctl(jstick->dev, JSIOCGAXMAP, jstick->axesMap);
- return jstick->dev;
-}
-/**************************************************************************
JoyGetDevCaps [MMSYSTEM.102]
- */
-LRESULT driver_joyGetDevCaps(DWORD_PTR dwDevID, LPJOYCAPSW lpCaps, DWORD dwSize) -{
- WINE_JSTCK* jstck;
- int dev;
- char nrOfAxes;
- char nrOfButtons;
- char identString[MAXPNAMELEN];
- int i;
- int driverVersion;
- if ((jstck = JSTCK_drvGet(dwDevID)) == NULL)
- return MMSYSERR_NODRIVER;
- if ((dev = JSTCK_OpenDevice(jstck)) < 0) return JOYERR_PARMS;
- ioctl(dev, JSIOCGAXES, &nrOfAxes);
- ioctl(dev, JSIOCGBUTTONS, &nrOfButtons);
- ioctl(dev, JSIOCGVERSION, &driverVersion);
- ioctl(dev, JSIOCGNAME(sizeof(identString)), identString);
- TRACE("Driver: 0x%06x, Name: %s, #Axes: %d, #Buttons: %d\n",
driverVersion, identString, nrOfAxes, nrOfButtons);
- lpCaps->wMid = MM_MICROSOFT;
- lpCaps->wPid = MM_PC_JOYSTICK;
- MultiByteToWideChar(CP_UNIXCP, 0, identString, -1, lpCaps->szPname, MAXPNAMELEN);
- lpCaps->szPname[MAXPNAMELEN-1] = '\0';
- lpCaps->wXmin = 0;
- lpCaps->wXmax = 0xFFFF;
- lpCaps->wYmin = 0;
- lpCaps->wYmax = 0xFFFF;
- lpCaps->wZmin = 0;
- lpCaps->wZmax = (nrOfAxes >= 3) ? 0xFFFF : 0;
-#ifdef BODGE_THE_HAT
- /* Half-Life won't allow you to map an axis event to things like
"next weapon" and "use". Linux reports the hat on my stick as
axis U and V. So, IFF BODGE_THE_HAT is defined, lie through our
teeth and say we have 32 buttons, and we will map the axes to
the high buttons. Really, perhaps this should be a registry entry,
or even a parameter to the Linux joystick driver (which would completely
remove the need for this.)
- */
- lpCaps->wNumButtons = 32;
-#else
- lpCaps->wNumButtons = nrOfButtons;
-#endif
- if (dwSize == sizeof(JOYCAPSW)) {
- /* complete 95 structure */
- lpCaps->wRmin = 0;
- lpCaps->wRmax = 0xFFFF;
- lpCaps->wUmin = 0;
- lpCaps->wUmax = 0xFFFF;
- lpCaps->wVmin = 0;
- lpCaps->wVmax = 0xFFFF;
- lpCaps->wMaxAxes = 6; /* same as MS Joystick Driver */
- lpCaps->wNumAxes = 0; /* nr of axes in use */
- lpCaps->wMaxButtons = 32; /* same as MS Joystick Driver */
- lpCaps->szRegKey[0] = 0;
- lpCaps->szOEMVxD[0] = 0;
- lpCaps->wCaps = 0;
for (i = 0; i < nrOfAxes; i++) {
switch (jstck->axesMap[i]) {
case 0: /* X */
case 1: /* Y */
case 8: /* Wheel */
case 9: /* Gas */
lpCaps->wNumAxes++;
break;
case 2: /* Z */
case 6: /* Throttle */
case 10: /* Brake */
lpCaps->wNumAxes++;
lpCaps->wCaps |= JOYCAPS_HASZ;
break;
case 5: /* Rz */
case 7: /* Rudder */
lpCaps->wNumAxes++;
lpCaps->wCaps |= JOYCAPS_HASR;
break;
case 3: /* Rx */
lpCaps->wNumAxes++;
lpCaps->wCaps |= JOYCAPS_HASU;
break;
case 4: /* Ry */
lpCaps->wNumAxes++;
lpCaps->wCaps |= JOYCAPS_HASV;
break;
case 16: /* Hat 0 X */
case 17: /* Hat 0 Y */
lpCaps->wCaps |= JOYCAPS_HASPOV | JOYCAPS_POV4DIR;
/* TODO: JOYCAPS_POVCTS handling */
break;
default:
WARN("Unknown axis %hhu(%u). Skipped.\n", jstck->axesMap[i], i);
}
- }
- }
- return JOYERR_NOERROR;
-}
-/**************************************************************************
driver_joyGetPos
- */
-LRESULT driver_joyGetPosEx(DWORD_PTR dwDevID, LPJOYINFOEX lpInfo) -{
- WINE_JSTCK* jstck;
- int dev;
- struct js_event ev;
- if ((jstck = JSTCK_drvGet(dwDevID)) == NULL)
- return MMSYSERR_NODRIVER;
- if ((dev = JSTCK_OpenDevice(jstck)) < 0) return JOYERR_PARMS;
- while ((read(dev, &ev, sizeof(struct js_event))) > 0) {
- if (ev.type == (JS_EVENT_AXIS)) {
switch (jstck->axesMap[ev.number]) {
case 0: /* X */
case 8: /* Wheel */
jstck->x = ev.value;
break;
case 1: /* Y */
case 9: /* Gas */
jstck->y = ev.value;
break;
case 2: /* Z */
case 6: /* Throttle */
case 10: /* Brake */
jstck->z = ev.value;
break;
case 5: /* Rz */
case 7: /* Rudder */
jstck->r = ev.value;
break;
case 3: /* Rx */
jstck->u = ev.value;
break;
case 4: /* Ry */
jstck->v = ev.value;
break;
case 16: /* Hat 0 X */
jstck->pov_x = ev.value;
break;
case 17: /* Hat 0 Y */
jstck->pov_y = ev.value;
break;
default:
FIXME("Unknown joystick event '%d'\n", ev.number);
}
- } else if (ev.type == (JS_EVENT_BUTTON)) {
if (ev.value) {
jstck->buttons |= (1 << ev.number);
/* FIXME: what to do for this field when
* multiple buttons are depressed ?
*/
if (lpInfo->dwFlags & JOY_RETURNBUTTONS)
lpInfo->dwButtonNumber = ev.number + 1;
}
else
jstck->buttons &= ~(1 << ev.number);
- }
- }
- /* EAGAIN is returned when the queue is empty */
- if (errno != EAGAIN) {
- /* FIXME: error should not be ignored */
- ERR("Error while reading joystick state (%s)\n", strerror(errno));
- }
- /* Now, copy the cached values into Window's structure... */
- if (lpInfo->dwFlags & JOY_RETURNBUTTONS)
lpInfo->dwButtons = jstck->buttons;
- if (lpInfo->dwFlags & JOY_RETURNX)
lpInfo->dwXpos = jstck->x + 32767;
- if (lpInfo->dwFlags & JOY_RETURNY)
lpInfo->dwYpos = jstck->y + 32767;
- if (lpInfo->dwFlags & JOY_RETURNZ)
lpInfo->dwZpos = jstck->z + 32767;
- if (lpInfo->dwFlags & JOY_RETURNR)
lpInfo->dwRpos = jstck->r + 32767;
-# ifdef BODGE_THE_HAT
- else if (lpInfo->dwFlags & JOY_RETURNBUTTONS)
- {
if (jstck->r > 0)
lpInfo->dwButtons |= 1<<7;
else if (jstck->r < 0)
lpInfo->dwButtons |= 1<<8;
- }
-# endif
- if (lpInfo->dwFlags & JOY_RETURNU)
- lpInfo->dwUpos = jstck->u + 32767;
-# ifdef BODGE_THE_HAT
- else if (lpInfo->dwFlags & JOY_RETURNBUTTONS)
- {
if (jstck->u > 0)
lpInfo->dwButtons |= 1<<9;
else if (jstck->u < 0)
lpInfo->dwButtons |= 1<<10;
- }
-# endif
- if (lpInfo->dwFlags & JOY_RETURNV)
lpInfo->dwVpos = jstck->v + 32767;
- if (lpInfo->dwFlags & JOY_RETURNPOV) {
- if (jstck->pov_y > 0) {
if (jstck->pov_x < 0)
lpInfo->dwPOV = 22500; /* SW */
else if (jstck->pov_x > 0)
lpInfo->dwPOV = 13500; /* SE */
else
lpInfo->dwPOV = 18000; /* S, JOY_POVBACKWARD */
- } else if (jstck->pov_y < 0) {
if (jstck->pov_x < 0)
lpInfo->dwPOV = 31500; /* NW */
else if (jstck->pov_x > 0)
lpInfo->dwPOV = 4500; /* NE */
else
lpInfo->dwPOV = 0; /* N, JOY_POVFORWARD */
- } else if (jstck->pov_x < 0)
lpInfo->dwPOV = 27000; /* W, JOY_POVLEFT */
- else if (jstck->pov_x > 0)
lpInfo->dwPOV = 9000; /* E, JOY_POVRIGHT */
- else
lpInfo->dwPOV = JOY_POVCENTERED; /* Center */
- }
- TRACE("x: %d, y: %d, z: %d, r: %d, u: %d, v: %d, buttons: 0x%04x, flags: 0x%04x (fd %d)\n",
lpInfo->dwXpos, lpInfo->dwYpos, lpInfo->dwZpos,
lpInfo->dwRpos, lpInfo->dwUpos, lpInfo->dwVpos,
lpInfo->dwButtons, lpInfo->dwFlags, dev
);
- return JOYERR_NOERROR;
-}
-/**************************************************************************
driver_joyGetPos
- */
-LRESULT driver_joyGetPos(DWORD_PTR dwDevID, LPJOYINFO lpInfo) -{
- JOYINFOEX ji;
- LONG ret;
- memset(&ji, 0, sizeof(ji));
- ji.dwSize = sizeof(ji);
- ji.dwFlags = JOY_RETURNX | JOY_RETURNY | JOY_RETURNZ | JOY_RETURNBUTTONS;
- ret = driver_joyGetPosEx(dwDevID, &ji);
- if (ret == JOYERR_NOERROR) {
- lpInfo->wXpos = ji.dwXpos;
- lpInfo->wYpos = ji.dwYpos;
- lpInfo->wZpos = ji.dwZpos;
- lpInfo->wButtons = ji.dwButtons;
- }
- return ret;
-}
-#endif /* HAVE_LINUX_JOYSTICK_H */ diff --git a/dlls/winejoystick.drv/joystick_osx.c b/dlls/winejoystick.drv/joystick_osx.c deleted file mode 100644 index 6f53477937f..00000000000 --- a/dlls/winejoystick.drv/joystick_osx.c +++ /dev/null @@ -1,935 +0,0 @@ -/*
- WinMM joystick driver OS X implementation
- Copyright 1997 Andreas Mohr
- Copyright 1998 Marcus Meissner
- Copyright 1998,1999 Lionel Ulmer
- Copyright 2000 Wolfgang Schwotzer
- Copyright 2000-2001 TransGaming Technologies Inc.
- Copyright 2002 David Hagood
- Copyright 2009 CodeWeavers, Aric Stewart
- Copyright 2015 Ken Thomases for CodeWeavers Inc.
- Copyright 2016 David Lawrie
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-#include "config.h"
-#if defined(HAVE_IOKIT_HID_IOHIDLIB_H)
-#define DWORD UInt32 -#define LPDWORD UInt32* -#define LONG SInt32 -#define LPLONG SInt32* -#define E_PENDING __carbon_E_PENDING -#define ULONG __carbon_ULONG -#define E_INVALIDARG __carbon_E_INVALIDARG -#define E_OUTOFMEMORY __carbon_E_OUTOFMEMORY -#define E_HANDLE __carbon_E_HANDLE -#define E_ACCESSDENIED __carbon_E_ACCESSDENIED -#define E_UNEXPECTED __carbon_E_UNEXPECTED -#define E_FAIL __carbon_E_FAIL -#define E_ABORT __carbon_E_ABORT -#define E_POINTER __carbon_E_POINTER -#define E_NOINTERFACE __carbon_E_NOINTERFACE -#define E_NOTIMPL __carbon_E_NOTIMPL -#define S_FALSE __carbon_S_FALSE -#define S_OK __carbon_S_OK -#define HRESULT_FACILITY __carbon_HRESULT_FACILITY -#define IS_ERROR __carbon_IS_ERROR -#define FAILED __carbon_FAILED -#define SUCCEEDED __carbon_SUCCEEDED -#define MAKE_HRESULT __carbon_MAKE_HRESULT -#define HRESULT __carbon_HRESULT -#define STDMETHODCALLTYPE __carbon_STDMETHODCALLTYPE -#include <IOKit/IOKitLib.h> -#include <IOKit/hid/IOHIDLib.h> -#undef ULONG -#undef E_INVALIDARG -#undef E_OUTOFMEMORY -#undef E_HANDLE -#undef E_ACCESSDENIED -#undef E_UNEXPECTED -#undef E_FAIL -#undef E_ABORT -#undef E_POINTER -#undef E_NOINTERFACE -#undef E_NOTIMPL -#undef S_FALSE -#undef S_OK -#undef HRESULT_FACILITY -#undef IS_ERROR -#undef FAILED -#undef SUCCEEDED -#undef MAKE_HRESULT -#undef HRESULT -#undef STDMETHODCALLTYPE -#undef DWORD -#undef LPDWORD -#undef LONG -#undef LPLONG -#undef E_PENDING
-#include "joystick.h"
-#include "wine/debug.h"
-WINE_DEFAULT_DEBUG_CHANNEL(joystick);
-#define MAXJOYSTICK (JOYSTICKID2 + 30)
-enum {
- AXIS_X, /* Winmm X */
- AXIS_Y, /* Winmm Y */
- AXIS_Z, /* Winmm Z */
- AXIS_RX, /* Winmm V */
- AXIS_RY, /* Winmm U */
- AXIS_RZ, /* Winmm R */
- NUM_AXES
-};
-struct axis {
- IOHIDElementRef element;
- CFIndex min_value, max_value;
-};
-typedef struct {
- BOOL in_use;
- IOHIDElementRef element;
- struct axis axes[NUM_AXES];
- CFMutableArrayRef buttons;
- IOHIDElementRef hatswitch;
-} joystick_t;
-static joystick_t joysticks[MAXJOYSTICK]; -static CFMutableArrayRef device_main_elements = NULL;
-static long get_device_property_long(IOHIDDeviceRef device, CFStringRef key) -{
- CFTypeRef ref;
- long result = 0;
- if (device)
- {
assert(IOHIDDeviceGetTypeID() == CFGetTypeID(device));
ref = IOHIDDeviceGetProperty(device, key);
if (ref && CFNumberGetTypeID() == CFGetTypeID(ref))
CFNumberGetValue((CFNumberRef)ref, kCFNumberLongType, &result);
- }
- return result;
-}
-static CFStringRef copy_device_name(IOHIDDeviceRef device) -{
- CFStringRef name;
- if (device)
- {
CFTypeRef ref_name;
assert(IOHIDDeviceGetTypeID() == CFGetTypeID(device));
ref_name = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey));
if (ref_name && CFStringGetTypeID() == CFGetTypeID(ref_name))
name = CFStringCreateCopy(kCFAllocatorDefault, ref_name);
else
{
long vendID, prodID;
vendID = get_device_property_long(device, CFSTR(kIOHIDVendorIDKey));
prodID = get_device_property_long(device, CFSTR(kIOHIDProductIDKey));
name = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("0x%04lx 0x%04lx"), vendID, prodID);
}
- }
- else
- {
ERR("NULL device\n");
name = CFStringCreateCopy(kCFAllocatorDefault, CFSTR(""));
- }
- return name;
-}
-static long get_device_location_ID(IOHIDDeviceRef device) -{
- return get_device_property_long(device, CFSTR(kIOHIDLocationIDKey));
-}
-static const char* debugstr_cf(CFTypeRef t) -{
- CFStringRef s;
- const char* ret;
- if (!t) return "(null)";
- if (CFGetTypeID(t) == CFStringGetTypeID())
s = t;
- else
s = CFCopyDescription(t);
- ret = CFStringGetCStringPtr(s, kCFStringEncodingUTF8);
- if (ret) ret = debugstr_a(ret);
- if (!ret)
- {
const UniChar* u = CFStringGetCharactersPtr(s);
if (u)
ret = debugstr_wn((const WCHAR*)u, CFStringGetLength(s));
- }
- if (!ret)
- {
UniChar buf[200];
int len = min(CFStringGetLength(s), ARRAY_SIZE(buf));
CFStringGetCharacters(s, CFRangeMake(0, len), buf);
ret = debugstr_wn(buf, len);
- }
- if (s != t) CFRelease(s);
- return ret;
-}
-static const char* debugstr_device(IOHIDDeviceRef device) -{
- return wine_dbg_sprintf("<IOHIDDevice %p product %s IOHIDLocationID %lu>", device,
debugstr_cf(IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey))),
get_device_location_ID(device));
-}
-static const char* debugstr_element(IOHIDElementRef element) -{
- return wine_dbg_sprintf("<IOHIDElement %p type %d usage %u/%u device %p>", element,
IOHIDElementGetType(element), IOHIDElementGetUsagePage(element),
IOHIDElementGetUsage(element), IOHIDElementGetDevice(element));
-}
-static int axis_for_usage_GD(int usage) -{
- switch (usage)
- {
case kHIDUsage_GD_X: return AXIS_X;
case kHIDUsage_GD_Y: return AXIS_Y;
case kHIDUsage_GD_Z: return AXIS_Z;
case kHIDUsage_GD_Rx: return AXIS_RX;
case kHIDUsage_GD_Ry: return AXIS_RY;
case kHIDUsage_GD_Rz: return AXIS_RZ;
- }
- return -1;
-}
-static int axis_for_usage_Sim(int usage) -{
- switch (usage)
- {
case kHIDUsage_Sim_Rudder: return AXIS_RZ;
case kHIDUsage_Sim_Throttle: return AXIS_Z;
case kHIDUsage_Sim_Steering: return AXIS_X;
case kHIDUsage_Sim_Accelerator: return AXIS_Y;
case kHIDUsage_Sim_Brake: return AXIS_RZ;
- }
- return -1;
-}
-/**************************************************************************
joystick_from_id
- */
-static joystick_t* joystick_from_id(DWORD_PTR device_id) -{
- int index;
- if ((device_id - (DWORD_PTR)joysticks) % sizeof(joysticks[0]) != 0)
return NULL;
- index = (device_id - (DWORD_PTR)joysticks) / sizeof(joysticks[0]);
- if (index < 0 || index >= MAXJOYSTICK || !((joystick_t*)device_id)->in_use)
return NULL;
- return (joystick_t*)device_id;
-}
-/**************************************************************************
create_osx_device_match
- */
-static CFDictionaryRef create_osx_device_match(int usage) -{
- CFDictionaryRef result = NULL;
- int number;
- CFStringRef keys[] = { CFSTR(kIOHIDDeviceUsagePageKey), CFSTR(kIOHIDDeviceUsageKey) };
- CFNumberRef values[2];
- int i;
- TRACE("usage %d\n", usage);
- number = kHIDPage_GenericDesktop;
- values[0] = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &number);
- values[1] = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usage);
- if (values[0] && values[1])
- {
result = CFDictionaryCreate(NULL, (const void**)keys, (const void**)values, ARRAY_SIZE(values),
&kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
if (!result)
ERR("CFDictionaryCreate failed.\n");
- }
- else
ERR("CFNumberCreate failed.\n");
- for (i = 0; i < ARRAY_SIZE(values); i++)
if (values[i]) CFRelease(values[i]);
- return result;
-}
-/**************************************************************************
find_top_level
- */
-static CFIndex find_top_level(IOHIDDeviceRef hid_device, CFMutableArrayRef main_elements) -{
- CFArrayRef elements;
- CFIndex total = 0;
- TRACE("hid_device %s\n", debugstr_device(hid_device));
- if (!hid_device)
return 0;
- elements = IOHIDDeviceCopyMatchingElements(hid_device, NULL, 0);
- if (elements)
- {
CFIndex i, count = CFArrayGetCount(elements);
for (i = 0; i < count; i++)
{
IOHIDElementRef element = (IOHIDElementRef)CFArrayGetValueAtIndex(elements, i);
int type = IOHIDElementGetType(element);
TRACE("element %s\n", debugstr_element(element));
/* Check for top-level gaming device collections */
if (type == kIOHIDElementTypeCollection && IOHIDElementGetParent(element) == 0)
{
int usage_page = IOHIDElementGetUsagePage(element);
int usage = IOHIDElementGetUsage(element);
if (usage_page == kHIDPage_GenericDesktop &&
(usage == kHIDUsage_GD_Joystick || usage == kHIDUsage_GD_GamePad || usage == kHIDUsage_GD_MultiAxisController))
{
CFArrayAppendValue(main_elements, element);
total++;
}
}
}
CFRelease(elements);
- }
- TRACE("-> total %d\n", (int)total);
- return total;
-} -/**************************************************************************
device_name_comparator
- Virtual joysticks may not have a kIOHIDLocationIDKey and will default to location ID of 0, this orders virtual joysticks by their name
- */
-static CFComparisonResult device_name_comparator(IOHIDDeviceRef device1, IOHIDDeviceRef device2) -{
- CFStringRef name1 = copy_device_name(device1), name2 = copy_device_name(device2);
- CFComparisonResult result = CFStringCompare(name1, name2, (kCFCompareForcedOrdering | kCFCompareNumerically));
- CFRelease(name1);
- CFRelease(name2);
- return result;
-}
-/**************************************************************************
device_location_name_comparator
- Helper to sort device array first by location ID, since location IDs are consistent across boots & launches, then by product name
- */
-static CFComparisonResult device_location_name_comparator(const void *val1, const void *val2, void *context) -{
- IOHIDDeviceRef device1 = (IOHIDDeviceRef)val1, device2 = (IOHIDDeviceRef)val2;
- long loc1 = get_device_location_ID(device1), loc2 = get_device_location_ID(device2);
- if (loc1 < loc2)
return kCFCompareLessThan;
- else if (loc1 > loc2)
return kCFCompareGreaterThan;
- return device_name_comparator(device1, device2);
-}
-/**************************************************************************
copy_set_to_array
- Helper to copy the CFSet to a CFArray
- */
-static void copy_set_to_array(const void *value, void *context) -{
- CFArrayAppendValue(context, value);
-}
-/**************************************************************************
find_osx_devices
- */
-static int find_osx_devices(void) -{
- IOHIDManagerRef hid_manager;
- int usages[] = { kHIDUsage_GD_Joystick, kHIDUsage_GD_GamePad, kHIDUsage_GD_MultiAxisController };
- int i;
- CFDictionaryRef matching_dicts[ARRAY_SIZE(usages)];
- CFArrayRef matching;
- CFSetRef devset;
- TRACE("()\n");
- hid_manager = IOHIDManagerCreate(kCFAllocatorDefault, 0L);
- if (IOHIDManagerOpen(hid_manager, 0) != kIOReturnSuccess)
- {
ERR("Couldn't open IOHIDManager.\n");
CFRelease(hid_manager);
return 0;
- }
- for (i = 0; i < ARRAY_SIZE(matching_dicts); i++)
- {
matching_dicts[i] = create_osx_device_match(usages[i]);
if (!matching_dicts[i])
{
while (i > 0)
CFRelease(matching_dicts[--i]);
goto fail;
}
- }
- matching = CFArrayCreate(NULL, (const void**)matching_dicts, ARRAY_SIZE(matching_dicts),
&kCFTypeArrayCallBacks);
- for (i = 0; i < ARRAY_SIZE(matching_dicts); i++)
CFRelease(matching_dicts[i]);
- IOHIDManagerSetDeviceMatchingMultiple(hid_manager, matching);
- CFRelease(matching);
- devset = IOHIDManagerCopyDevices(hid_manager);
- if (devset)
- {
CFIndex num_devices, num_main_elements;
CFMutableArrayRef devices;
num_devices = CFSetGetCount(devset);
devices = CFArrayCreateMutable(kCFAllocatorDefault, num_devices, &kCFTypeArrayCallBacks);
CFSetApplyFunction(devset, copy_set_to_array, (void *)devices);
CFArraySortValues(devices, CFRangeMake(0, num_devices), device_location_name_comparator, NULL);
CFRelease(devset);
if (!devices)
goto fail;
device_main_elements = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
if (!device_main_elements)
{
CFRelease(devices);
goto fail;
}
num_main_elements = 0;
for (i = 0; i < num_devices; i++)
{
IOHIDDeviceRef hid_device = (IOHIDDeviceRef)CFArrayGetValueAtIndex(devices, i);
TRACE("hid_device %s\n", debugstr_device(hid_device));
num_main_elements += find_top_level(hid_device, device_main_elements);
}
CFRelease(devices);
TRACE("found %i device(s), %i collection(s)\n",(int)num_devices,(int)num_main_elements);
return (int)num_main_elements;
- }
-fail:
- IOHIDManagerClose(hid_manager, 0);
- CFRelease(hid_manager);
- return 0;
-}
-/**************************************************************************
collect_joystick_elements
- */
-static void collect_joystick_elements(joystick_t* joystick, IOHIDElementRef collection) -{
- CFIndex i, count;
- CFArrayRef children = IOHIDElementGetChildren(collection);
- TRACE("collection %s\n", debugstr_element(collection));
- count = CFArrayGetCount(children);
- for (i = 0; i < count; i++)
- {
IOHIDElementRef child;
int type;
uint32_t usage_page;
child = (IOHIDElementRef)CFArrayGetValueAtIndex(children, i);
TRACE("child %s\n", debugstr_element(child));
type = IOHIDElementGetType(child);
usage_page = IOHIDElementGetUsagePage(child);
switch (type)
{
case kIOHIDElementTypeCollection:
collect_joystick_elements(joystick, child);
break;
case kIOHIDElementTypeInput_Button:
{
TRACE("kIOHIDElementTypeInput_Button usage_page %d\n", usage_page);
/* avoid strange elements found on the 360 controller */
if (usage_page == kHIDPage_Button)
CFArrayAppendValue(joystick->buttons, child);
break;
}
case kIOHIDElementTypeInput_Axis:
case kIOHIDElementTypeInput_Misc:
{
uint32_t usage = IOHIDElementGetUsage( child );
switch (usage_page)
{
case kHIDPage_GenericDesktop:
{
switch(usage)
{
case kHIDUsage_GD_Hatswitch:
{
TRACE("kIOHIDElementTypeInput_Axis/Misc / kHIDUsage_GD_Hatswitch\n");
if (joystick->hatswitch)
TRACE(" ignoring additional hatswitch\n");
else
joystick->hatswitch = (IOHIDElementRef)CFRetain(child);
break;
}
case kHIDUsage_GD_X:
case kHIDUsage_GD_Y:
case kHIDUsage_GD_Z:
case kHIDUsage_GD_Rx:
case kHIDUsage_GD_Ry:
case kHIDUsage_GD_Rz:
{
int axis = axis_for_usage_GD(usage);
TRACE("kIOHIDElementTypeInput_Axis/Misc / kHIDUsage_GD_<axis> (%d) axis %d\n", usage, axis);
if (axis < 0 || joystick->axes[axis].element)
TRACE(" ignoring\n");
else
{
joystick->axes[axis].element = (IOHIDElementRef)CFRetain(child);
joystick->axes[axis].min_value = IOHIDElementGetLogicalMin(child);
joystick->axes[axis].max_value = IOHIDElementGetLogicalMax(child);
}
break;
}
case kHIDUsage_GD_Slider:
case kHIDUsage_GD_Dial:
case kHIDUsage_GD_Wheel:
{
/* if one axis is taken, fall to the next until axes are filled */
int possible_axes[3] = {AXIS_Z,AXIS_RY,AXIS_RX};
int axis = 0;
while(axis < 3 && joystick->axes[possible_axes[axis]].element)
axis++;
if (axis == 3)
TRACE("kIOHIDElementTypeInput_Axis/Misc / kHIDUsage_GD_<axis> (%d)\n ignoring\n", usage);
else
{
TRACE("kIOHIDElementTypeInput_Axis/Misc / kHIDUsage_GD_<axis> (%d) axis %d\n", usage, possible_axes[axis]);
joystick->axes[possible_axes[axis]].element = (IOHIDElementRef)CFRetain(child);
joystick->axes[possible_axes[axis]].min_value = IOHIDElementGetLogicalMin(child);
joystick->axes[possible_axes[axis]].max_value = IOHIDElementGetLogicalMax(child);
}
break;
}
default:
FIXME("kIOHIDElementTypeInput_Axis/Misc / Unhandled GD Page usage %d\n", usage);
break;
}
break;
}
case kHIDPage_Simulation:
{
switch(usage)
{
case kHIDUsage_Sim_Rudder:
case kHIDUsage_Sim_Throttle:
case kHIDUsage_Sim_Steering:
case kHIDUsage_Sim_Accelerator:
case kHIDUsage_Sim_Brake:
{
int axis = axis_for_usage_Sim(usage);
TRACE("kIOHIDElementTypeInput_Axis/Misc / kHIDUsage_Sim_<axis> (%d) axis %d\n", usage, axis);
if (axis < 0 || joystick->axes[axis].element)
TRACE(" ignoring\n");
else
{
joystick->axes[axis].element = (IOHIDElementRef)CFRetain(child);
joystick->axes[axis].min_value = IOHIDElementGetLogicalMin(child);
joystick->axes[axis].max_value = IOHIDElementGetLogicalMax(child);
}
break;
}
default:
FIXME("kIOHIDElementTypeInput_Axis/Misc / Unhandled Sim Page usage %d\n", usage);
break;
}
break;
}
default:
FIXME("kIOHIDElementTypeInput_Axis/Misc / Unhandled Usage Page %d\n", usage_page);
break;
}
break;
}
case kIOHIDElementTypeFeature:
/* Describes input and output elements not intended for consumption by the end user. Ignoring. */
break;
default:
FIXME("Unhandled type %i\n",type);
break;
}
- }
-}
-/**************************************************************************
button_usage_comparator
- */
-static CFComparisonResult button_usage_comparator(const void *val1, const void *val2, void *context) -{
- IOHIDElementRef element1 = (IOHIDElementRef)val1, element2 = (IOHIDElementRef)val2;
- int usage1 = IOHIDElementGetUsage(element1), usage2 = IOHIDElementGetUsage(element2);
- if (usage1 < usage2)
return kCFCompareLessThan;
- if (usage1 > usage2)
return kCFCompareGreaterThan;
- return kCFCompareEqualTo;
-}
-/**************************************************************************
driver_open
- */
-LRESULT driver_open(LPSTR str, DWORD index) -{
- if (index >= MAXJOYSTICK || joysticks[index].in_use)
return 0;
- joysticks[index].in_use = TRUE;
- return (LRESULT)&joysticks[index];
-}
-/**************************************************************************
driver_close
- */
-LRESULT driver_close(DWORD_PTR device_id) -{
- joystick_t* joystick = joystick_from_id(device_id);
- int i;
- if (joystick == NULL)
return 0;
- CFRelease(joystick->element);
- for (i = 0; i < NUM_AXES; i++)
- {
if (joystick->axes[i].element)
CFRelease(joystick->axes[i].element);
- }
- if (joystick->buttons)
CFRelease(joystick->buttons);
- if (joystick->hatswitch)
CFRelease(joystick->hatswitch);
- memset(joystick, 0, sizeof(*joystick));
- return 1;
-}
-/**************************************************************************
open_joystick
- */
-static BOOL open_joystick(joystick_t* joystick) -{
- CFIndex index;
- CFRange range;
- if (joystick->element)
return TRUE;
- if (!device_main_elements)
- {
find_osx_devices();
if (!device_main_elements)
return FALSE;
- }
- index = joystick - joysticks;
- if (index >= CFArrayGetCount(device_main_elements))
return FALSE;
- joystick->element = (IOHIDElementRef)CFArrayGetValueAtIndex(device_main_elements, index);
- joystick->buttons = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
- collect_joystick_elements(joystick, joystick->element);
- /* Sort buttons into correct order */
- range.location = 0;
- range.length = CFArrayGetCount(joystick->buttons);
- CFArraySortValues(joystick->buttons, range, button_usage_comparator, NULL);
- if (range.length > 32)
- {
/* Delete any buttons beyond the first 32 */
range.location = 32;
range.length -= 32;
CFArrayReplaceValues(joystick->buttons, range, NULL, 0);
- }
- return TRUE;
-}
-/**************************************************************************
driver_joyGetDevCaps
- */
-LRESULT driver_joyGetDevCaps(DWORD_PTR device_id, JOYCAPSW* caps, DWORD size) -{
- joystick_t* joystick;
- IOHIDDeviceRef device;
- if ((joystick = joystick_from_id(device_id)) == NULL)
return MMSYSERR_NODRIVER;
- if (!open_joystick(joystick))
return JOYERR_PARMS;
- caps->szPname[0] = 0;
- device = IOHIDElementGetDevice(joystick->element);
- if (device)
- {
CFStringRef product_name = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey));
if (product_name)
{
CFRange range;
range.location = 0;
range.length = min(MAXPNAMELEN - 1, CFStringGetLength(product_name));
CFStringGetCharacters(product_name, range, (UniChar*)caps->szPname);
caps->szPname[range.length] = 0;
}
- }
- caps->wMid = MM_MICROSOFT;
- caps->wPid = MM_PC_JOYSTICK;
- caps->wXmin = 0;
- caps->wXmax = 0xFFFF;
- caps->wYmin = 0;
- caps->wYmax = 0xFFFF;
- caps->wZmin = 0;
- caps->wZmax = joystick->axes[AXIS_Z].element ? 0xFFFF : 0;
- caps->wNumButtons = CFArrayGetCount(joystick->buttons);
- if (size == sizeof(JOYCAPSW))
- {
int i;
/* complete 95 structure */
caps->wRmin = 0;
caps->wRmax = 0xFFFF;
caps->wUmin = 0;
caps->wUmax = 0xFFFF;
caps->wVmin = 0;
caps->wVmax = 0xFFFF;
caps->wMaxAxes = 6; /* same as MS Joystick Driver */
caps->wNumAxes = 0;
caps->wMaxButtons = 32; /* same as MS Joystick Driver */
caps->szRegKey[0] = 0;
caps->szOEMVxD[0] = 0;
caps->wCaps = 0;
for (i = 0; i < NUM_AXES; i++)
{
if (joystick->axes[i].element)
{
caps->wNumAxes++;
switch (i)
{
case AXIS_Z: caps->wCaps |= JOYCAPS_HASZ; break;
case AXIS_RX: caps->wCaps |= JOYCAPS_HASV; break;
case AXIS_RY: caps->wCaps |= JOYCAPS_HASU; break;
case AXIS_RZ: caps->wCaps |= JOYCAPS_HASR; break;
}
}
}
if (joystick->hatswitch)
caps->wCaps |= JOYCAPS_HASPOV | JOYCAPS_POV4DIR;
- }
- TRACE("name %s buttons %u axes %d caps 0x%08x\n", debugstr_w(caps->szPname), caps->wNumButtons, caps->wNumAxes, caps->wCaps);
- return JOYERR_NOERROR;
-}
-/*
- Helper to get the value from an element
- */
-static LRESULT driver_getElementValue(IOHIDDeviceRef device, IOHIDElementRef element, IOHIDValueRef *pValueRef) -{
- IOReturn ret;
- ret = IOHIDDeviceGetValue(device, element, pValueRef);
- switch (ret)
- {
case kIOReturnSuccess:
return JOYERR_NOERROR;
case kIOReturnNotAttached:
return JOYERR_UNPLUGGED;
default:
ERR("IOHIDDeviceGetValue returned 0x%x\n",ret);
return JOYERR_NOCANDO;
- }
-}
-/**************************************************************************
driver_joyGetPosEx
- */
-LRESULT driver_joyGetPosEx(DWORD_PTR device_id, JOYINFOEX* info) -{
- static const struct {
DWORD flag;
off_t offset;
- } axis_map[NUM_AXES] = {
{ JOY_RETURNX, FIELD_OFFSET(JOYINFOEX, dwXpos) },
{ JOY_RETURNY, FIELD_OFFSET(JOYINFOEX, dwYpos) },
{ JOY_RETURNZ, FIELD_OFFSET(JOYINFOEX, dwZpos) },
{ JOY_RETURNV, FIELD_OFFSET(JOYINFOEX, dwVpos) },
{ JOY_RETURNU, FIELD_OFFSET(JOYINFOEX, dwUpos) },
{ JOY_RETURNR, FIELD_OFFSET(JOYINFOEX, dwRpos) },
- };
- joystick_t* joystick;
- IOHIDDeviceRef device;
- CFIndex i, count;
- IOHIDValueRef valueRef;
- long value;
- LRESULT rc;
- if ((joystick = joystick_from_id(device_id)) == NULL)
return MMSYSERR_NODRIVER;
- if (!open_joystick(joystick))
return JOYERR_PARMS;
- device = IOHIDElementGetDevice(joystick->element);
- if (info->dwFlags & JOY_RETURNBUTTONS)
- {
info->dwButtons = 0;
info->dwButtonNumber = 0;
count = CFArrayGetCount(joystick->buttons);
for (i = 0; i < count; i++)
{
IOHIDElementRef button = (IOHIDElementRef)CFArrayGetValueAtIndex(joystick->buttons, i);
rc = driver_getElementValue(device, button, &valueRef);
if (rc != JOYERR_NOERROR)
return rc;
value = IOHIDValueGetIntegerValue(valueRef);
if (value)
{
info->dwButtons |= 1 << i;
info->dwButtonNumber++;
}
}
- }
- for (i = 0; i < NUM_AXES; i++)
- {
if (info->dwFlags & axis_map[i].flag)
{
DWORD* field = (DWORD*)((char*)info + axis_map[i].offset);
if (joystick->axes[i].element)
{
rc = driver_getElementValue(device, joystick->axes[i].element, &valueRef);
if (rc != JOYERR_NOERROR)
return rc;
value = IOHIDValueGetIntegerValue(valueRef) - joystick->axes[i].min_value;
*field = MulDiv(value, 0xFFFF, joystick->axes[i].max_value - joystick->axes[i].min_value);
}
else
{
*field = 0;
info->dwFlags &= ~axis_map[i].flag;
}
}
- }
- if (info->dwFlags & JOY_RETURNPOV)
- {
if (joystick->hatswitch)
{
rc = driver_getElementValue(device, joystick->hatswitch, &valueRef);
if (rc != JOYERR_NOERROR)
return rc;
value = IOHIDValueGetIntegerValue(valueRef);
if (value >= 8)
info->dwPOV = JOY_POVCENTERED;
else
info->dwPOV = value * 4500;
}
else
{
info->dwPOV = JOY_POVCENTERED;
info->dwFlags &= ~JOY_RETURNPOV;
}
- }
- TRACE("x: %d, y: %d, z: %d, r: %d, u: %d, v: %d, buttons: 0x%04x, pov %d, flags: 0x%04x\n",
info->dwXpos, info->dwYpos, info->dwZpos, info->dwRpos, info->dwUpos, info->dwVpos, info->dwButtons, info->dwPOV, info->dwFlags);
- return JOYERR_NOERROR;
-}
-/**************************************************************************
driver_joyGetPos
- */
-LRESULT driver_joyGetPos(DWORD_PTR device_id, JOYINFO* info) -{
- JOYINFOEX ji;
- LONG ret;
- memset(&ji, 0, sizeof(ji));
- ji.dwSize = sizeof(ji);
- ji.dwFlags = JOY_RETURNX | JOY_RETURNY | JOY_RETURNZ | JOY_RETURNBUTTONS;
- ret = driver_joyGetPosEx(device_id, &ji);
- if (ret == JOYERR_NOERROR)
- {
info->wXpos = ji.dwXpos;
info->wYpos = ji.dwYpos;
info->wZpos = ji.dwZpos;
info->wButtons = ji.dwButtons;
- }
- return ret;
-}
-#endif /* HAVE_IOKIT_HID_IOHIDLIB_H */ diff --git a/dlls/winejoystick.drv/winejoystick.drv.spec b/dlls/winejoystick.drv/winejoystick.drv.spec deleted file mode 100644 index 29932efde7c..00000000000 --- a/dlls/winejoystick.drv/winejoystick.drv.spec +++ /dev/null @@ -1 +0,0 @@ -@ stdcall -private DriverProc(long long long long long) JSTCK_DriverProc diff --git a/tools/winapi/win32.api b/tools/winapi/win32.api index d9b77dbce39..5f3dd85cc93 100644 --- a/tools/winapi/win32.api +++ b/tools/winapi/win32.api @@ -5615,19 +5615,6 @@ IUnknown * IWineD3D * IWineD3DClipper *
-%%winejoystick.drv
-%long
-HDRVR -LPARAM -LRESULT -UINT
-%long --pointer
-DWORD_PTR
%%l3codeca.acm
%long
2.34.0
Signed-off-by: Andrew Eikum aeikum@codeweavers.com
On Fri, Dec 03, 2021 at 12:19:01PM +0100, Rémi Bernon wrote:
Signed-off-by: Rémi Bernon rbernon@codeweavers.com
v2: Pass a size to joyGetDevCapsW matching the one passed to joyGetDevCapsA, fixing some tests, as the winejoystick.drv isn't accepting JOYCAPS2W sizes for the moment.
dlls/winmm/joystick.c | 99 ++++++++++++++++++++++++------------------- 1 file changed, 56 insertions(+), 43 deletions(-)
diff --git a/dlls/winmm/joystick.c b/dlls/winmm/joystick.c index 2b1811d3778..bb8142a29a9 100644 --- a/dlls/winmm/joystick.c +++ b/dlls/winmm/joystick.c @@ -167,64 +167,77 @@ UINT WINAPI DECLSPEC_HOTPATCH joyGetNumDevs(void) /**************************************************************************
joyGetDevCapsW [WINMM.@]
*/ -MMRESULT WINAPI DECLSPEC_HOTPATCH joyGetDevCapsW(UINT_PTR wID, LPJOYCAPSW lpCaps, UINT wSize) +MMRESULT WINAPI DECLSPEC_HOTPATCH joyGetDevCapsW( UINT_PTR id, JOYCAPSW *caps, UINT size ) {
- if (wID >= MAXJOYSTICK) return JOYERR_PARMS;
- if (!JOY_LoadDriver(wID)) return MMSYSERR_NODRIVER;
- TRACE( "id %d, caps %p, size %u.\n", (int)id, caps, size );
- lpCaps->wPeriodMin = JOY_PERIOD_MIN; /* FIXME */
- lpCaps->wPeriodMax = JOY_PERIOD_MAX; /* FIXME (same as MS Joystick Driver) */
- if (!caps) return MMSYSERR_INVALPARAM;
- if (size != sizeof(JOYCAPSW) && size != sizeof(JOYCAPS2W)) return JOYERR_PARMS;
- return SendDriverMessage(JOY_Sticks[wID].hDriver, JDD_GETDEVCAPS, (LPARAM)lpCaps, wSize);
- if (id >= MAXJOYSTICK) return JOYERR_PARMS;
- if (!JOY_LoadDriver( id )) return MMSYSERR_NODRIVER;
- caps->wPeriodMin = JOY_PERIOD_MIN; /* FIXME */
- caps->wPeriodMax = JOY_PERIOD_MAX; /* FIXME (same as MS Joystick Driver) */
- return SendDriverMessage( JOY_Sticks[id].hDriver, JDD_GETDEVCAPS, (LPARAM)caps, size );
}
/**************************************************************************
joyGetDevCapsA [WINMM.@]
*/ -MMRESULT WINAPI DECLSPEC_HOTPATCH joyGetDevCapsA(UINT_PTR wID, LPJOYCAPSA lpCaps, UINT wSize) +MMRESULT WINAPI DECLSPEC_HOTPATCH joyGetDevCapsA( UINT_PTR id, JOYCAPSA *caps, UINT size ) {
- JOYCAPSW jcw;
- MMRESULT ret;
- UINT size_w = sizeof(JOYCAPS2W);
- JOYCAPS2W caps_w;
- MMRESULT res;
- if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
- TRACE( "id %d, caps %p, size %u.\n", (int)id, caps, size );
- ret = joyGetDevCapsW(wID, &jcw, sizeof(jcw));
- if (!caps) return MMSYSERR_INVALPARAM;
- if (size != sizeof(JOYCAPSA) && size != sizeof(JOYCAPS2A)) return JOYERR_PARMS;
- if (ret == JOYERR_NOERROR)
- if (size == sizeof(JOYCAPSA)) size_w = sizeof(JOYCAPSW);
- res = joyGetDevCapsW( id, (JOYCAPSW *)&caps_w, size_w );
- if (res) return res;
- caps->wMid = caps_w.wMid;
- caps->wPid = caps_w.wPid;
- WideCharToMultiByte( CP_ACP, 0, caps_w.szPname, -1, caps->szPname,
sizeof(caps->szPname), NULL, NULL );
- caps->wXmin = caps_w.wXmin;
- caps->wXmax = caps_w.wXmax;
- caps->wYmin = caps_w.wYmin;
- caps->wYmax = caps_w.wYmax;
- caps->wZmin = caps_w.wZmin;
- caps->wZmax = caps_w.wZmax;
- caps->wNumButtons = caps_w.wNumButtons;
- caps->wPeriodMin = caps_w.wPeriodMin;
- caps->wPeriodMax = caps_w.wPeriodMax;
- caps->wRmin = caps_w.wRmin;
- caps->wRmax = caps_w.wRmax;
- caps->wUmin = caps_w.wUmin;
- caps->wUmax = caps_w.wUmax;
- caps->wVmin = caps_w.wVmin;
- caps->wVmax = caps_w.wVmax;
- caps->wCaps = caps_w.wCaps;
- caps->wMaxAxes = caps_w.wMaxAxes;
- caps->wNumAxes = caps_w.wNumAxes;
- caps->wMaxButtons = caps_w.wMaxButtons;
- WideCharToMultiByte( CP_ACP, 0, caps_w.szRegKey, -1, caps->szRegKey,
sizeof(caps->szRegKey), NULL, NULL );
- WideCharToMultiByte( CP_ACP, 0, caps_w.szOEMVxD, -1, caps->szOEMVxD,
sizeof(caps->szOEMVxD), NULL, NULL );
- if (size == sizeof(JOYCAPS2A)) {
lpCaps->wMid = jcw.wMid;
lpCaps->wPid = jcw.wPid;
WideCharToMultiByte( CP_ACP, 0, jcw.szPname, -1, lpCaps->szPname,
sizeof(lpCaps->szPname), NULL, NULL );
lpCaps->wXmin = jcw.wXmin;
lpCaps->wXmax = jcw.wXmax;
lpCaps->wYmin = jcw.wYmin;
lpCaps->wYmax = jcw.wYmax;
lpCaps->wZmin = jcw.wZmin;
lpCaps->wZmax = jcw.wZmax;
lpCaps->wNumButtons = jcw.wNumButtons;
lpCaps->wPeriodMin = jcw.wPeriodMin;
lpCaps->wPeriodMax = jcw.wPeriodMax;
if (wSize >= sizeof(JOYCAPSA)) { /* Win95 extensions ? */
lpCaps->wRmin = jcw.wRmin;
lpCaps->wRmax = jcw.wRmax;
lpCaps->wUmin = jcw.wUmin;
lpCaps->wUmax = jcw.wUmax;
lpCaps->wVmin = jcw.wVmin;
lpCaps->wVmax = jcw.wVmax;
lpCaps->wCaps = jcw.wCaps;
lpCaps->wMaxAxes = jcw.wMaxAxes;
lpCaps->wNumAxes = jcw.wNumAxes;
lpCaps->wMaxButtons = jcw.wMaxButtons;
WideCharToMultiByte( CP_ACP, 0, jcw.szRegKey, -1, lpCaps->szRegKey,
sizeof(lpCaps->szRegKey), NULL, NULL );
WideCharToMultiByte( CP_ACP, 0, jcw.szOEMVxD, -1, lpCaps->szOEMVxD,
sizeof(lpCaps->szOEMVxD), NULL, NULL );
}
JOYCAPS2A *caps2_a = (JOYCAPS2A *)caps;
caps2_a->ManufacturerGuid = caps_w.ManufacturerGuid;
caps2_a->ProductGuid = caps_w.ProductGuid;
}caps2_a->NameGuid = caps_w.NameGuid;
- return ret;
- return JOYERR_NOERROR;
}
/**************************************************************************
2.34.0