Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput/tests/keyboard.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
diff --git a/dlls/dinput/tests/keyboard.c b/dlls/dinput/tests/keyboard.c index d6ab5b5c7e3..0e399f021c2 100644 --- a/dlls/dinput/tests/keyboard.c +++ b/dlls/dinput/tests/keyboard.c @@ -93,6 +93,7 @@ static void acquire_tests(IDirectInputA *pDI, HWND hwnd) }; DIDATAFORMAT df; HKL hkl, hkl_orig; + UINT prev_raw_devices_count, raw_devices_count;
hkl = activate_keyboard_layout(MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), &hkl_orig); if (!hkl) return; @@ -165,6 +166,22 @@ static void acquire_tests(IDirectInputA *pDI, HWND hwnd) } keybd_event('Q', 0, KEYEVENTF_KEYUP, 0);
+ prev_raw_devices_count = 0; + GetRegisteredRawInputDevices(NULL, &prev_raw_devices_count, sizeof(RAWINPUTDEVICE)); + ok(prev_raw_devices_count == 0 || broken(prev_raw_devices_count == 1) /* wxppro, w2003std */, + "Unexpected raw devices registered: %d\n", prev_raw_devices_count); + + hr = IDirectInputDevice_Acquire(pKeyboard); + ok(SUCCEEDED(hr), "IDirectInputDevice_Acquire() failed: %08x\n", hr); + + raw_devices_count = 0; + GetRegisteredRawInputDevices(NULL, &raw_devices_count, sizeof(RAWINPUTDEVICE)); + ok(raw_devices_count == prev_raw_devices_count, + "Unexpected raw devices registered: %d\n", raw_devices_count); + + hr = IDirectInputDevice_Unacquire(pKeyboard); + ok(SUCCEEDED(hr), "IDirectInputDevice_Unacquire() failed: %08x\n", hr); + if (pKeyboard) IUnknown_Release(pKeyboard);
ActivateKeyboardLayout(hkl_orig, 0); -- 2.23.0.rc1
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput8/tests/device.c | 170 ++++++++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+)
diff --git a/dlls/dinput8/tests/device.c b/dlls/dinput8/tests/device.c index 1bfb34a1983..cd86289dd77 100644 --- a/dlls/dinput8/tests/device.c +++ b/dlls/dinput8/tests/device.c @@ -560,12 +560,182 @@ static void test_save_settings(void) IDirectInput_Release(pDI); }
+static void test_mouse_keyboard(void) +{ + HRESULT hr; + HWND hwnd, di_hwnd = INVALID_HANDLE_VALUE; + IDirectInput8A *di = NULL; + IDirectInputDevice8A *di_mouse, *di_keyboard; + UINT raw_devices_count; + RAWINPUTDEVICE raw_devices[3]; + + hwnd = CreateWindowExA(WS_EX_TOPMOST, "static", "dinput", WS_POPUP | WS_VISIBLE, 0, 0, 100, 100, NULL, NULL, NULL, NULL); + ok(hwnd != NULL, "CreateWindowExA failed\n"); + + hr = CoCreateInstance(&CLSID_DirectInput8, 0, CLSCTX_INPROC_SERVER, &IID_IDirectInput8A, (LPVOID*)&di); + if (hr == DIERR_OLDDIRECTINPUTVERSION || + hr == DIERR_BETADIRECTINPUTVERSION || + hr == REGDB_E_CLASSNOTREG) + { + win_skip("test_mouse_keyboard requires dinput8\n"); + return; + } + ok(SUCCEEDED(hr), "DirectInput8Create failed: %08x\n", hr); + + hr = IDirectInput8_Initialize(di, GetModuleHandleA(NULL), DIRECTINPUT_VERSION); + if (hr == DIERR_OLDDIRECTINPUTVERSION || hr == DIERR_BETADIRECTINPUTVERSION) + { + win_skip("test_mouse_keyboard requires dinput8\n"); + return; + } + ok(SUCCEEDED(hr), "IDirectInput8_Initialize failed: %08x\n", hr); + + hr = IDirectInput8_CreateDevice(di, &GUID_SysMouse, &di_mouse, NULL); + ok(SUCCEEDED(hr), "IDirectInput8_CreateDevice failed: %08x\n", hr); + hr = IDirectInputDevice8_SetDataFormat(di_mouse, &c_dfDIMouse); + ok(SUCCEEDED(hr), "IDirectInputDevice8_SetDataFormat failed: %08x\n", hr); + + hr = IDirectInput8_CreateDevice(di, &GUID_SysKeyboard, &di_keyboard, NULL); + ok(SUCCEEDED(hr), "IDirectInput8_CreateDevice failed: %08x\n", hr); + hr = IDirectInputDevice8_SetDataFormat(di_keyboard, &c_dfDIKeyboard); + ok(SUCCEEDED(hr), "IDirectInputDevice8_SetDataFormat failed: %08x\n", hr); + + raw_devices_count = ARRAY_SIZE(raw_devices); + GetRegisteredRawInputDevices(NULL, &raw_devices_count, sizeof(RAWINPUTDEVICE)); + todo_wine + ok(raw_devices_count == 0, "Unexpected raw devices registered: %d\n", raw_devices_count); + + hr = IDirectInputDevice8_Acquire(di_keyboard); + ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %08x\n", hr); + raw_devices_count = ARRAY_SIZE(raw_devices); + memset(raw_devices, 0, sizeof(raw_devices)); + hr = GetRegisteredRawInputDevices(raw_devices, &raw_devices_count, sizeof(RAWINPUTDEVICE)); + todo_wine + ok(hr == 1, "GetRegisteredRawInputDevices returned %d, raw_devices_count: %d\n", hr, raw_devices_count); + todo_wine + ok(raw_devices[0].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[0].usUsagePage); + todo_wine + ok(raw_devices[0].usUsage == 6, "Unexpected raw device usage: %x\n", raw_devices[0].usUsage); + todo_wine + ok(raw_devices[0].dwFlags == RIDEV_INPUTSINK, "Unexpected raw device flags: %x\n", raw_devices[0].dwFlags); + todo_wine + ok(raw_devices[0].hwndTarget != NULL, "Unexpected raw device target: %p\n", raw_devices[0].hwndTarget); + hr = IDirectInputDevice8_Unacquire(di_keyboard); + ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %08x\n", hr); + raw_devices_count = ARRAY_SIZE(raw_devices); + GetRegisteredRawInputDevices(NULL, &raw_devices_count, sizeof(RAWINPUTDEVICE)); + todo_wine + ok(raw_devices_count == 0, "Unexpected raw devices registered: %d\n", raw_devices_count); + + if (raw_devices[0].hwndTarget != NULL) + di_hwnd = raw_devices[0].hwndTarget; + + hr = IDirectInputDevice8_Acquire(di_mouse); + ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %08x\n", hr); + raw_devices_count = ARRAY_SIZE(raw_devices); + memset(raw_devices, 0, sizeof(raw_devices)); + hr = GetRegisteredRawInputDevices(raw_devices, &raw_devices_count, sizeof(RAWINPUTDEVICE)); + todo_wine + ok(hr == 1, "GetRegisteredRawInputDevices returned %d, raw_devices_count: %d\n", hr, raw_devices_count); + todo_wine + ok(raw_devices[0].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[0].usUsagePage); + todo_wine + ok(raw_devices[0].usUsage == 2, "Unexpected raw device usage: %x\n", raw_devices[0].usUsage); + todo_wine + ok(raw_devices[0].dwFlags == RIDEV_INPUTSINK, "Unexpected raw device flags: %x\n", raw_devices[0].dwFlags); + todo_wine + ok(raw_devices[0].hwndTarget == di_hwnd, "Unexpected raw device target: %p\n", raw_devices[0].hwndTarget); + hr = IDirectInputDevice8_Unacquire(di_mouse); + ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %08x\n", hr); + raw_devices_count = ARRAY_SIZE(raw_devices); + GetRegisteredRawInputDevices(NULL, &raw_devices_count, sizeof(RAWINPUTDEVICE)); + todo_wine + ok(raw_devices_count == 0, "Unexpected raw devices registered: %d\n", raw_devices_count); + + /* expect dinput8 to take over any activated raw input devices */ + raw_devices[0].usUsagePage = 0x01; + raw_devices[0].usUsage = 0x05; + raw_devices[0].dwFlags = 0; + raw_devices[0].hwndTarget = hwnd; + raw_devices[1].usUsagePage = 0x01; + raw_devices[1].usUsage = 0x06; + raw_devices[1].dwFlags = 0; + raw_devices[1].hwndTarget = hwnd; + raw_devices[2].usUsagePage = 0x01; + raw_devices[2].usUsage = 0x02; + raw_devices[2].dwFlags = 0; + raw_devices[2].hwndTarget = hwnd; + raw_devices_count = ARRAY_SIZE(raw_devices); + hr = RegisterRawInputDevices(raw_devices, raw_devices_count, sizeof(RAWINPUTDEVICE)); + ok(hr == TRUE, "RegisterRawInputDevices failed\n"); + + hr = IDirectInputDevice8_Acquire(di_keyboard); + ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %08x\n", hr); + hr = IDirectInputDevice8_Acquire(di_mouse); + ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %08x\n", hr); + raw_devices_count = ARRAY_SIZE(raw_devices); + memset(raw_devices, 0, sizeof(raw_devices)); + hr = GetRegisteredRawInputDevices(raw_devices, &raw_devices_count, sizeof(RAWINPUTDEVICE)); + todo_wine + ok(hr == 3, "GetRegisteredRawInputDevices returned %d, raw_devices_count: %d\n", hr, raw_devices_count); + todo_wine + ok(raw_devices[0].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[0].usUsagePage); + todo_wine + ok(raw_devices[0].usUsage == 2, "Unexpected raw device usage: %x\n", raw_devices[0].usUsage); + todo_wine + ok(raw_devices[0].dwFlags == RIDEV_INPUTSINK, "Unexpected raw device flags: %x\n", raw_devices[0].dwFlags); + todo_wine + ok(raw_devices[0].hwndTarget == di_hwnd, "Unexpected raw device target: %p\n", raw_devices[0].hwndTarget); + todo_wine + ok(raw_devices[1].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[1].usUsagePage); + todo_wine + ok(raw_devices[1].usUsage == 5, "Unexpected raw device usage: %x\n", raw_devices[1].usUsage); + ok(raw_devices[1].dwFlags == 0, "Unexpected raw device flags: %x\n", raw_devices[1].dwFlags); + todo_wine + ok(raw_devices[1].hwndTarget == hwnd, "Unexpected raw device target: %p\n", raw_devices[1].hwndTarget); + todo_wine + ok(raw_devices[2].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[1].usUsagePage); + todo_wine + ok(raw_devices[2].usUsage == 6, "Unexpected raw device usage: %x\n", raw_devices[1].usUsage); + todo_wine + ok(raw_devices[2].dwFlags == RIDEV_INPUTSINK, "Unexpected raw device flags: %x\n", raw_devices[1].dwFlags); + todo_wine + ok(raw_devices[2].hwndTarget == di_hwnd, "Unexpected raw device target: %p\n", raw_devices[1].hwndTarget); + hr = IDirectInputDevice8_Unacquire(di_keyboard); + ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %08x\n", hr); + hr = IDirectInputDevice8_Unacquire(di_mouse); + ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %08x\n", hr); + raw_devices_count = ARRAY_SIZE(raw_devices); + GetRegisteredRawInputDevices(NULL, &raw_devices_count, sizeof(RAWINPUTDEVICE)); + todo_wine + ok(raw_devices_count == 1, "Unexpected raw devices registered: %d\n", raw_devices_count); + + raw_devices_count = ARRAY_SIZE(raw_devices); + hr = GetRegisteredRawInputDevices(raw_devices, &raw_devices_count, sizeof(RAWINPUTDEVICE)); + todo_wine + ok(hr == 1, "GetRegisteredRawInputDevices returned %d, raw_devices_count: %d\n", hr, raw_devices_count); + todo_wine + ok(raw_devices[0].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[0].usUsagePage); + todo_wine + ok(raw_devices[0].usUsage == 5, "Unexpected raw device usage: %x\n", raw_devices[0].usUsage); + ok(raw_devices[0].dwFlags == 0, "Unexpected raw device flags: %x\n", raw_devices[0].dwFlags); + todo_wine + ok(raw_devices[0].hwndTarget == hwnd, "Unexpected raw device target: %p\n", raw_devices[0].hwndTarget); + + IDirectInputDevice8_Release(di_mouse); + IDirectInputDevice8_Release(di_keyboard); + IDirectInput8_Release(di); + + DestroyWindow(hwnd); +} + START_TEST(device) { CoInitialize(NULL);
test_action_mapping(); test_save_settings(); + test_mouse_keyboard();
CoUninitialize(); }
Signed-off-by: Rémi Bernon rbernon@codeweavers.com ---
Not sure if it is very useful to match native names, or even desirable?
dlls/dinput8/tests/device.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
diff --git a/dlls/dinput8/tests/device.c b/dlls/dinput8/tests/device.c index cd86289dd77..0bf6936812f 100644 --- a/dlls/dinput8/tests/device.c +++ b/dlls/dinput8/tests/device.c @@ -628,7 +628,20 @@ static void test_mouse_keyboard(void) ok(raw_devices_count == 0, "Unexpected raw devices registered: %d\n", raw_devices_count);
if (raw_devices[0].hwndTarget != NULL) + { + WCHAR di_hwnd_class[] = {'D','I','E','m','W','i','n',0}; + WCHAR str[16]; + int i; + di_hwnd = raw_devices[0].hwndTarget; + i = GetClassNameW(di_hwnd, str, ARRAY_SIZE(str)); + ok(i == lstrlenW(di_hwnd_class), "GetClassName returned incorrect length\n"); + ok(!lstrcmpW(di_hwnd_class, str), "GetClassName returned incorrect name for this window's class\n"); + + i = GetWindowTextW(di_hwnd, str, ARRAY_SIZE(str)); + ok(i == lstrlenW(di_hwnd_class), "GetClassName returned incorrect length\n"); + ok(!lstrcmpW(di_hwnd_class, str), "GetClassName returned incorrect name for this window's class\n"); + }
hr = IDirectInputDevice8_Acquire(di_mouse); ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %08x\n", hr); -- 2.23.0.rc1
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput8/tests/device.c | 13 --------- dlls/user32/rawinput.c | 55 +++++++++++++++++++++++++++++++++++-- server/protocol.def | 6 ++++ server/queue.c | 24 ++++++++++++++++ 4 files changed, 83 insertions(+), 15 deletions(-)
diff --git a/dlls/dinput8/tests/device.c b/dlls/dinput8/tests/device.c index 0bf6936812f..2b7814e3bbc 100644 --- a/dlls/dinput8/tests/device.c +++ b/dlls/dinput8/tests/device.c @@ -602,7 +602,6 @@ static void test_mouse_keyboard(void)
raw_devices_count = ARRAY_SIZE(raw_devices); GetRegisteredRawInputDevices(NULL, &raw_devices_count, sizeof(RAWINPUTDEVICE)); - todo_wine ok(raw_devices_count == 0, "Unexpected raw devices registered: %d\n", raw_devices_count);
hr = IDirectInputDevice8_Acquire(di_keyboard); @@ -624,7 +623,6 @@ static void test_mouse_keyboard(void) ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %08x\n", hr); raw_devices_count = ARRAY_SIZE(raw_devices); GetRegisteredRawInputDevices(NULL, &raw_devices_count, sizeof(RAWINPUTDEVICE)); - todo_wine ok(raw_devices_count == 0, "Unexpected raw devices registered: %d\n", raw_devices_count);
if (raw_devices[0].hwndTarget != NULL) @@ -662,7 +660,6 @@ static void test_mouse_keyboard(void) ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %08x\n", hr); raw_devices_count = ARRAY_SIZE(raw_devices); GetRegisteredRawInputDevices(NULL, &raw_devices_count, sizeof(RAWINPUTDEVICE)); - todo_wine ok(raw_devices_count == 0, "Unexpected raw devices registered: %d\n", raw_devices_count);
/* expect dinput8 to take over any activated raw input devices */ @@ -689,26 +686,18 @@ static void test_mouse_keyboard(void) raw_devices_count = ARRAY_SIZE(raw_devices); memset(raw_devices, 0, sizeof(raw_devices)); hr = GetRegisteredRawInputDevices(raw_devices, &raw_devices_count, sizeof(RAWINPUTDEVICE)); - todo_wine ok(hr == 3, "GetRegisteredRawInputDevices returned %d, raw_devices_count: %d\n", hr, raw_devices_count); - todo_wine ok(raw_devices[0].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[0].usUsagePage); - todo_wine ok(raw_devices[0].usUsage == 2, "Unexpected raw device usage: %x\n", raw_devices[0].usUsage); todo_wine ok(raw_devices[0].dwFlags == RIDEV_INPUTSINK, "Unexpected raw device flags: %x\n", raw_devices[0].dwFlags); todo_wine ok(raw_devices[0].hwndTarget == di_hwnd, "Unexpected raw device target: %p\n", raw_devices[0].hwndTarget); - todo_wine ok(raw_devices[1].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[1].usUsagePage); - todo_wine ok(raw_devices[1].usUsage == 5, "Unexpected raw device usage: %x\n", raw_devices[1].usUsage); ok(raw_devices[1].dwFlags == 0, "Unexpected raw device flags: %x\n", raw_devices[1].dwFlags); - todo_wine ok(raw_devices[1].hwndTarget == hwnd, "Unexpected raw device target: %p\n", raw_devices[1].hwndTarget); - todo_wine ok(raw_devices[2].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[1].usUsagePage); - todo_wine ok(raw_devices[2].usUsage == 6, "Unexpected raw device usage: %x\n", raw_devices[1].usUsage); todo_wine ok(raw_devices[2].dwFlags == RIDEV_INPUTSINK, "Unexpected raw device flags: %x\n", raw_devices[1].dwFlags); @@ -727,12 +716,10 @@ static void test_mouse_keyboard(void) hr = GetRegisteredRawInputDevices(raw_devices, &raw_devices_count, sizeof(RAWINPUTDEVICE)); todo_wine ok(hr == 1, "GetRegisteredRawInputDevices returned %d, raw_devices_count: %d\n", hr, raw_devices_count); - todo_wine ok(raw_devices[0].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[0].usUsagePage); todo_wine ok(raw_devices[0].usUsage == 5, "Unexpected raw device usage: %x\n", raw_devices[0].usUsage); ok(raw_devices[0].dwFlags == 0, "Unexpected raw device flags: %x\n", raw_devices[0].dwFlags); - todo_wine ok(raw_devices[0].hwndTarget == hwnd, "Unexpected raw device target: %p\n", raw_devices[0].hwndTarget);
IDirectInputDevice8_Release(di_mouse); diff --git a/dlls/user32/rawinput.c b/dlls/user32/rawinput.c index 49cf9f73a0d..cb03a6553a6 100644 --- a/dlls/user32/rawinput.c +++ b/dlls/user32/rawinput.c @@ -469,14 +469,65 @@ UINT WINAPI GetRawInputDeviceInfoW(HANDLE device, UINT command, void *data, UINT return s; }
+static int compare_raw_input_devices(const void *ap, const void *bp) +{ + const RAWINPUTDEVICE a = *(const RAWINPUTDEVICE *)ap; + const RAWINPUTDEVICE b = *(const RAWINPUTDEVICE *)bp; + + if (a.usUsagePage != b.usUsagePage) return a.usUsagePage - b.usUsagePage; + if (a.usUsage != b.usUsage) return a.usUsage - b.usUsage; + return 0; +} + /*********************************************************************** * GetRegisteredRawInputDevices (USER32.@) */ UINT WINAPI DECLSPEC_HOTPATCH GetRegisteredRawInputDevices(RAWINPUTDEVICE *devices, UINT *device_count, UINT size) { - FIXME("devices %p, device_count %p, size %u stub!\n", devices, device_count, size); + struct rawinput_device *d = NULL; + unsigned int count = ~0U;
- return 0; + TRACE("devices %p, device_count %p, size %u\n", devices, device_count, size); + + if (!device_count) + { + SetLastError(ERROR_INVALID_PARAMETER); + return ~0U; + } + + if (devices && !(d = HeapAlloc( GetProcessHeap(), 0, *device_count * sizeof(*d) ))) + return ~0U; + + SERVER_START_REQ( get_rawinput_devices ) + { + if (d) + wine_server_set_reply( req, d, *device_count * sizeof(*d) ); + + if (wine_server_call( req )) + goto done; + + if (!d || reply->device_count > *device_count) + { + *device_count = reply->device_count; + SetLastError( ERROR_INSUFFICIENT_BUFFER ); + goto done; + } + + for (count = 0; count < reply->device_count; ++count) + { + devices[count].usUsagePage = d[count].usage_page; + devices[count].usUsage = d[count].usage; + devices[count].dwFlags = d[count].flags; + devices[count].hwndTarget = wine_server_ptr_handle(d[count].target); + } + } + SERVER_END_REQ; + + qsort(devices, count, sizeof(*devices), compare_raw_input_devices); + +done: + if (d) HeapFree( GetProcessHeap(), 0, d ); + return count; }
diff --git a/server/protocol.def b/server/protocol.def index 6af0ae0cff8..2647e87f1fe 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -3864,6 +3864,12 @@ struct handle_info VARARG(devices,rawinput_devices); @END
+/* Retrieve the list of registered rawinput devices */ +@REQ(get_rawinput_devices) +@REPLY + unsigned int device_count; + VARARG(devices,rawinput_devices); +@END
/* Retrieve the suspended context of a thread */ @REQ(get_suspend_context) diff --git a/server/queue.c b/server/queue.c index 96587d11d1e..6207fdb1f7c 100644 --- a/server/queue.c +++ b/server/queue.c @@ -3123,3 +3123,27 @@ DECL_HANDLER(update_rawinput_devices) e = find_rawinput_device( 1, 6 ); current->process->rawinput_kbd = e ? &e->device : NULL; } + +DECL_HANDLER(get_rawinput_devices) +{ + unsigned int device_count = list_count(¤t->process->rawinput_devices); + struct rawinput_device *devices; + struct rawinput_device_entry *e; + unsigned int i; + + reply->device_count = device_count; + if (get_reply_max_size() / sizeof (*devices) < device_count) + return; + + if (!(devices = mem_alloc( device_count * sizeof (*devices) ))) + { + set_error( STATUS_NO_MEMORY ); + return; + } + + i = 0; + LIST_FOR_EACH_ENTRY( e, ¤t->process->rawinput_devices, struct rawinput_device_entry, entry ) + devices[i++] = e->device; + + set_reply_data_ptr( devices, device_count * sizeof (*devices) ); +}
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=55813
Your paranoid android.
=== debian10 (32 bit report) ===
user32: msg.c:5145: Test succeeded inside todo block: ShowWindow(SW_SHOWMINIMIZED):overlapped: marked "todo_wine" but succeeds
Report errors: user32:msg prints too much data (35221 bytes)
=== debian10 (32 bit Chinese:China report) ===
user32: msg.c:5145: Test succeeded inside todo block: ShowWindow(SW_SHOWMINIMIZED):overlapped: marked "todo_wine" but succeeds
Report errors: user32:msg prints too much data (35221 bytes)
=== debian10 (32 bit WoW report) ===
user32: msg.c:5145: Test succeeded inside todo block: ShowWindow(SW_SHOWMINIMIZED):overlapped: marked "todo_wine" but succeeds
Report errors: user32:msg prints too much data (35221 bytes)
=== debian10 (64 bit WoW report) ===
user32: msg.c:5145: Test succeeded inside todo block: ShowWindow(SW_SHOWMINIMIZED):overlapped: marked "todo_wine" but succeeds
Report errors: user32:msg prints too much data (35221 bytes)
On 8/27/19 1:03 AM, Marvin wrote:
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=55813
Your paranoid android.
=== debian10 (32 bit report) ===
user32: msg.c:5145: Test succeeded inside todo block: ShowWindow(SW_SHOWMINIMIZED):overlapped: marked "todo_wine" but succeeds
Report errors: user32:msg prints too much data (35221 bytes)
=== debian10 (32 bit Chinese:China report) ===
user32: msg.c:5145: Test succeeded inside todo block: ShowWindow(SW_SHOWMINIMIZED):overlapped: marked "todo_wine" but succeeds
Report errors: user32:msg prints too much data (35221 bytes)
=== debian10 (32 bit WoW report) ===
user32: msg.c:5145: Test succeeded inside todo block: ShowWindow(SW_SHOWMINIMIZED):overlapped: marked "todo_wine" but succeeds
Report errors: user32:msg prints too much data (35221 bytes)
=== debian10 (64 bit WoW report) ===
user32: msg.c:5145: Test succeeded inside todo block: ShowWindow(SW_SHOWMINIMIZED):overlapped: marked "todo_wine" but succeeds
Report errors: user32:msg prints too much data (35221 bytes)
I don't see how this is related. Also, it looks like from the full logs that the test is actually failing but is reported as succeeding inside todo, which is weird.
When testing on my side the user32 msg tests are triggering a crash in mutter, but work fine with openbox (and do not report any failure for this patch). Wouldn't it be better to use openbox - or any other WM that doesn't crash spuriously - for the automated regression tests?
On Tue, 27 Aug 2019, Rémi Bernon wrote: [...]
=== debian10 (32 bit report) ===
user32: msg.c:5145: Test succeeded inside todo block: ShowWindow(SW_SHOWMINIMIZED):overlapped: marked "todo_wine" but succeeds
Report errors: user32:msg prints too much data (35221 bytes)
[...]
I don't see how this is related. Also, it looks like from the full logs that the test is actually failing but is reported as succeeding inside todo, which is weird.
There are two issues: * The "too much data" one is not related to your patch specifically. It's an error that gets added by the TestBot on tests that print too much data, such as user32:msg has been doing for a long time.
The issue there is that on Linux the WineTest results are already very close to the 1.5 MB limit. With over 600 tests that's about 2.5 KB / test. So tests that print over 32 KB are taking way more than their fair share and get identified as such in the hope that we at least not introduce new hogs and hopefully eventually fix the existing ones (hint, hint).
* The second issue is that if an ok() call succeeds in a todo_wine then that todo_wine should be removed. So the patch is wrong and needs to be fixed. Of course if the specific ok() call fails randomly then... I guess the test needs to be fixed again so back to square one. It does become a real problem when the failure depends on the Unix platform though.
This specific ShowWindow(SW_SHOWMINIMIZED) ok() call seems to fail pretty systematically and as such should have been treated as a preexisting failure. However it looks like a full WineTest run has not been done since the 23rd, which typically happens when the official WineTest.exe fails to build. Maybe that's why the failure was not detected as a preexisting one.
(Removing the TestBot's dependency on this external WineTest.exe build is on my todo list)
When testing on my side the user32 msg tests are triggering a crash in mutter, but work fine with openbox (and do not report any failure for this patch). Wouldn't it be better to use openbox - or any other WM that doesn't crash spuriously - for the automated regression tests?
The Debian TestBot VMs use fvwm precisely because neither the GNOME nor the KDE window managers are up to the task (they not only used to crash but also mishandled various test cases).
I don't see any evidence that fvwm crashed in the logs and the screenshot looks normal barring the tiny window in the top-left corner (but that might be a left-over from the test, maybe due to the failures?). I'm not a specialist on these things so maybe I missed the telltale signs.
Note that the screen being blank is normal, it's a very basic fvwm configuration. I guess it can be confusing and does make it harder to see if the window manager crashed. Maybe the TestBot should put up a window saying 'This screen intentionally left blank' ;-)
Yes that's alright, I initially thought the failure was caused by a crash, as I experienced one for these tests, but after trying again with openbox it looks like this test sequence randomly succeeds although it is expected not to.
I'm relieved to learn that mutter is not used for testing :)
On Tue, 27 Aug 2019, Rémi Bernon wrote: [...]
I'm relieved to learn that mutter is not used for testing :)
I think it's an often overlooked feature; one can get information about the test VMs configuration in two places:
* On the VM selection page when submitting a job: click on the short VM description (such as Debian 10 / vm4) in the Description column.
* And similarly on the test result page in each VM section clicking on the short description will similarly reveal more details.
For instance clicking on "Debian 10 / vm4" shows the following:
Debian 10 configured for Wine. Runs fvwm. [CPU:4*host RAM:4GB disk:virtio-scsi eth:virtio snd:ich6 GPU:qxl display:spice testagentd:1.7] Missions: win32,test=module:win32,lang=fr_FR:win32,lang=ja_JP:win32,test=module,lang=zh_CN
The first line describes the software and hardware configuration of the VM. If more information about the software side would be useful I could add some more.
The second line describes the tests that the VM is configured to perform. It's a colon separated list. * win32,test=module The VM will perform tests in a regular 32 bit Wine build (so not a Windows on Windows setup) and that if a patch touches a module, such as user32, then all of that module's tests should be rerun. This is meant to detect test breakage caused by changes in the Wine implementation.
* win32,lang=fr_FR and win32,lang=ja_JP Same build but in a French and Japanese locale respectively. And since 'test' is not specified it means a test is only run if it is patched directly.
* win32,test=module,lang=zh_CN Still the same build but in a Chinese locale and again running all of a dll's tests if that dll is patched. This helps provide a minimum level of locale testing when patching Wine dlls but it can also be helpful to detect random failures for tests that don't depend on locales.
Each of these tests is run in its own wineprefix so they are mostly independent. But they run out of the same account on the same X session so if a test borks the X server it would impact the ones that come after.
This adds a global message window that will receive WM_INPUT messages, dispatched to every raw input device event_proc.
Devices that use raw input interface will not register low-level hooks anymore. They will also conflict with any raw input device registered outside of dinput, as exposed by the unit tests.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput/device_private.h | 3 ++ dlls/dinput/dinput_main.c | 79 +++++++++++++++++++++++++++++++++++- 2 files changed, 81 insertions(+), 1 deletion(-)
diff --git a/dlls/dinput/device_private.h b/dlls/dinput/device_private.h index d9e2997eaaf..4ba37c8ddff 100644 --- a/dlls/dinput/device_private.h +++ b/dlls/dinput/device_private.h @@ -70,6 +70,9 @@ struct IDirectInputDeviceImpl int acquired; DI_EVENT_PROC event_proc; /* function to receive mouse & keyboard events */
+ BOOL use_raw_input; /* use raw input instead of low-level messages */ + RAWINPUTDEVICE raw_device; /* raw device to (un)register */ + LPDIDEVICEOBJECTDATA data_queue; /* buffer for 'GetDeviceData'. */ int queue_len; /* size of the queue - set in 'SetProperty' */ int queue_head; /* position to write new event into queue */ diff --git a/dlls/dinput/dinput_main.c b/dlls/dinput/dinput_main.c index 0855cb41cd5..4fd0b9cc5a9 100644 --- a/dlls/dinput/dinput_main.c +++ b/dlls/dinput/dinput_main.c @@ -97,6 +97,10 @@ static const struct dinput_device *dinput_devices[] =
HINSTANCE DINPUT_instance;
+static ATOM di_em_win_class; +static const WCHAR di_em_winW[] = {'D','I','E','m','W','i','n',0}; +static HWND di_em_win; + static BOOL check_hook_thread(void); static CRITICAL_SECTION dinput_hook_crit; static struct list direct_input_list = LIST_INIT( direct_input_list ); @@ -611,6 +615,59 @@ static HRESULT WINAPI IDirectInputWImpl_QueryInterface(LPDIRECTINPUT7W iface, RE return IDirectInputAImpl_QueryInterface( &This->IDirectInput7A_iface, riid, ppobj ); }
+static LRESULT WINAPI di_em_win_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) +{ + IDirectInputImpl *dinput; + + TRACE( "%p %d %lx %lx\n", hwnd, msg, wparam, lparam ); + + if (msg == WM_INPUT) + { + EnterCriticalSection( &dinput_hook_crit ); + LIST_FOR_EACH_ENTRY( dinput, &direct_input_list, IDirectInputImpl, entry ) + { + IDirectInputDeviceImpl *dev; + + EnterCriticalSection( &dinput->crit ); + LIST_FOR_EACH_ENTRY( dev, &dinput->devices_list, IDirectInputDeviceImpl, entry ) + { + if (dev->acquired && dev->event_proc && dev->use_raw_input) + { + TRACE("calling %p->%p (%lx %lx)\n", dev, dev->event_proc, wparam, lparam); + dev->event_proc( &dev->IDirectInputDevice8A_iface, GET_RAWINPUT_CODE_WPARAM(wparam), lparam ); + } + } + LeaveCriticalSection( &dinput->crit ); + } + LeaveCriticalSection( &dinput_hook_crit ); + } + + return DefWindowProcW(hwnd, msg, wparam, lparam); +} + +static void register_di_em_win_class(void) +{ + static WNDCLASSEXW class; + + ZeroMemory(&class, sizeof(class)); + class.cbSize = sizeof(class); + class.lpfnWndProc = di_em_win_wndproc; + class.hInstance = DINPUT_instance; + class.lpszClassName = di_em_winW; + + if (!(di_em_win_class = RegisterClassExW( &class ))) + WARN( "Unable to register message window class\n" ); +} + +static void unregister_di_em_win_class(void) +{ + if (!di_em_win_class) + return; + + if (!UnregisterClassW( MAKEINTRESOURCEW( di_em_win_class ), DINPUT_instance )) + WARN( "Unable to unregister message window class\n" ); +} + static HRESULT initialize_directinput_instance(IDirectInputImpl *This, DWORD dwVersion) { if (!This->initialized) @@ -1706,6 +1763,9 @@ static DWORD WINAPI hook_thread_proc(void *param) static HHOOK kbd_hook, mouse_hook; MSG msg;
+ di_em_win = CreateWindowW( MAKEINTRESOURCEW(di_em_win_class), di_em_winW, + 0, 0, 0, 0, 0, HWND_MESSAGE, 0, DINPUT_instance, NULL ); + /* Force creation of the message queue */ PeekMessageW( &msg, 0, 0, 0, PM_NOREMOVE ); SetEvent(param); @@ -1738,7 +1798,7 @@ static DWORD WINAPI hook_thread_proc(void *param) EnterCriticalSection( &dinput->crit ); LIST_FOR_EACH_ENTRY( dev, &dinput->devices_list, IDirectInputDeviceImpl, entry ) { - if (!dev->acquired || !dev->event_proc) continue; + if (!dev->acquired || !dev->event_proc || dev->use_raw_input) continue;
if (IsEqualGUID( &dev->guid, &GUID_SysKeyboard )) kbd_cnt++; @@ -1770,6 +1830,9 @@ static DWORD WINAPI hook_thread_proc(void *param) DispatchMessageW(&msg); }
+ DestroyWindow( di_em_win ); + di_em_win = NULL; + FreeLibraryAndExitThread(DINPUT_instance, 0); }
@@ -1851,6 +1914,18 @@ void check_dinput_hooks(LPDIRECTINPUTDEVICE8W iface, BOOL acquired) hook_thread_event = NULL; }
+ if (dev->use_raw_input) + { + if (acquired) + dev->raw_device.dwFlags = RIDEV_INPUTSINK; + else + dev->raw_device.dwFlags = RIDEV_REMOVE; + dev->raw_device.hwndTarget = di_em_win; + + if (!RegisterRawInputDevices( &dev->raw_device, 1, sizeof(RAWINPUTDEVICE) )) + WARN( "Unable to (un)register raw device %x:%x\n", dev->raw_device.usUsagePage, dev->raw_device.usUsage ); + } + PostThreadMessageW( hook_thread_id, WM_USER+0x10, 1, 0 );
LeaveCriticalSection(&dinput_hook_crit); @@ -1877,9 +1952,11 @@ BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved) case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(inst); DINPUT_instance = inst; + register_di_em_win_class(); break; case DLL_PROCESS_DETACH: if (reserved) break; + unregister_di_em_win_class(); DeleteCriticalSection(&dinput_hook_crit); break; }
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=55814
Your paranoid android.
=== debian10 (32 bit report) ===
dinput: mouse.c:173: Test failed: GetDeviceData() failed: 00000000 cnt:0
user32: msg.c:5145: Test succeeded inside todo block: ShowWindow(SW_SHOWMINIMIZED):overlapped: marked "todo_wine" but succeeds
Report errors: user32:msg prints too much data (35221 bytes)
=== debian10 (32 bit Chinese:China report) ===
dinput: mouse.c:173: Test failed: GetDeviceData() failed: 00000000 cnt:0
user32: msg.c:5145: Test succeeded inside todo block: ShowWindow(SW_SHOWMINIMIZED):overlapped: marked "todo_wine" but succeeds
Report errors: user32:msg prints too much data (35221 bytes)
=== debian10 (32 bit WoW report) ===
dinput: mouse.c:173: Test failed: GetDeviceData() failed: 00000000 cnt:0
user32: msg.c:5145: Test succeeded inside todo block: ShowWindow(SW_SHOWMINIMIZED):overlapped: marked "todo_wine" but succeeds win.c:10097: Test failed: GetForegroundWindow() = 000E0120
Report errors: user32:msg prints too much data (35221 bytes)
=== debian10 (64 bit WoW report) ===
dinput: mouse.c:173: Test failed: GetDeviceData() failed: 00000000 cnt:0
user32: msg.c:5145: Test succeeded inside todo block: ShowWindow(SW_SHOWMINIMIZED):overlapped: marked "todo_wine" but succeeds
Report errors: user32:msg prints too much data (35221 bytes)
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput/keyboard.c | 88 ++++++++++++++++++++++++++++++------- dlls/dinput8/tests/device.c | 7 --- 2 files changed, 72 insertions(+), 23 deletions(-)
diff --git a/dlls/dinput/keyboard.c b/dlls/dinput/keyboard.c index b5e665933ec..0f3d85a0ecc 100644 --- a/dlls/dinput/keyboard.c +++ b/dlls/dinput/keyboard.c @@ -107,28 +107,77 @@ static int KeyboardCallback( LPDIRECTINPUTDEVICE8A iface, WPARAM wparam, LPARAM { SysKeyboardImpl *This = impl_from_IDirectInputDevice8A(iface); int dik_code, ret = This->base.dwCoopLevel & DISCL_EXCLUSIVE; - KBDLLHOOKSTRUCT *hook = (KBDLLHOOKSTRUCT *)lparam; + KBDLLHOOKSTRUCT *hook; BYTE new_diks;
- if (wparam != WM_KEYDOWN && wparam != WM_KEYUP && - wparam != WM_SYSKEYDOWN && wparam != WM_SYSKEYUP) - return 0; + if (wparam == RIM_INPUT || wparam == RIM_INPUTSINK) + { + RAWINPUTHEADER raw_header; + RAWINPUT raw_input; + UINT size; + + TRACE("(%p) wp %08lx, lp %08lx\n", iface, wparam, lparam); + + size = sizeof(raw_header); + if (GetRawInputData( (HRAWINPUT)lparam, RID_HEADER, &raw_header, &size, sizeof(RAWINPUTHEADER) ) != sizeof(raw_header)) + { + WARN( "Unable to read raw input data header\n" ); + return 0; + } + + if (raw_header.dwType != RIM_TYPEKEYBOARD) + return 0;
- TRACE("(%p) wp %08lx, lp %08lx, vk %02x, scan %02x\n", - iface, wparam, lparam, hook->vkCode, hook->scanCode); + if (raw_header.dwSize > sizeof(raw_input)) + { + WARN( "Unexpected size for keyboard raw input data\n" ); + return 0; + } + + size = raw_header.dwSize; + if (GetRawInputData( (HRAWINPUT)lparam, RID_INPUT, &raw_input, &size, sizeof(RAWINPUTHEADER) ) != raw_header.dwSize ) + { + WARN( "Unable to read raw input data\n" ); + return 0; + }
- switch (hook->vkCode) + switch (raw_input.data.keyboard.VKey) + { + /* R-Shift is special - it is an extended key with separate scan code */ + case VK_RSHIFT: dik_code = DIK_RSHIFT; break; + case VK_PAUSE: dik_code = DIK_PAUSE; break; + case VK_NUMLOCK: dik_code = DIK_NUMLOCK; break; + case VK_SUBTRACT: dik_code = DIK_SUBTRACT; break; + default: + dik_code = map_dik_code(0, raw_input.data.keyboard.VKey, This->subtype); + if (raw_input.data.keyboard.Flags & RI_KEY_E0) dik_code |= 0x80; + } + new_diks = (raw_input.data.keyboard.Flags & RI_KEY_BREAK) ? 0 : 0x80; + } + else { - /* R-Shift is special - it is an extended key with separate scan code */ - case VK_RSHIFT : dik_code = DIK_RSHIFT; break; - case VK_PAUSE : dik_code = DIK_PAUSE; break; - case VK_NUMLOCK : dik_code = DIK_NUMLOCK; break; - case VK_SUBTRACT: dik_code = DIK_SUBTRACT; break; - default: - dik_code = map_dik_code(hook->scanCode & 0xff, hook->vkCode, This->subtype); - if (hook->flags & LLKHF_EXTENDED) dik_code |= 0x80; + if (wparam != WM_KEYDOWN && wparam != WM_KEYUP && + wparam != WM_SYSKEYDOWN && wparam != WM_SYSKEYUP) + return 0; + + hook = (KBDLLHOOKSTRUCT *)lparam; + + TRACE("(%p) wp %08lx, lp %08lx, vk %02x, scan %02x\n", + iface, wparam, lparam, hook->vkCode, hook->scanCode); + + switch (hook->vkCode) + { + /* R-Shift is special - it is an extended key with separate scan code */ + case VK_RSHIFT : dik_code = DIK_RSHIFT; break; + case VK_PAUSE : dik_code = DIK_PAUSE; break; + case VK_NUMLOCK : dik_code = DIK_NUMLOCK; break; + case VK_SUBTRACT: dik_code = DIK_SUBTRACT; break; + default: + dik_code = map_dik_code(hook->scanCode & 0xff, hook->vkCode, This->subtype); + if (hook->flags & LLKHF_EXTENDED) dik_code |= 0x80; + } + new_diks = hook->flags & LLKHF_UP ? 0 : 0x80; } - new_diks = hook->flags & LLKHF_UP ? 0 : 0x80;
/* returns now if key event already known */ if (new_diks == This->DInputKeyState[dik_code]) @@ -295,6 +344,13 @@ static SysKeyboardImpl *alloc_device(REFGUID rguid, IDirectInputImpl *dinput) list_add_tail(&dinput->devices_list, &newDevice->base.entry); LeaveCriticalSection(&dinput->crit);
+ if (dinput->dwVersion >= DIRECTINPUT_VERSION) + { + newDevice->base.use_raw_input = TRUE; + newDevice->base.raw_device.usUsagePage = 1; /* HID generic device page */ + newDevice->base.raw_device.usUsage = 6; /* HID generic keyboard */ + } + return newDevice;
failed: diff --git a/dlls/dinput8/tests/device.c b/dlls/dinput8/tests/device.c index 2b7814e3bbc..9f2d0dbd29a 100644 --- a/dlls/dinput8/tests/device.c +++ b/dlls/dinput8/tests/device.c @@ -609,15 +609,10 @@ static void test_mouse_keyboard(void) raw_devices_count = ARRAY_SIZE(raw_devices); memset(raw_devices, 0, sizeof(raw_devices)); hr = GetRegisteredRawInputDevices(raw_devices, &raw_devices_count, sizeof(RAWINPUTDEVICE)); - todo_wine ok(hr == 1, "GetRegisteredRawInputDevices returned %d, raw_devices_count: %d\n", hr, raw_devices_count); - todo_wine ok(raw_devices[0].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[0].usUsagePage); - todo_wine ok(raw_devices[0].usUsage == 6, "Unexpected raw device usage: %x\n", raw_devices[0].usUsage); - todo_wine ok(raw_devices[0].dwFlags == RIDEV_INPUTSINK, "Unexpected raw device flags: %x\n", raw_devices[0].dwFlags); - todo_wine ok(raw_devices[0].hwndTarget != NULL, "Unexpected raw device target: %p\n", raw_devices[0].hwndTarget); hr = IDirectInputDevice8_Unacquire(di_keyboard); ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %08x\n", hr); @@ -699,9 +694,7 @@ static void test_mouse_keyboard(void) ok(raw_devices[1].hwndTarget == hwnd, "Unexpected raw device target: %p\n", raw_devices[1].hwndTarget); ok(raw_devices[2].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[1].usUsagePage); ok(raw_devices[2].usUsage == 6, "Unexpected raw device usage: %x\n", raw_devices[1].usUsage); - todo_wine ok(raw_devices[2].dwFlags == RIDEV_INPUTSINK, "Unexpected raw device flags: %x\n", raw_devices[1].dwFlags); - todo_wine ok(raw_devices[2].hwndTarget == di_hwnd, "Unexpected raw device target: %p\n", raw_devices[1].hwndTarget); hr = IDirectInputDevice8_Unacquire(di_keyboard); ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %08x\n", hr);
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=55815
Your paranoid android.
=== debian10 (32 bit report) ===
dinput: keyboard.c:154: Test failed: Keyboard event not processed, skipping test keyboard.c:171: Test failed: Unexpected raw devices registered: 1 mouse.c:173: Test failed: GetDeviceData() failed: 00000000 cnt:0
user32: menu.c:2354: Test failed: test 30 menu: Timeout msg.c:5145: Test succeeded inside todo block: ShowWindow(SW_SHOWMINIMIZED):overlapped: marked "todo_wine" but succeeds
Report errors: user32:msg prints too much data (35222 bytes)
=== debian10 (32 bit Chinese:China report) ===
dinput: keyboard.c:154: Test failed: Keyboard event not processed, skipping test keyboard.c:171: Test failed: Unexpected raw devices registered: 1 mouse.c:173: Test failed: GetDeviceData() failed: 00000000 cnt:0
user32: clipboard.c:1383: Test failed: gle 5 clipboard.c:1385: Test failed: gle 1418 clipboard.c:1388: Test failed: got 00000000 clipboard.c:1389: Test failed: expected moveable mem 00000000 clipboard.c:1391: Test failed: got 00000000 clipboard.c:1392: Test failed: expected moveable mem 00000000 clipboard.c:1395: Test failed: got 00000000 clipboard.c:1396: Test failed: expected bitmap 00000000 clipboard.c:1398: Test failed: got 00000000 clipboard.c:1399: Test failed: expected bitmap 00000000 clipboard.c:1400: Test failed: expected free object 000E0043 clipboard.c:1402: Test failed: got 00000000 clipboard.c:1403: Test failed: expected bitmap 00000000 clipboard.c:1405: Test failed: got 00000000 clipboard.c:1406: Test failed: expected palette 00000000 clipboard.c:1408: Test failed: got 00000000 clipboard.c:1409: Test failed: expected moveable mem 00000000 clipboard.c:1411: Test failed: got 00000000 clipboard.c:1412: Test failed: expected moveable mem 00000000 clipboard.c:1426: Test failed: got 00000000 clipboard.c:1427: Test failed: expected fixed mem 00000000 clipboard.c:1429: Test failed: got 00000000 clipboard.c:1430: Test failed: expected fixed mem 00000000 clipboard.c:1432: Test failed: got 00000000 clipboard.c:1433: Test failed: expected moveable mem 00000000 clipboard.c:1445: Test failed: wrong data 00000000 clipboard.c:1446: Test failed: expected moveable mem 00000000 clipboard.c:1449: Test failed: wrong data 00000000, cf 0000c040 clipboard.c:1450: Test failed: expected moveable mem 00000000 clipboard.c:1453: Test failed: wrong data 00000000 clipboard.c:1454: Test failed: expected moveable mem 00000000 clipboard.c:1457: Test failed: wrong data 00000000 clipboard.c:1458: Test failed: expected moveable mem 00000000 clipboard.c:1461: Test failed: wrong data 00000000 clipboard.c:1462: Test failed: expected fixed mem 00000000 clipboard.c:1465: Test failed: wrong data 00000000 clipboard.c:1466: Test failed: expected fixed mem 00000000 clipboard.c:1469: Test failed: wrong data 00000000 clipboard.c:1470: Test failed: expected moveable mem 00000000 clipboard.c:1476: Test failed: got 00000000 clipboard.c:1477: Test failed: expected moveable mem 00000000 clipboard.c:1478: Test failed: expected freed mem 0012701A clipboard.c:1481: Test failed: got 00000000 clipboard.c:1482: Test failed: expected fixed mem 00000000 clipboard.c:1487: Test failed: gle 1418 clipboard.c:1550: Test failed: wrong data 00000000 clipboard.c:1553: Test failed: wrong data 00000000, cf 0000c040 clipboard.c:1556: Test failed: wrong data 00000000 clipboard.c:1559: Test failed: wrong data 00000000 clipboard.c:1562: Test failed: wrong data 00000000 clipboard.c:1565: Test failed: wrong data 00000000 clipboard.c:1568: Test failed: wrong data 00000000 clipboard.c:1575: Test failed: expected fixed mem 00000000 clipboard.c:1577: Test failed: expected fixed mem 00000000 clipboard.c:1579: Test failed: expected fixed mem 00000000 clipboard.c:1581: Test failed: expected bitmap 00000000 clipboard.c:1583: Test failed: expected bitmap 00000000 clipboard.c:1585: Test failed: expected palette 00000000 clipboard.c:1587: Test failed: expected fixed mem 00000000 clipboard.c:1589: Test failed: expected fixed mem 00000000 clipboard.c:1601: Test failed: expected freed mem 0012579A clipboard.c:1602: Test failed: expected freed mem 0012B16A clipboard.c:1603: Test failed: expected freed mem 0012C9FA clipboard.c:1604: Test failed: expected freed mem 0012CA32 clipboard.c:1605: Test failed: expected freed mem 001295F2 clipboard.c:1608: Test failed: expected freed handle 000B0041 clipboard.c:1609: Test failed: expected freed handle 000A0045 clipboard.c:1610: Test failed: expected freed handle 0045003F msg.c:5145: Test succeeded inside todo block: ShowWindow(SW_SHOWMINIMIZED):overlapped: marked "todo_wine" but succeeds
Report errors: user32:msg prints too much data (35221 bytes)
=== debian10 (32 bit WoW report) ===
dinput: keyboard.c:154: Test failed: Keyboard event not processed, skipping test keyboard.c:171: Test failed: Unexpected raw devices registered: 1 mouse.c:173: Test failed: GetDeviceData() failed: 00000000 cnt:0
user32: msg.c:5145: Test succeeded inside todo block: ShowWindow(SW_SHOWMINIMIZED):overlapped: marked "todo_wine" but succeeds
Report errors: user32:msg prints too much data (35221 bytes)
=== debian10 (64 bit WoW report) ===
dinput: keyboard.c:154: Test failed: Keyboard event not processed, skipping test keyboard.c:171: Test failed: Unexpected raw devices registered: 1 mouse.c:173: Test failed: GetDeviceData() failed: 00000000 cnt:0
user32: msg.c:5145: Test succeeded inside todo block: ShowWindow(SW_SHOWMINIMIZED):overlapped: marked "todo_wine" but succeeds
Report errors: user32:msg prints too much data (35221 bytes)
@@ -295,6 +344,13 @@ static SysKeyboardImpl *alloc_device(REFGUID rguid, IDirectInputImpl *dinput) list_add_tail(&dinput->devices_list, &newDevice->base.entry); LeaveCriticalSection(&dinput->crit);
- if (dinput->dwVersion >= DIRECTINPUT_VERSION)
- {
newDevice->base.use_raw_input = TRUE;
newDevice->base.raw_device.usUsagePage = 1; /* HID generic device page */
newDevice->base.raw_device.usUsage = 6; /* HID generic keyboard */
- }
Of course this should be >= 0x0800
On Mon, 26 Aug 2019 16:07:00 +0200, Rémi Bernon wrote:
- switch (hook->vkCode)
switch (raw_input.data.keyboard.VKey)
{
/* R-Shift is special - it is an extended key with separate scan code */
case VK_RSHIFT: dik_code = DIK_RSHIFT; break;
case VK_PAUSE: dik_code = DIK_PAUSE; break;
case VK_NUMLOCK: dik_code = DIK_NUMLOCK; break;
case VK_SUBTRACT: dik_code = DIK_SUBTRACT; break;
default:
dik_code = map_dik_code(0, raw_input.data.keyboard.VKey, This->subtype);
You may want to use raw_input.data.keyboard.MakeCode here insetad of 0. MapVirtualKey(MAPVK_VK_TO_VSC) is slightly broken (e.g. numeric keypad).
if (raw_input.data.keyboard.Flags & RI_KEY_E0) dik_code |= 0x80;
}
new_diks = (raw_input.data.keyboard.Flags & RI_KEY_BREAK) ? 0 : 0x80;
- }
Akihiro Sagawa
On 8/27/19 3:15 PM, Akihiro Sagawa wrote:
On Mon, 26 Aug 2019 16:07:00 +0200, Rémi Bernon wrote:
- switch (hook->vkCode)
switch (raw_input.data.keyboard.VKey)
{
/* R-Shift is special - it is an extended key with separate scan code */
case VK_RSHIFT: dik_code = DIK_RSHIFT; break;
case VK_PAUSE: dik_code = DIK_PAUSE; break;
case VK_NUMLOCK: dik_code = DIK_NUMLOCK; break;
case VK_SUBTRACT: dik_code = DIK_SUBTRACT; break;
default:
dik_code = map_dik_code(0, raw_input.data.keyboard.VKey, This->subtype);
You may want to use raw_input.data.keyboard.MakeCode here insetad of 0. MapVirtualKey(MAPVK_VK_TO_VSC) is slightly broken (e.g. numeric keypad).
if (raw_input.data.keyboard.Flags & RI_KEY_E0) dik_code |= 0x80;
}
new_diks = (raw_input.data.keyboard.Flags & RI_KEY_BREAK) ? 0 : 0x80;
- }
Akihiro Sagawa
Thanks, I guess I missed the field.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput/mouse.c | 166 ++++++++++++++++++++++++++++++++++++ dlls/dinput8/tests/device.c | 10 --- 2 files changed, 166 insertions(+), 10 deletions(-)
diff --git a/dlls/dinput/mouse.c b/dlls/dinput/mouse.c index 52a766b2a1a..e4f179c6b78 100644 --- a/dlls/dinput/mouse.c +++ b/dlls/dinput/mouse.c @@ -246,6 +246,13 @@ static SysMouseImpl *alloc_device(REFGUID rguid, IDirectInputImpl *dinput) list_add_tail(&dinput->devices_list, &newDevice->base.entry); LeaveCriticalSection(&dinput->crit);
+ if (dinput->dwVersion >= DIRECTINPUT_VERSION) + { + newDevice->base.use_raw_input = TRUE; + newDevice->base.raw_device.usUsagePage = 1; /* HID generic device page */ + newDevice->base.raw_device.usUsage = 2; /* HID generic mouse */ + } + return newDevice;
failed: @@ -320,6 +327,165 @@ static int dinput_mouse_hook( LPDIRECTINPUTDEVICE8A iface, WPARAM wparam, LPARAM SysMouseImpl* This = impl_from_IDirectInputDevice8A(iface); int wdata = 0, inst_id = -1, ret = 0;
+ if (wparam == RIM_INPUT || wparam == RIM_INPUTSINK) + { + RAWINPUTHEADER raw_header; + RAWINPUT raw_input; + UINT size; + POINT rel, pt; + + TRACE("(%p) wp %08lx, lp %08lx\n", iface, wparam, lparam); + + size = sizeof(raw_header); + if (GetRawInputData( (HRAWINPUT)lparam, RID_HEADER, &raw_header, &size, sizeof(RAWINPUTHEADER) ) != sizeof(raw_header)) + { + WARN( "Unable to read raw input data header\n" ); + return 0; + } + + if (raw_header.dwType != RIM_TYPEMOUSE) + return 0; + + if (raw_header.dwSize > sizeof(raw_input)) + { + WARN( "Unexpected size for mouse raw input data\n" ); + return 0; + } + + size = raw_header.dwSize; + if (GetRawInputData( (HRAWINPUT)lparam, RID_INPUT, &raw_input, &size, sizeof(RAWINPUTHEADER) ) != raw_header.dwSize ) + { + WARN( "Unable to read raw input data\n" ); + return 0; + } + + if (raw_input.data.mouse.usFlags & MOUSE_VIRTUAL_DESKTOP) + FIXME( "Unimplemented MOUSE_VIRTUAL_DESKTOP flag\n" ); + if (raw_input.data.mouse.usFlags & MOUSE_ATTRIBUTES_CHANGED) + FIXME( "Unimplemented MOUSE_ATTRIBUTES_CHANGED flag\n" ); + + EnterCriticalSection(&This->base.crit); + + rel.x = raw_input.data.mouse.lLastX; + rel.y = raw_input.data.mouse.lLastY; + if (raw_input.data.mouse.usFlags & MOUSE_MOVE_ABSOLUTE) + { + GetCursorPos(&pt); + rel.x -= pt.x; + rel.y -= pt.y; + } + + This->m_state.lX += rel.x; + This->m_state.lY += rel.y; + + if (This->base.data_format.user_df->dwFlags & DIDF_ABSAXIS) + { + pt.x = This->m_state.lX; + pt.y = This->m_state.lY; + } + else + { + pt = rel; + } + + if (rel.x) + queue_event(iface, DIDFT_MAKEINSTANCE(WINE_MOUSE_X_AXIS_INSTANCE) | DIDFT_RELAXIS, + pt.x, GetCurrentTime(), This->base.dinput->evsequence); + + if (rel.y) + queue_event(iface, DIDFT_MAKEINSTANCE(WINE_MOUSE_Y_AXIS_INSTANCE) | DIDFT_RELAXIS, + pt.y, GetCurrentTime(), This->base.dinput->evsequence); + + if (rel.x || rel.y) + { + if ((This->warp_override == WARP_FORCE_ON) || + (This->warp_override != WARP_DISABLE && (This->base.dwCoopLevel & DISCL_EXCLUSIVE))) + This->need_warp = TRUE; + } + + if (raw_input.data.mouse.usButtonFlags & RI_MOUSE_WHEEL) + { + This->m_state.lZ += (wdata = (SHORT)raw_input.data.mouse.usButtonData); + queue_event(iface, DIDFT_MAKEINSTANCE(WINE_MOUSE_Z_AXIS_INSTANCE) | DIDFT_RELAXIS, + wdata, GetCurrentTime(), This->base.dinput->evsequence); + ret = This->clipped; + } + + if (raw_input.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_1_DOWN) + { + This->m_state.rgbButtons[0] = (wdata = 0x80); + queue_event(iface, DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 0) | DIDFT_PSHBUTTON, + wdata, GetCurrentTime(), This->base.dinput->evsequence); + } + + if (raw_input.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_1_UP) + { + This->m_state.rgbButtons[0] = (wdata = 0x00); + queue_event(iface, DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 0) | DIDFT_PSHBUTTON, + wdata, GetCurrentTime(), This->base.dinput->evsequence); + } + + if (raw_input.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_2_DOWN) + { + This->m_state.rgbButtons[1] = (wdata = 0x80); + queue_event(iface, DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 1) | DIDFT_PSHBUTTON, + wdata, GetCurrentTime(), This->base.dinput->evsequence); + } + + if (raw_input.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_2_UP) + { + This->m_state.rgbButtons[1] = (wdata = 0x00); + queue_event(iface, DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 1) | DIDFT_PSHBUTTON, + wdata, GetCurrentTime(), This->base.dinput->evsequence); + } + + if (raw_input.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_3_DOWN) + { + This->m_state.rgbButtons[2] = (wdata = 0x80); + queue_event(iface, DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 2) | DIDFT_PSHBUTTON, + wdata, GetCurrentTime(), This->base.dinput->evsequence); + } + + if (raw_input.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_3_UP) + { + This->m_state.rgbButtons[2] = (wdata = 0x00); + queue_event(iface, DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 2) | DIDFT_PSHBUTTON, + wdata, GetCurrentTime(), This->base.dinput->evsequence); + } + + if (raw_input.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_4_DOWN) + { + This->m_state.rgbButtons[3] = (wdata = 0x80); + queue_event(iface, DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 3) | DIDFT_PSHBUTTON, + wdata, GetCurrentTime(), This->base.dinput->evsequence); + } + + if (raw_input.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_4_UP) + { + This->m_state.rgbButtons[3] = (wdata = 0x00); + queue_event(iface, DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 3) | DIDFT_PSHBUTTON, + wdata, GetCurrentTime(), This->base.dinput->evsequence); + } + + if (raw_input.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_5_DOWN) + { + This->m_state.rgbButtons[4] = (wdata = 0x80); + queue_event(iface, DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 4) | DIDFT_PSHBUTTON, + wdata, GetCurrentTime(), This->base.dinput->evsequence); + } + + if (raw_input.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_5_UP) + { + This->m_state.rgbButtons[4] = (wdata = 0x00); + queue_event(iface, DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 4) | DIDFT_PSHBUTTON, + wdata, GetCurrentTime(), This->base.dinput->evsequence); + } + + LeaveCriticalSection(&This->base.crit); + + return ret; + } + TRACE("msg %lx @ (%d %d)\n", wparam, hook->pt.x, hook->pt.y);
EnterCriticalSection(&This->base.crit); diff --git a/dlls/dinput8/tests/device.c b/dlls/dinput8/tests/device.c index 9f2d0dbd29a..e7fe1302046 100644 --- a/dlls/dinput8/tests/device.c +++ b/dlls/dinput8/tests/device.c @@ -641,15 +641,10 @@ static void test_mouse_keyboard(void) raw_devices_count = ARRAY_SIZE(raw_devices); memset(raw_devices, 0, sizeof(raw_devices)); hr = GetRegisteredRawInputDevices(raw_devices, &raw_devices_count, sizeof(RAWINPUTDEVICE)); - todo_wine ok(hr == 1, "GetRegisteredRawInputDevices returned %d, raw_devices_count: %d\n", hr, raw_devices_count); - todo_wine ok(raw_devices[0].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[0].usUsagePage); - todo_wine ok(raw_devices[0].usUsage == 2, "Unexpected raw device usage: %x\n", raw_devices[0].usUsage); - todo_wine ok(raw_devices[0].dwFlags == RIDEV_INPUTSINK, "Unexpected raw device flags: %x\n", raw_devices[0].dwFlags); - todo_wine ok(raw_devices[0].hwndTarget == di_hwnd, "Unexpected raw device target: %p\n", raw_devices[0].hwndTarget); hr = IDirectInputDevice8_Unacquire(di_mouse); ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %08x\n", hr); @@ -684,9 +679,7 @@ static void test_mouse_keyboard(void) ok(hr == 3, "GetRegisteredRawInputDevices returned %d, raw_devices_count: %d\n", hr, raw_devices_count); ok(raw_devices[0].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[0].usUsagePage); ok(raw_devices[0].usUsage == 2, "Unexpected raw device usage: %x\n", raw_devices[0].usUsage); - todo_wine ok(raw_devices[0].dwFlags == RIDEV_INPUTSINK, "Unexpected raw device flags: %x\n", raw_devices[0].dwFlags); - todo_wine ok(raw_devices[0].hwndTarget == di_hwnd, "Unexpected raw device target: %p\n", raw_devices[0].hwndTarget); ok(raw_devices[1].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[1].usUsagePage); ok(raw_devices[1].usUsage == 5, "Unexpected raw device usage: %x\n", raw_devices[1].usUsage); @@ -702,15 +695,12 @@ static void test_mouse_keyboard(void) ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %08x\n", hr); raw_devices_count = ARRAY_SIZE(raw_devices); GetRegisteredRawInputDevices(NULL, &raw_devices_count, sizeof(RAWINPUTDEVICE)); - todo_wine ok(raw_devices_count == 1, "Unexpected raw devices registered: %d\n", raw_devices_count);
raw_devices_count = ARRAY_SIZE(raw_devices); hr = GetRegisteredRawInputDevices(raw_devices, &raw_devices_count, sizeof(RAWINPUTDEVICE)); - todo_wine ok(hr == 1, "GetRegisteredRawInputDevices returned %d, raw_devices_count: %d\n", hr, raw_devices_count); ok(raw_devices[0].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[0].usUsagePage); - todo_wine ok(raw_devices[0].usUsage == 5, "Unexpected raw device usage: %x\n", raw_devices[0].usUsage); ok(raw_devices[0].dwFlags == 0, "Unexpected raw device flags: %x\n", raw_devices[0].dwFlags); ok(raw_devices[0].hwndTarget == hwnd, "Unexpected raw device target: %p\n", raw_devices[0].hwndTarget); -- 2.23.0.rc1
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=55816
Your paranoid android.
=== debian10 (32 bit report) ===
dinput: keyboard.c:154: Test failed: Keyboard event not processed, skipping test keyboard.c:171: Test failed: Unexpected raw devices registered: 1 mouse.c:162: Test failed: GetDeviceData() failed: 00000000 cnt:0 mouse.c:173: Test failed: GetDeviceData() failed: 00000000 cnt:0
user32: msg.c:5145: Test succeeded inside todo block: ShowWindow(SW_SHOWMINIMIZED):overlapped: marked "todo_wine" but succeeds
Report errors: user32:msg prints too much data (35221 bytes)
=== debian10 (32 bit Chinese:China report) ===
dinput: keyboard.c:154: Test failed: Keyboard event not processed, skipping test keyboard.c:171: Test failed: Unexpected raw devices registered: 1 mouse.c:162: Test failed: GetDeviceData() failed: 00000000 cnt:0 mouse.c:173: Test failed: GetDeviceData() failed: 00000000 cnt:0
user32: msg.c:5145: Test succeeded inside todo block: ShowWindow(SW_SHOWMINIMIZED):overlapped: marked "todo_wine" but succeeds
Report errors: user32:msg prints too much data (35221 bytes)
=== debian10 (32 bit WoW report) ===
dinput: keyboard.c:154: Test failed: Keyboard event not processed, skipping test keyboard.c:171: Test failed: Unexpected raw devices registered: 1 mouse.c:162: Test failed: GetDeviceData() failed: 00000000 cnt:0 mouse.c:173: Test failed: GetDeviceData() failed: 00000000 cnt:0
user32: msg.c:5145: Test succeeded inside todo block: ShowWindow(SW_SHOWMINIMIZED):overlapped: marked "todo_wine" but succeeds
Report errors: user32:msg prints too much data (35221 bytes)
=== debian10 (64 bit WoW report) ===
dinput: keyboard.c:154: Test failed: Keyboard event not processed, skipping test keyboard.c:171: Test failed: Unexpected raw devices registered: 1 mouse.c:162: Test failed: GetDeviceData() failed: 00000000 cnt:0 mouse.c:173: Test failed: GetDeviceData() failed: 00000000 cnt:0
user32: msg.c:5145: Test succeeded inside todo block: ShowWindow(SW_SHOWMINIMIZED):overlapped: marked "todo_wine" but succeeds msg.c:8713: Test failed: WaitForSingleObject failed 102 msg.c:8719: Test failed: destroy child on thread exit: 0: the msg 0x0082 was expected, but got msg 0x000f instead msg.c:8719: Test failed: destroy child on thread exit: 1: the msg 0x000f was expected, but got msg 0x0014 instead msg.c:8719: Test failed: destroy child on thread exit: 2: the msg sequence is not complete: expected 0014 - actual 0000
Report errors: user32:msg prints too much data (35952 bytes)
On 8/26/19 4:07 PM, Rémi Bernon wrote:
Signed-off-by: Rémi Bernon rbernon@codeweavers.com
dlls/dinput/mouse.c | 166 ++++++++++++++++++++++++++++++++++++ dlls/dinput8/tests/device.c | 10 --- 2 files changed, 166 insertions(+), 10 deletions(-)
diff --git a/dlls/dinput/mouse.c b/dlls/dinput/mouse.c index 52a766b2a1a..e4f179c6b78 100644 --- a/dlls/dinput/mouse.c +++ b/dlls/dinput/mouse.c @@ -246,6 +246,13 @@ static SysMouseImpl *alloc_device(REFGUID rguid, IDirectInputImpl *dinput) list_add_tail(&dinput->devices_list, &newDevice->base.entry); LeaveCriticalSection(&dinput->crit);
- if (dinput->dwVersion >= DIRECTINPUT_VERSION)
- {
newDevice->base.use_raw_input = TRUE;
newDevice->base.raw_device.usUsagePage = 1; /* HID generic device page */
newDevice->base.raw_device.usUsage = 2; /* HID generic mouse */
- }
return newDevice;
Same here, dinput->dwVersion >= 0x0800
Hi Rémi,
Since you are going to resend this anyway, is it possible to use a loop for all the RI_MOUSE_BUTTON_*_(UP|DOWN) handling, to avoid so much code duplication?