Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput/device.c | 3 --- dlls/dinput/joystick_hid.c | 2 ++ dlls/dinput/joystick_linux.c | 3 +++ dlls/dinput/joystick_linuxinput.c | 3 +++ dlls/dinput/joystick_osx.c | 6 ++++++ dlls/dinput/keyboard.c | 1 + dlls/dinput/mouse.c | 16 ++++++++++++++++ 7 files changed, 31 insertions(+), 3 deletions(-)
diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c index e04d40e5a7c..17eaff69d50 100644 --- a/dlls/dinput/device.c +++ b/dlls/dinput/device.c @@ -986,9 +986,6 @@ void queue_event( IDirectInputDevice8W *iface, int inst_id, DWORD data, DWORD ti int next_pos, ofs = id_to_offset(&This->data_format, inst_id); ULONGLONG time_ms = GetTickCount64();
- /* Event is being set regardless of the queue state */ - if (This->hEvent) SetEvent(This->hEvent); - if (time_ms - notify_ms > 1000) { PostMessageW(GetDesktopWindow(), WM_WINE_NOTIFY_ACTIVITY, 0, 0); diff --git a/dlls/dinput/joystick_hid.c b/dlls/dinput/joystick_hid.c index 3ef6f0db9cc..709953be8f0 100644 --- a/dlls/dinput/joystick_hid.c +++ b/dlls/dinput/joystick_hid.c @@ -908,6 +908,8 @@ static HRESULT hid_joystick_read_state( IDirectInputDevice8W *iface )
enum_value_objects( impl, &filter, DIDFT_ALL, read_device_state_value, ¶ms ); enum_button_objects( impl, &filter, DIDFT_ALL, check_device_state_button, ¶ms ); + if (memcmp( ¶ms.old_state, &impl->state, sizeof(impl->state) ) && impl->base.hEvent) + SetEvent( impl->base.hEvent ); }
memset( &impl->read_ovl, 0, sizeof(impl->read_ovl) ); diff --git a/dlls/dinput/joystick_linux.c b/dlls/dinput/joystick_linux.c index 3a8b0f07704..c439cca81c3 100644 --- a/dlls/dinput/joystick_linux.c +++ b/dlls/dinput/joystick_linux.c @@ -777,7 +777,10 @@ static void joy_polldev( IDirectInputDevice8W *iface ) } } if (inst_id >= 0) + { queue_event(iface, inst_id, value, GetCurrentTime(), This->generic.base.dinput->evsequence++); + if (This->generic.base.hEvent) SetEvent( This->generic.base.hEvent ); + } } }
diff --git a/dlls/dinput/joystick_linuxinput.c b/dlls/dinput/joystick_linuxinput.c index 27dd75a8b55..8279ffbf74a 100644 --- a/dlls/dinput/joystick_linuxinput.c +++ b/dlls/dinput/joystick_linuxinput.c @@ -806,8 +806,11 @@ static void joy_polldev( IDirectInputDevice8W *iface ) break; } if (inst_id >= 0) + { queue_event(iface, inst_id, value, GetCurrentTime(), This->generic.base.dinput->evsequence++); + if (This->generic.base.hEvent) SetEvent( This->generic.base.hEvent ); + } } }
diff --git a/dlls/dinput/joystick_osx.c b/dlls/dinput/joystick_osx.c index 62a063b6da1..e8732bd696c 100644 --- a/dlls/dinput/joystick_osx.c +++ b/dlls/dinput/joystick_osx.c @@ -840,6 +840,8 @@ static void poll_osx_device_state( IDirectInputDevice8W *iface ) { inst_id = DIDFT_MAKEINSTANCE(button_idx) | DIDFT_PSHBUTTON; queue_event(iface,inst_id,newVal,GetCurrentTime(),device->generic.base.dinput->evsequence++); + if (device->generic.base.hEvent) + SetEvent( device->generic.base.hEvent ); } button_idx ++; } @@ -870,6 +872,8 @@ static void poll_osx_device_state( IDirectInputDevice8W *iface ) { inst_id = DIDFT_MAKEINSTANCE(pov_idx) | DIDFT_POV; queue_event(iface,inst_id,newVal,GetCurrentTime(),device->generic.base.dinput->evsequence++); + if (device->generic.base.hEvent) + SetEvent( device->generic.base.hEvent ); } pov_idx ++; break; @@ -947,6 +951,8 @@ static void poll_osx_device_state( IDirectInputDevice8W *iface ) { inst_id = DIDFT_MAKEINSTANCE(wine_obj) | DIDFT_ABSAXIS; queue_event(iface,inst_id,newVal,GetCurrentTime(),device->generic.base.dinput->evsequence++); + if (device->generic.base.hEvent) + SetEvent( device->generic.base.hEvent ); }
break; diff --git a/dlls/dinput/keyboard.c b/dlls/dinput/keyboard.c index 5d532ab8059..3e1cac1733f 100644 --- a/dlls/dinput/keyboard.c +++ b/dlls/dinput/keyboard.c @@ -127,6 +127,7 @@ int dinput_keyboard_hook( IDirectInputDevice8W *iface, WPARAM wparam, LPARAM lpa EnterCriticalSection(&This->base.crit); queue_event(iface, DIDFT_MAKEINSTANCE(dik_code) | DIDFT_PSHBUTTON, new_diks, GetCurrentTime(), This->base.dinput->evsequence++); + if (This->base.hEvent) SetEvent( This->base.hEvent ); LeaveCriticalSection(&This->base.crit);
return ret; diff --git a/dlls/dinput/mouse.c b/dlls/dinput/mouse.c index 9f696cb414a..0ab791c69a5 100644 --- a/dlls/dinput/mouse.c +++ b/dlls/dinput/mouse.c @@ -234,6 +234,7 @@ void dinput_mouse_rawinput_hook( IDirectInputDevice8W *iface, WPARAM wparam, LPA POINT rel, pt; DWORD seq; int i, wdata = 0; + BOOL notify = FALSE;
static const USHORT mouse_button_flags[] = { @@ -277,12 +278,18 @@ void dinput_mouse_rawinput_hook( IDirectInputDevice8W *iface, WPARAM wparam, LPA }
if (rel.x) + { queue_event( iface, DIDFT_MAKEINSTANCE(WINE_MOUSE_X_AXIS_INSTANCE) | DIDFT_RELAXIS, pt.x, GetCurrentTime(), seq ); + notify = TRUE; + }
if (rel.y) + { queue_event( iface, DIDFT_MAKEINSTANCE(WINE_MOUSE_Y_AXIS_INSTANCE) | DIDFT_RELAXIS, pt.y, GetCurrentTime(), seq ); + notify = TRUE; + }
if (rel.x || rel.y) { @@ -296,6 +303,7 @@ void dinput_mouse_rawinput_hook( IDirectInputDevice8W *iface, WPARAM wparam, LPA This->m_state.lZ += (wdata = (SHORT)ri->data.mouse.usButtonData); queue_event( iface, DIDFT_MAKEINSTANCE(WINE_MOUSE_Z_AXIS_INSTANCE) | DIDFT_RELAXIS, wdata, GetCurrentTime(), seq ); + notify = TRUE; }
for (i = 0; i < ARRAY_SIZE(mouse_button_flags); ++i) @@ -305,9 +313,11 @@ void dinput_mouse_rawinput_hook( IDirectInputDevice8W *iface, WPARAM wparam, LPA This->m_state.rgbButtons[i / 2] = 0x80 - (i % 2) * 0x80; queue_event( iface, DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE +(i / 2) ) | DIDFT_PSHBUTTON, This->m_state.rgbButtons[i / 2], GetCurrentTime(), seq ); + notify = TRUE; } }
+ if (notify && This->base.hEvent) SetEvent( This->base.hEvent ); LeaveCriticalSection( &This->base.crit ); }
@@ -317,6 +327,7 @@ int dinput_mouse_hook( IDirectInputDevice8W *iface, WPARAM wparam, LPARAM lparam MSLLHOOKSTRUCT *hook = (MSLLHOOKSTRUCT *)lparam; SysMouseImpl *This = impl_from_IDirectInputDevice8W( iface ); int wdata = 0, inst_id = -1, ret = 0; + BOOL notify = FALSE;
TRACE("msg %lx @ (%d %d)\n", wparam, hook->pt.x, hook->pt.y);
@@ -347,8 +358,11 @@ int dinput_mouse_hook( IDirectInputDevice8W *iface, WPARAM wparam, LPARAM lparam { /* Already have X, need to queue it */ if (inst_id != -1) + { queue_event(iface, inst_id, wdata, GetCurrentTime(), This->base.dinput->evsequence); + notify = TRUE; + } inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_Y_AXIS_INSTANCE) | DIDFT_RELAXIS; wdata = pt1.y; } @@ -408,8 +422,10 @@ int dinput_mouse_hook( IDirectInputDevice8W *iface, WPARAM wparam, LPARAM lparam _dump_mouse_state(&This->m_state); queue_event(iface, inst_id, wdata, GetCurrentTime(), This->base.dinput->evsequence++); + notify = TRUE; }
+ if (notify && This->base.hEvent) SetEvent( This->base.hEvent ); LeaveCriticalSection(&This->base.crit); return ret; }
So that we don't have to specify it explicitely every time. Input reports length is now enforced, and we don't mean to test the length every time we inject input.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput8/tests/driver_hid.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-)
diff --git a/dlls/dinput8/tests/driver_hid.c b/dlls/dinput8/tests/driver_hid.c index 28694e5a4c6..f484710e498 100644 --- a/dlls/dinput8/tests/driver_hid.c +++ b/dlls/dinput8/tests/driver_hid.c @@ -225,11 +225,15 @@ static void input_queue_cleanup( struct input_queue *queue )
static BOOL input_queue_read_locked( struct input_queue *queue, IRP *irp ) { + IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation( irp ); + ULONG out_size = stack->Parameters.DeviceIoControl.OutputBufferLength; struct hid_expect *tmp = queue->pos; + if (tmp >= queue->end) return FALSE; + if (tmp->ret_length) out_size = tmp->ret_length;
- memcpy( irp->UserBuffer, tmp->report_buf, tmp->ret_length ); - irp->IoStatus.Information = tmp->ret_length; + memcpy( irp->UserBuffer, tmp->report_buf, out_size ); + irp->IoStatus.Information = out_size; irp->IoStatus.Status = tmp->ret_status; if (tmp < queue->end) queue->pos = tmp + 1;
@@ -464,7 +468,7 @@ static NTSTATUS WINAPI driver_internal_ioctl( DEVICE_OBJECT *device, IRP *irp ) "unexpected data\n" ); winetest_pop_context();
- irp->IoStatus.Information = expect.ret_length; + irp->IoStatus.Information = expect.ret_length ? expect.ret_length : expect.report_len; ret = expect.ret_status; break; } @@ -487,8 +491,8 @@ static NTSTATUS WINAPI driver_internal_ioctl( DEVICE_OBJECT *device, IRP *irp ) ok( packet->reportBufferLen == expect.report_len, "got len %u\n", packet->reportBufferLen ); winetest_pop_context();
- memcpy( packet->reportBuffer, expect.report_buf, expect.ret_length ); - irp->IoStatus.Information = expect.ret_length; + irp->IoStatus.Information = expect.ret_length ? expect.ret_length : expect.report_len; + memcpy( packet->reportBuffer, expect.report_buf, irp->IoStatus.Information ); ret = expect.ret_status; break; } @@ -513,7 +517,7 @@ static NTSTATUS WINAPI driver_internal_ioctl( DEVICE_OBJECT *device, IRP *irp ) "unexpected data\n" ); winetest_pop_context();
- irp->IoStatus.Information = expect.ret_length; + irp->IoStatus.Information = expect.ret_length ? expect.ret_length : expect.report_len; ret = expect.ret_status; break; } @@ -536,8 +540,8 @@ static NTSTATUS WINAPI driver_internal_ioctl( DEVICE_OBJECT *device, IRP *irp ) ok( packet->reportBufferLen == expect.report_len, "got len %u\n", packet->reportBufferLen ); winetest_pop_context();
- memcpy( packet->reportBuffer, expect.report_buf, expect.ret_length ); - irp->IoStatus.Information = expect.ret_length; + irp->IoStatus.Information = expect.ret_length ? expect.ret_length : expect.report_len; + memcpy( packet->reportBuffer, expect.report_buf, irp->IoStatus.Information ); ret = expect.ret_status; break; } @@ -562,7 +566,7 @@ static NTSTATUS WINAPI driver_internal_ioctl( DEVICE_OBJECT *device, IRP *irp ) "unexpected data\n" ); winetest_pop_context();
- irp->IoStatus.Information = expect.ret_length; + irp->IoStatus.Information = expect.ret_length ? expect.ret_length : expect.report_len; ret = expect.ret_status; break; }
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput8/tests/hid.c | 103 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 101 insertions(+), 2 deletions(-)
diff --git a/dlls/dinput8/tests/hid.c b/dlls/dinput8/tests/hid.c index 310be9990d6..499141a4389 100644 --- a/dlls/dinput8/tests/hid.c +++ b/dlls/dinput8/tests/hid.c @@ -3349,6 +3349,43 @@ static void test_simple_joystick(void) .dwPOVs = 1, .dwButtons = 2, }; + struct hid_expect injected_input[] = + { + { + .code = IOCTL_HID_READ_REPORT, + .report_buf = {1,0x10,0x10,0}, + }, + { + .code = IOCTL_HID_READ_REPORT, + .report_buf = {1,0x38,0x38,0xf8}, + }, + { + .code = IOCTL_HID_READ_REPORT, + .report_buf = {1,0x01,0x01,0x00}, + }, + { + .code = IOCTL_HID_READ_REPORT, + .report_buf = {1,0x01,0x01,0x00}, + }, + { + .code = IOCTL_HID_READ_REPORT, + .report_buf = {1,0x80,0x80,0xff}, + }, + { + .code = IOCTL_HID_READ_REPORT, + .report_buf = {1,0x10,0xee,0x54}, + }, + }; + static const struct DIJOYSTATE2 expect_state[] = + { + {.lX = 32767, .lY = 32767, .rgdwPOV = {-1, -1, -1, -1}, .rgbButtons = {0, 0}}, + {.lX = 32767, .lY = 32767, .rgdwPOV = {-1, -1, -1, -1}, .rgbButtons = {0, 0}}, + {.lX = 65535, .lY = 65535, .rgdwPOV = {31500, -1, -1, -1}, .rgbButtons = {0x80, 0x80}}, + {.lX = 20779, .lY = 20779, .rgdwPOV = {-1, -1, -1, -1}, .rgbButtons = {0, 0}}, + {.lX = 20779, .lY = 20779, .rgdwPOV = {-1, -1, -1, -1}, .rgbButtons = {0, 0}}, + {.lX = 0, .lY = 0, .rgdwPOV = {-1, -1, -1, -1}, .rgbButtons = {0x80, 0x80}}, + {.lX = 32767, .lY = 5594, .rgdwPOV = {13500, -1, -1, -1}, .rgbButtons = {0x80}}, + };
const DIDEVICEINSTANCEW expect_devinst = { @@ -3413,10 +3450,11 @@ static void test_simple_joystick(void) IDirectInputDevice8W *device; DIDEVCAPS caps = {0}; IDirectInput8W *di; - HANDLE event; + HANDLE event, file; + DIJOYSTATE2 state; + ULONG i, res, ref; HRESULT hr; WCHAR *tmp; - ULONG ref; HWND hwnd;
GetCurrentDirectoryW( ARRAY_SIZE(cwd), cwd ); @@ -3709,6 +3747,10 @@ static void test_simple_joystick(void) hr = IDirectInputDevice8_SetEventNotification( device, event ); ok( hr == DI_OK, "IDirectInputDevice8_SetEventNotification 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, 0, NULL ); + ok( file != INVALID_HANDLE_VALUE, "got error %u\n", GetLastError() ); + hr = IDirectInputDevice8_SetCooperativeLevel( device, NULL, 0 ); ok( hr == DIERR_INVALIDPARAM, "IDirectInputDevice8_SetCooperativeLevel returned: %#x\n", hr ); hr = IDirectInputDevice8_SetCooperativeLevel( device, NULL, DISCL_BACKGROUND ); @@ -3745,9 +3787,65 @@ static void test_simple_joystick(void) hr = IDirectInputDevice8_SetCooperativeLevel( device, NULL, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE ); ok( hr == DI_OK, "IDirectInputDevice8_SetCooperativeLevel returned: %#x\n", hr );
+ hr = IDirectInputDevice8_GetDeviceState( device, sizeof(DIJOYSTATE2), &state ); + todo_wine + ok( hr == DIERR_NOTACQUIRED, "IDirectInputDevice8_GetDeviceState returned: %#x\n", hr ); + + hr = IDirectInputDevice8_Poll( device ); + ok( hr == DIERR_NOTACQUIRED, "IDirectInputDevice8_Poll returned: %#x\n", hr ); + hr = IDirectInputDevice8_Acquire( device ); ok( hr == DI_OK, "IDirectInputDevice8_Acquire returned: %#x\n", hr );
+ hr = IDirectInputDevice8_Poll( device ); + todo_wine + ok( hr == DI_NOEFFECT, "IDirectInputDevice8_Poll returned: %#x\n", hr ); + + hr = IDirectInputDevice8_GetDeviceState( device, sizeof(DIJOYSTATE2) + 1, &state ); + todo_wine + ok( hr == DIERR_INVALIDPARAM, "IDirectInputDevice8_GetDeviceState returned: %#x\n", hr ); + + for (i = 0; i < ARRAY_SIZE(injected_input); ++i) + { + winetest_push_context( "state[%d]", i ); + hr = IDirectInputDevice8_GetDeviceState( device, sizeof(DIJOYSTATE2), &state ); + ok( hr == DI_OK, "IDirectInputDevice8_GetDeviceState returned: %#x\n", hr ); + todo_wine_if( i != 2 ) + check_member( state, expect_state[i], "%d", lX ); + todo_wine_if( i != 2 ) + check_member( state, expect_state[i], "%d", lY ); + check_member( state, expect_state[i], "%d", lZ ); + todo_wine_if( i == 0 ) + check_member( state, expect_state[i], "%#x", rgdwPOV[0] ); + check_member( state, expect_state[i], "%#x", rgdwPOV[1] ); + check_member( state, expect_state[i], "%#x", rgbButtons[0] ); + check_member( state, expect_state[i], "%#x", rgbButtons[1] ); + check_member( state, expect_state[i], "%#x", rgbButtons[2] ); + + send_hid_input( file, &injected_input[i], sizeof(*injected_input) ); + + res = WaitForSingleObject( event, 100 ); + if (i == 0 || i == 3) todo_wine_if( i == 0 ) + ok( res == WAIT_TIMEOUT, "WaitForSingleObject succeeded\n" ); + else ok( res == WAIT_OBJECT_0, "WaitForSingleObject failed\n" ); ResetEvent( event ); + winetest_pop_context(); + } + + hr = IDirectInputDevice8_GetDeviceState( device, sizeof(DIJOYSTATE2), &state ); + ok( hr == DI_OK, "IDirectInputDevice8_GetDeviceState returned: %#x\n", hr ); + winetest_push_context( "state[%d]", i ); + todo_wine + check_member( state, expect_state[i], "%d", lX ); + todo_wine + check_member( state, expect_state[i], "%d", lY ); + check_member( state, expect_state[i], "%d", lZ ); + check_member( state, expect_state[i], "%#x", rgdwPOV[0] ); + check_member( state, expect_state[i], "%#x", rgdwPOV[1] ); + check_member( state, expect_state[i], "%#x", rgbButtons[0] ); + check_member( state, expect_state[i], "%#x", rgbButtons[1] ); + check_member( state, expect_state[i], "%#x", rgbButtons[2] ); + winetest_pop_context(); + hr = IDirectInputDevice8_Unacquire( device ); ok( hr == DI_OK, "IDirectInputDevice8_Unacquire returned: %#x\n", hr );
@@ -3758,6 +3856,7 @@ static void test_simple_joystick(void) ok( ref == 0, "IDirectInputDeviceW_Release returned %d\n", ref );
CloseHandle( event ); + CloseHandle( file );
ref = IDirectInput8_Release( di ); ok( ref == 0, "IDirectInput8_Release returned %d\n", ref );
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput8/tests/hid.c | 128 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+)
diff --git a/dlls/dinput8/tests/hid.c b/dlls/dinput8/tests/hid.c index 499141a4389..b70fea1be06 100644 --- a/dlls/dinput8/tests/hid.c +++ b/dlls/dinput8/tests/hid.c @@ -3386,6 +3386,23 @@ static void test_simple_joystick(void) {.lX = 0, .lY = 0, .rgdwPOV = {-1, -1, -1, -1}, .rgbButtons = {0x80, 0x80}}, {.lX = 32767, .lY = 5594, .rgdwPOV = {13500, -1, -1, -1}, .rgbButtons = {0x80}}, }; + static const DIDEVICEOBJECTDATA expect_objdata[] = + { + {.dwOfs = 0x4, .dwData = 0xffff, .dwSequence = 0xa}, + {.dwOfs = 0x4, .dwData = 0xffff, .dwSequence = 0xa}, + {.dwOfs = 0, .dwData = 0xffff, .dwSequence = 0xa}, + {.dwOfs = 0x20, .dwData = 31500, .dwSequence = 0xa}, + {.dwOfs = 0x30, .dwData = 0x80, .dwSequence = 0xa}, + {.dwOfs = 0x4, .dwData = 0x512b, .dwSequence = 0xd}, + {.dwOfs = 0, .dwData = 0x512b, .dwSequence = 0xd}, + {.dwOfs = 0x20, .dwData = -1, .dwSequence = 0xd}, + {.dwOfs = 0x30, .dwData = 0, .dwSequence = 0xd}, + {.dwOfs = 0x31, .dwData = 0, .dwSequence = 0xd}, + {.dwOfs = 0x4, .dwData = 0, .dwSequence = 0xf}, + {.dwOfs = 0, .dwData = 0, .dwSequence = 0xf}, + {.dwOfs = 0x30, .dwData = 0x80, .dwSequence = 0xf}, + {.dwOfs = 0x31, .dwData = 0x80, .dwSequence = 0xf}, + };
const DIDEVICEINSTANCEW expect_devinst = { @@ -3445,6 +3462,7 @@ static void test_simple_joystick(void) }, }; WCHAR cwd[MAX_PATH], tempdir[MAX_PATH]; + DIDEVICEOBJECTDATA objdata[32] = {0}; DIDEVICEINSTANCEW devinst = {0}; DIDATAFORMAT dataformat = {0}; IDirectInputDevice8W *device; @@ -3846,6 +3864,116 @@ static void test_simple_joystick(void) check_member( state, expect_state[i], "%#x", rgbButtons[2] ); winetest_pop_context();
+ res = 1; + hr = IDirectInputDevice8_GetDeviceData( device, sizeof(DIDEVICEOBJECTDATA) - 1, objdata, &res, DIGDD_PEEK ); + todo_wine + ok( hr == DIERR_INVALIDPARAM, "IDirectInputDevice8_GetDeviceData returned %#x\n", hr ); + res = 1; + hr = IDirectInputDevice8_GetDeviceData( device, sizeof(DIDEVICEOBJECTDATA), objdata, &res, DIGDD_PEEK ); + ok( hr == DIERR_NOTBUFFERED, "IDirectInputDevice8_GetDeviceData returned %#x\n", hr ); + + hr = IDirectInputDevice8_Unacquire( device ); + ok( hr == DI_OK, "IDirectInputDevice8_Unacquire returned: %#x\n", hr ); + prop_dword.diph.dwHow = DIPH_DEVICE; + prop_dword.diph.dwObj = 0; + prop_dword.dwData = 1; + hr = IDirectInputDevice8_SetProperty( device, DIPROP_BUFFERSIZE, &prop_dword.diph ); + ok( hr == DI_OK, "IDirectInputDevice8_SetProperty DIPROP_BUFFERSIZE returned %#x\n", hr ); + hr = IDirectInputDevice8_Acquire( device ); + ok( hr == DI_OK, "IDirectInputDevice8_Unacquire returned: %#x\n", hr ); + + res = 1; + hr = IDirectInputDevice8_GetDeviceData( device, sizeof(DIDEVICEOBJECTDATA), objdata, &res, DIGDD_PEEK ); + ok( hr == DI_OK, "IDirectInputDevice8_GetDeviceData returned %#x\n", hr ); + ok( res == 0, "got %u expected %u\n", res, 0 ); + + send_hid_input( file, &injected_input[0], sizeof(*injected_input) ); + res = WaitForSingleObject( event, 100 ); + ok( res == WAIT_OBJECT_0, "WaitForSingleObject failed\n" ); + ResetEvent( event ); + + res = 1; + hr = IDirectInputDevice8_GetDeviceData( device, sizeof(DIDEVICEOBJECTDATA), objdata, &res, DIGDD_PEEK ); + ok( hr == DI_BUFFEROVERFLOW, "IDirectInputDevice8_GetDeviceData returned %#x\n", hr ); + ok( res == 0, "got %u expected %u\n", res, 0 ); + res = 1; + hr = IDirectInputDevice8_GetDeviceData( device, sizeof(DIDEVICEOBJECTDATA), objdata, &res, 0 ); + todo_wine + ok( hr == DI_OK, "IDirectInputDevice8_GetDeviceData returned %#x\n", hr ); + ok( res == 0, "got %u expected %u\n", res, 0 ); + + hr = IDirectInputDevice8_Unacquire( device ); + ok( hr == DI_OK, "IDirectInputDevice8_Unacquire returned: %#x\n", hr ); + prop_dword.diph.dwHow = DIPH_DEVICE; + prop_dword.diph.dwObj = 0; + prop_dword.dwData = 10; + hr = IDirectInputDevice8_SetProperty( device, DIPROP_BUFFERSIZE, &prop_dword.diph ); + ok( hr == DI_OK, "IDirectInputDevice8_SetProperty DIPROP_BUFFERSIZE returned %#x\n", hr ); + hr = IDirectInputDevice8_Acquire( device ); + ok( hr == DI_OK, "IDirectInputDevice8_Unacquire returned: %#x\n", hr ); + + send_hid_input( file, &injected_input[1], sizeof(*injected_input) ); + res = WaitForSingleObject( event, 100 ); + ok( res == WAIT_OBJECT_0, "WaitForSingleObject failed\n" ); + ResetEvent( event ); + + res = 1; + hr = IDirectInputDevice8_GetDeviceData( device, sizeof(DIDEVICEOBJECTDATA), objdata, &res, DIGDD_PEEK ); + ok( hr == DI_OK, "IDirectInputDevice8_GetDeviceData returned %#x\n", hr ); + ok( res == 1, "got %u expected %u\n", res, 1 ); + check_member( objdata[0], expect_objdata[0], "%#x", dwOfs ); + check_member( objdata[0], expect_objdata[0], "%#x", dwData ); + todo_wine + check_member( objdata[0], expect_objdata[0], "%#x", dwSequence ); + ok( objdata[0].uAppData == -1, "got %p, expected %p\n", (void *)objdata[0].uAppData, (void *)-1 ); + res = 4; + hr = IDirectInputDevice8_GetDeviceData( device, sizeof(DIDEVICEOBJECTDATA), objdata, &res, 0 ); + ok( hr == DI_OK, "IDirectInputDevice8_GetDeviceData returned %#x\n", hr ); + ok( res == 4, "got %u expected %u\n", res, 4 ); + for (i = 0; i < 4; ++i) + { + winetest_push_context( "objdata[%d]", i ); + check_member( objdata[i], expect_objdata[1 + i], "%#x", dwOfs ); + check_member( objdata[i], expect_objdata[1 + i], "%#x", dwData ); + todo_wine + check_member( objdata[i], expect_objdata[1 + i], "%#x", dwSequence ); + ok( objdata[i].uAppData == -1, "got %p, expected %p\n", (void *)objdata[i].uAppData, (void *)-1 ); + winetest_pop_context(); + } + + send_hid_input( file, &injected_input[2], sizeof(*injected_input) ); + res = WaitForSingleObject( event, 100 ); + ok( res == WAIT_OBJECT_0, "WaitForSingleObject failed\n" ); + ResetEvent( event ); + send_hid_input( file, &injected_input[4], sizeof(*injected_input) ); + res = WaitForSingleObject( event, 100 ); + ok( res == WAIT_OBJECT_0, "WaitForSingleObject failed\n" ); + ResetEvent( event ); + + res = 1; + hr = IDirectInputDevice8_GetDeviceData( device, sizeof(DIDEVICEOBJECTDATA), objdata, &res, 0 ); + ok( hr == DI_BUFFEROVERFLOW, "IDirectInputDevice8_GetDeviceData returned %#x\n", hr ); + ok( res == 1, "got %u expected %u\n", res, 1 ); + todo_wine + check_member( objdata[0], expect_objdata[5], "%#x", dwOfs ); + todo_wine + check_member( objdata[0], expect_objdata[5], "%#x", dwData ); + ok( objdata[0].uAppData == -1, "got %p, expected %p\n", (void *)objdata[0].uAppData, (void *)-1 ); + res = ARRAY_SIZE(objdata); + hr = IDirectInputDevice8_GetDeviceData( device, sizeof(DIDEVICEOBJECTDATA), objdata, &res, 0 ); + ok( hr == DI_OK, "IDirectInputDevice8_GetDeviceData returned %#x\n", hr ); + ok( res == 8, "got %u expected %u\n", res, 8 ); + for (i = 0; i < 8; ++i) + { + winetest_push_context( "objdata[%d]", i ); + todo_wine + check_member( objdata[i], expect_objdata[6 + i], "%#x", dwOfs ); + todo_wine_if( i != 3 && i != 4 && i != 7 ) + check_member( objdata[i], expect_objdata[6 + i], "%#x", dwData ); + ok( objdata[i].uAppData == -1, "got %p, expected %p\n", (void *)objdata[i].uAppData, (void *)-1 ); + winetest_pop_context(); + } + hr = IDirectInputDevice8_Unacquire( device ); ok( hr == DI_OK, "IDirectInputDevice8_Unacquire returned: %#x\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=98202
Your paranoid android.
=== debiant2 (32 bit French report) ===
dinput8: hid.c:3919: Test succeeded inside todo block: got dwSequence 0xa, expected 0xa hid.c:3931: Test succeeded inside todo block: objdata[0]: got dwSequence 0xa, expected 0xa hid.c:3931: Test succeeded inside todo block: objdata[1]: got dwSequence 0xa, expected 0xa hid.c:3931: Test succeeded inside todo block: objdata[2]: got dwSequence 0xa, expected 0xa hid.c:3931: Test succeeded inside todo block: objdata[3]: got dwSequence 0xa, expected 0xa
=== debiant2 (32 bit Japanese:Japan report) ===
dinput8: hid.c:3919: Test succeeded inside todo block: got dwSequence 0xa, expected 0xa hid.c:3931: Test succeeded inside todo block: objdata[0]: got dwSequence 0xa, expected 0xa hid.c:3931: Test succeeded inside todo block: objdata[1]: got dwSequence 0xa, expected 0xa hid.c:3931: Test succeeded inside todo block: objdata[2]: got dwSequence 0xa, expected 0xa hid.c:3931: Test succeeded inside todo block: objdata[3]: got dwSequence 0xa, expected 0xa
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput8/tests/hid.c | 391 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 391 insertions(+)
diff --git a/dlls/dinput8/tests/hid.c b/dlls/dinput8/tests/hid.c index b70fea1be06..2af38452471 100644 --- a/dlls/dinput8/tests/hid.c +++ b/dlls/dinput8/tests/hid.c @@ -3386,6 +3386,26 @@ static void test_simple_joystick(void) {.lX = 0, .lY = 0, .rgdwPOV = {-1, -1, -1, -1}, .rgbButtons = {0x80, 0x80}}, {.lX = 32767, .lY = 5594, .rgdwPOV = {13500, -1, -1, -1}, .rgbButtons = {0x80}}, }; + static const struct DIJOYSTATE2 expect_state_abs[] = + { + {.lX = -9000, .lY = 26000, .rgdwPOV = {-1, -1, -1, -1}, .rgbButtons = {0, 0}}, + {.lX = -9000, .lY = 26000, .rgdwPOV = {-1, -1, -1, -1}, .rgbButtons = {0, 0}}, + {.lX = -4000, .lY = 51000, .rgdwPOV = {31500, -1, -1, -1}, .rgbButtons = {0x80, 0x80}}, + {.lX = -10667, .lY = 12905, .rgdwPOV = {-1, -1, -1, -1}, .rgbButtons = {0, 0}}, + {.lX = -10667, .lY = 12905, .rgdwPOV = {-1, -1, -1, -1}, .rgbButtons = {0, 0}}, + {.lX = -14000, .lY = 1000, .rgdwPOV = {-1, -1, -1, -1}, .rgbButtons = {0x80, 0x80}}, + {.lX = -9000, .lY = 1000, .rgdwPOV = {13500, -1, -1, -1}, .rgbButtons = {0x80}}, + }; + static const struct DIJOYSTATE2 expect_state_rel[] = + { + {.lX = 0, .lY = 0, .rgdwPOV = {13500, -1, -1, -1}, .rgbButtons = {0x80, 0}}, + {.lX = 9016, .lY = -984, .rgdwPOV = {-1, -1, -1, -1}, .rgbButtons = {0, 0}}, + {.lX = 40, .lY = 40, .rgdwPOV = {31500, -1, -1, -1}, .rgbButtons = {0x80, 0x80}}, + {.lX = -55, .lY = -55, .rgdwPOV = {-1, -1, -1, -1}, .rgbButtons = {0, 0}}, + {.lX = 0, .lY = 0, .rgdwPOV = {-1, -1, -1, -1}, .rgbButtons = {0, 0}}, + {.lX = -129, .lY = -129, .rgdwPOV = {-1, -1, -1, -1}, .rgbButtons = {0x80, 0x80}}, + {.lX = 144, .lY = 110, .rgdwPOV = {13500, -1, -1, -1}, .rgbButtons = {0x80}}, + }; static const DIDEVICEOBJECTDATA expect_objdata[] = { {.dwOfs = 0x4, .dwData = 0xffff, .dwSequence = 0xa}, @@ -3974,6 +3994,377 @@ static void test_simple_joystick(void) winetest_pop_context(); }
+ send_hid_input( file, &injected_input[3], sizeof(*injected_input) ); + res = WaitForSingleObject( event, 100 ); + ok( res == WAIT_OBJECT_0, "WaitForSingleObject failed\n" ); + ResetEvent( event ); + + hr = IDirectInputDevice8_GetDeviceState( device, sizeof(DIJOYSTATE2), &state ); + ok( hr == DI_OK, "IDirectInputDevice8_GetDeviceState returned: %#x\n", hr ); + todo_wine + check_member( state, expect_state[3], "%d", lX ); + todo_wine + check_member( state, expect_state[3], "%d", lY ); + check_member( state, expect_state[3], "%d", lZ ); + check_member( state, expect_state[3], "%d", rgdwPOV[0] ); + check_member( state, expect_state[3], "%d", rgdwPOV[1] ); + check_member( state, expect_state[3], "%#x", rgbButtons[0] ); + check_member( state, expect_state[3], "%#x", rgbButtons[1] ); + check_member( state, expect_state[3], "%#x", rgbButtons[2] ); + + prop_range.diph.dwHow = DIPH_DEVICE; + prop_range.diph.dwObj = 0; + prop_range.lMin = 1000; + prop_range.lMax = 51000; + hr = IDirectInputDevice8_SetProperty( device, DIPROP_RANGE, &prop_range.diph ); + ok( hr == DI_OK, "IDirectInputDevice8_SetProperty DIPROP_RANGE returned %#x\n", hr ); + prop_range.diph.dwHow = DIPH_BYUSAGE; + prop_range.diph.dwObj = MAKELONG( HID_USAGE_GENERIC_X, HID_USAGE_PAGE_GENERIC ); + prop_range.lMin = -4000; + prop_range.lMax = -14000; + hr = IDirectInputDevice8_SetProperty( device, DIPROP_RANGE, &prop_range.diph ); + todo_wine + ok( hr == DIERR_INVALIDPARAM, "IDirectInputDevice8_SetProperty DIPROP_RANGE returned %#x\n", hr ); + prop_range.lMin = -14000; + prop_range.lMax = -4000; + hr = IDirectInputDevice8_SetProperty( device, DIPROP_RANGE, &prop_range.diph ); + ok( hr == DI_OK, "IDirectInputDevice8_SetProperty DIPROP_RANGE returned %#x\n", hr ); + + prop_range.diph.dwHow = DIPH_DEVICE; + prop_range.diph.dwObj = 0; + prop_range.lMin = 0xdeadbeef; + prop_range.lMax = 0xdeadbeef; + hr = IDirectInputDevice8_GetProperty( device, DIPROP_RANGE, &prop_range.diph ); + todo_wine + ok( hr == DIERR_UNSUPPORTED, "IDirectInputDevice8_GetProperty DIPROP_RANGE returned %#x\n", hr ); + prop_range.diph.dwHow = DIPH_BYUSAGE; + prop_range.diph.dwObj = MAKELONG( HID_USAGE_GENERIC_X, HID_USAGE_PAGE_GENERIC ); + prop_range.lMin = 0xdeadbeef; + prop_range.lMax = 0xdeadbeef; + hr = IDirectInputDevice8_GetProperty( device, DIPROP_RANGE, &prop_range.diph ); + ok( hr == DI_OK, "IDirectInputDevice8_GetProperty DIPROP_RANGE returned %#x\n", hr ); + todo_wine + ok( prop_range.lMin == -14000, "got %d expected %d\n", prop_range.lMin, -14000 ); + todo_wine + ok( prop_range.lMax == -4000, "got %d expected %d\n", prop_range.lMax, -4000 ); + prop_range.diph.dwHow = DIPH_BYUSAGE; + prop_range.diph.dwObj = MAKELONG( HID_USAGE_GENERIC_Y, HID_USAGE_PAGE_GENERIC ); + prop_range.lMin = 0xdeadbeef; + prop_range.lMax = 0xdeadbeef; + hr = IDirectInputDevice8_GetProperty( device, DIPROP_RANGE, &prop_range.diph ); + ok( hr == DI_OK, "IDirectInputDevice8_GetProperty DIPROP_RANGE returned %#x\n", hr ); + todo_wine + ok( prop_range.lMin == 1000, "got %d expected %d\n", prop_range.lMin, 1000 ); + todo_wine + ok( prop_range.lMax == 51000, "got %d expected %d\n", prop_range.lMax, 51000 ); + + hr = IDirectInputDevice8_GetDeviceState( device, sizeof(DIJOYSTATE2), &state ); + ok( hr == DI_OK, "IDirectInputDevice8_GetDeviceState returned: %#x\n", hr ); + todo_wine + check_member( state, expect_state_abs[1], "%d", lX ); + todo_wine + check_member( state, expect_state_abs[1], "%d", lY ); + check_member( state, expect_state_abs[1], "%d", lZ ); + check_member( state, expect_state_abs[1], "%d", rgdwPOV[0] ); + check_member( state, expect_state_abs[1], "%d", rgdwPOV[1] ); + check_member( state, expect_state_abs[1], "%#x", rgbButtons[0] ); + check_member( state, expect_state_abs[1], "%#x", rgbButtons[1] ); + check_member( state, expect_state_abs[1], "%#x", rgbButtons[2] ); + + hr = IDirectInputDevice8_SetProperty( device, NULL, NULL ); + ok( hr == DIERR_INVALIDPARAM, "IDirectInputDevice8_SetProperty returned %#x\n", hr ); + hr = IDirectInputDevice8_SetProperty( device, &GUID_NULL, NULL ); + ok( hr == DIERR_INVALIDPARAM, "IDirectInputDevice8_SetProperty returned %#x\n", hr ); + hr = IDirectInputDevice8_SetProperty( device, DIPROP_VIDPID, NULL ); + ok( hr == DIERR_INVALIDPARAM, "IDirectInputDevice8_SetProperty returned %#x\n", hr ); + hr = IDirectInputDevice8_SetProperty( device, DIPROP_VIDPID, &prop_string.diph ); + todo_wine + ok( hr == DIERR_INVALIDPARAM, "IDirectInputDevice8_SetProperty returned %#x\n", hr ); + + prop_dword.diph.dwHow = DIPH_DEVICE; + prop_dword.diph.dwObj = 0; + prop_dword.dwData = 0xdeadbeef; + hr = IDirectInputDevice8_SetProperty( device, DIPROP_VIDPID, &prop_dword.diph ); + todo_wine + ok( hr == DIERR_READONLY, "IDirectInputDevice8_SetProperty DIPROP_VIDPID returned %#x\n", hr ); + hr = IDirectInputDevice8_SetProperty( device, DIPROP_GUIDANDPATH, &prop_guid_path.diph ); + todo_wine + ok( hr == DIERR_READONLY, "IDirectInputDevice8_SetProperty DIPROP_GUIDANDPATH returned %#x\n", hr ); + + prop_string.diph.dwHow = DIPH_DEVICE; + prop_string.diph.dwObj = 0; + wcscpy( prop_string.wsz, L"instance name" ); + hr = IDirectInputDevice8_SetProperty( device, DIPROP_INSTANCENAME, &prop_string.diph ); + ok( hr == DIERR_UNSUPPORTED, "IDirectInputDevice8_SetProperty DIPROP_INSTANCENAME returned %#x\n", hr ); + + wcscpy( prop_string.wsz, L"product name" ); + hr = IDirectInputDevice8_SetProperty( device, DIPROP_PRODUCTNAME, &prop_string.diph ); + todo_wine + ok( hr == DI_OK, "IDirectInputDevice8_SetProperty DIPROP_PRODUCTNAME returned %#x\n", hr ); + hr = IDirectInputDevice8_GetProperty( device, DIPROP_PRODUCTNAME, &prop_string.diph ); + ok( hr == DI_OK, "IDirectInputDevice8_GetProperty DIPROP_PRODUCTNAME returned %#x\n", hr ); + todo_wine + ok( !wcscmp( prop_string.wsz, expect_devinst.tszProductName ), "got product %s\n", + debugstr_w(prop_string.wsz) ); + + hr = IDirectInputDevice8_SetProperty( device, DIPROP_TYPENAME, &prop_string.diph ); + todo_wine + ok( hr == DIERR_READONLY, "IDirectInputDevice8_SetProperty DIPROP_TYPENAME returned %#x\n", hr ); + hr = IDirectInputDevice8_SetProperty( device, DIPROP_USERNAME, &prop_string.diph ); + todo_wine + ok( hr == DIERR_READONLY, "IDirectInputDevice8_SetProperty DIPROP_USERNAME returned %#x\n", hr ); + hr = IDirectInputDevice8_SetProperty( device, DIPROP_FFLOAD, &prop_dword.diph ); + todo_wine + ok( hr == DIERR_READONLY, "IDirectInputDevice8_SetProperty DIPROP_FFLOAD returned %#x\n", hr ); + hr = IDirectInputDevice8_SetProperty( device, DIPROP_GRANULARITY, &prop_dword.diph ); + todo_wine + ok( hr == DIERR_READONLY, "IDirectInputDevice8_SetProperty DIPROP_GRANULARITY returned %#x\n", hr ); + + hr = IDirectInputDevice8_SetProperty( device, DIPROP_JOYSTICKID, &prop_dword.diph ); + todo_wine + ok( hr == DIERR_ACQUIRED, "IDirectInputDevice8_SetProperty DIPROP_JOYSTICKID returned %#x\n", hr ); + hr = IDirectInputDevice8_SetProperty( device, DIPROP_AXISMODE, &prop_dword.diph ); + ok( hr == DIERR_ACQUIRED, "IDirectInputDevice8_SetProperty DIPROP_AXISMODE returned %#x\n", hr ); + hr = IDirectInputDevice8_SetProperty( device, DIPROP_BUFFERSIZE, &prop_dword.diph ); + ok( hr == DIERR_ACQUIRED, "IDirectInputDevice8_SetProperty DIPROP_BUFFERSIZE returned %#x\n", hr ); + hr = IDirectInputDevice8_SetProperty( device, DIPROP_AUTOCENTER, &prop_dword.diph ); + todo_wine + ok( hr == DIERR_ACQUIRED, "IDirectInputDevice8_SetProperty DIPROP_AUTOCENTER returned %#x\n", hr ); + prop_pointer.diph.dwHow = DIPH_BYUSAGE; + prop_pointer.diph.dwObj = MAKELONG( HID_USAGE_GENERIC_X, HID_USAGE_PAGE_GENERIC ); + hr = IDirectInputDevice8_SetProperty( device, DIPROP_APPDATA, &prop_pointer.diph ); + todo_wine + ok( hr == DIERR_ACQUIRED, "IDirectInputDevice8_SetProperty DIPROP_APPDATA returned %#x\n", hr ); + + prop_dword.diph.dwHow = DIPH_DEVICE; + prop_dword.diph.dwObj = 0; + prop_dword.dwData = 10001; + hr = IDirectInputDevice8_SetProperty( device, DIPROP_DEADZONE, &prop_dword.diph ); + todo_wine + ok( hr == DIERR_INVALIDPARAM, "IDirectInputDevice8_SetProperty DIPROP_DEADZONE returned %#x\n", hr ); + hr = IDirectInputDevice8_SetProperty( device, DIPROP_SATURATION, &prop_dword.diph ); + todo_wine + ok( hr == DIERR_INVALIDPARAM, "IDirectInputDevice8_SetProperty DIPROP_SATURATION returned %#x\n", hr ); + prop_dword.dwData = 1000; + hr = IDirectInputDevice8_SetProperty( device, DIPROP_DEADZONE, &prop_dword.diph ); + todo_wine + ok( hr == DI_OK, "IDirectInputDevice8_SetProperty DIPROP_DEADZONE returned %#x\n", hr ); + prop_dword.dwData = 6000; + hr = IDirectInputDevice8_SetProperty( device, DIPROP_SATURATION, &prop_dword.diph ); + todo_wine + ok( hr == DI_OK, "IDirectInputDevice8_SetProperty DIPROP_SATURATION returned %#x\n", hr ); + + hr = IDirectInputDevice8_GetProperty( device, DIPROP_DEADZONE, &prop_dword.diph ); + todo_wine + ok( hr == DIERR_UNSUPPORTED, "IDirectInputDevice8_GetProperty DIPROP_DEADZONE returned %#x\n", hr ); + hr = IDirectInputDevice8_GetProperty( device, DIPROP_SATURATION, &prop_dword.diph ); + todo_wine + ok( hr == DIERR_UNSUPPORTED, "IDirectInputDevice8_GetProperty DIPROP_SATURATION returned %#x\n", hr ); + + prop_dword.diph.dwHow = DIPH_BYUSAGE; + prop_dword.diph.dwObj = MAKELONG( HID_USAGE_GENERIC_X, HID_USAGE_PAGE_GENERIC ); + prop_dword.dwData = 2000; + hr = IDirectInputDevice8_SetProperty( device, DIPROP_DEADZONE, &prop_dword.diph ); + todo_wine + ok( hr == DI_OK, "IDirectInputDevice8_SetProperty DIPROP_DEADZONE returned %#x\n", hr ); + ok( prop_dword.dwData == 2000, "got %u expected %u\n", prop_dword.dwData, 2000 ); + prop_dword.dwData = 7000; + hr = IDirectInputDevice8_SetProperty( device, DIPROP_SATURATION, &prop_dword.diph ); + todo_wine + ok( hr == DI_OK, "IDirectInputDevice8_SetProperty DIPROP_SATURATION returned %#x\n", hr ); + + prop_dword.diph.dwHow = DIPH_BYUSAGE; + prop_dword.diph.dwObj = MAKELONG( HID_USAGE_GENERIC_X, HID_USAGE_PAGE_GENERIC ); + prop_dword.dwData = 0xdeadbeef; + hr = IDirectInputDevice8_GetProperty( device, DIPROP_DEADZONE, &prop_dword.diph ); + todo_wine + ok( hr == DI_OK, "IDirectInputDevice8_GetProperty DIPROP_DEADZONE returned %#x\n", hr ); + todo_wine + ok( prop_dword.dwData == 2000, "got %u expected %u\n", prop_dword.dwData, 2000 ); + prop_dword.dwData = 0xdeadbeef; + hr = IDirectInputDevice8_GetProperty( device, DIPROP_SATURATION, &prop_dword.diph ); + todo_wine + ok( hr == DI_OK, "IDirectInputDevice8_GetProperty DIPROP_SATURATION returned %#x\n", hr ); + todo_wine + ok( prop_dword.dwData == 7000, "got %u expected %u\n", prop_dword.dwData, 7000 ); + + prop_dword.diph.dwHow = DIPH_BYUSAGE; + prop_dword.diph.dwObj = MAKELONG( HID_USAGE_GENERIC_Y, HID_USAGE_PAGE_GENERIC ); + prop_dword.dwData = 0xdeadbeef; + hr = IDirectInputDevice8_GetProperty( device, DIPROP_DEADZONE, &prop_dword.diph ); + todo_wine + ok( hr == DI_OK, "IDirectInputDevice8_GetProperty DIPROP_DEADZONE returned %#x\n", hr ); + todo_wine + ok( prop_dword.dwData == 1000, "got %u expected %u\n", prop_dword.dwData, 1000 ); + prop_dword.dwData = 0xdeadbeef; + hr = IDirectInputDevice8_GetProperty( device, DIPROP_SATURATION, &prop_dword.diph ); + todo_wine + ok( hr == DI_OK, "IDirectInputDevice8_GetProperty DIPROP_SATURATION returned %#x\n", hr ); + todo_wine + ok( prop_dword.dwData == 6000, "got %u expected %u\n", prop_dword.dwData, 6000 ); + + for (i = 0; i < ARRAY_SIZE(injected_input); ++i) + { + winetest_push_context( "state[%d]", i ); + hr = IDirectInputDevice8_GetDeviceState( device, sizeof(DIJOYSTATE2), &state ); + ok( hr == DI_OK, "IDirectInputDevice8_GetDeviceState returned: %#x\n", hr ); + if (broken( state.lX == -10750 )) win_skip( "Ignoring 32-bit rounding\n" ); + else + { + todo_wine + check_member( state, expect_state_abs[i], "%d", lX ); + todo_wine_if( i != 2 ) + check_member( state, expect_state_abs[i], "%d", lY ); + } + check_member( state, expect_state_abs[i], "%d", lZ ); + check_member( state, expect_state_abs[i], "%d", rgdwPOV[0] ); + check_member( state, expect_state_abs[i], "%d", rgdwPOV[1] ); + check_member( state, expect_state_abs[i], "%#x", rgbButtons[0] ); + check_member( state, expect_state_abs[i], "%#x", rgbButtons[1] ); + check_member( state, expect_state_abs[i], "%#x", rgbButtons[2] ); + + send_hid_input( file, &injected_input[i], sizeof(*injected_input) ); + + res = WaitForSingleObject( event, 100 ); + if (i == 0 || i == 3) todo_wine_if( i == 0 ) + ok( res == WAIT_TIMEOUT, "WaitForSingleObject succeeded\n" ); + else ok( res == WAIT_OBJECT_0, "WaitForSingleObject failed\n" ); ResetEvent( event ); + winetest_pop_context(); + } + + hr = IDirectInputDevice8_GetDeviceState( device, sizeof(DIJOYSTATE2), &state ); + ok( hr == DI_OK, "IDirectInputDevice8_GetDeviceState returned: %#x\n", hr ); + winetest_push_context( "state[%d]", i ); + todo_wine + check_member( state, expect_state_abs[i], "%d", lX ); + todo_wine + check_member( state, expect_state_abs[i], "%d", lY ); + check_member( state, expect_state_abs[i], "%d", lZ ); + check_member( state, expect_state_abs[i], "%d", rgdwPOV[0] ); + check_member( state, expect_state_abs[i], "%d", rgdwPOV[1] ); + check_member( state, expect_state_abs[i], "%#x", rgbButtons[0] ); + check_member( state, expect_state_abs[i], "%#x", rgbButtons[1] ); + check_member( state, expect_state_abs[i], "%#x", rgbButtons[2] ); + winetest_pop_context(); + + hr = IDirectInputDevice8_Unacquire( device ); + ok( hr == DI_OK, "IDirectInputDevice8_Unacquire returned: %#x\n", hr ); + + prop_dword.diph.dwHow = DIPH_DEVICE; + prop_dword.diph.dwObj = 0; + hr = IDirectInputDevice8_SetProperty( device, DIPROP_JOYSTICKID, &prop_dword.diph ); + ok( hr == DIERR_UNSUPPORTED, "IDirectInputDevice8_SetProperty DIPROP_JOYSTICKID returned %#x\n", hr ); + prop_dword.dwData = 0x1000; + hr = IDirectInputDevice8_SetProperty( device, DIPROP_BUFFERSIZE, &prop_dword.diph ); + ok( hr == DI_OK, "IDirectInputDevice8_SetProperty DIPROP_BUFFERSIZE returned %#x\n", hr ); + prop_dword.dwData = 0xdeadbeef; + hr = IDirectInputDevice8_SetProperty( device, DIPROP_AUTOCENTER, &prop_dword.diph ); + todo_wine + ok( hr == DIERR_INVALIDPARAM, "IDirectInputDevice8_SetProperty DIPROP_AUTOCENTER returned %#x\n", hr ); + prop_dword.dwData = DIPROPAUTOCENTER_ON; + hr = IDirectInputDevice8_SetProperty( device, DIPROP_AUTOCENTER, &prop_dword.diph ); + ok( hr == DIERR_UNSUPPORTED, "IDirectInputDevice8_SetProperty DIPROP_AUTOCENTER returned %#x\n", hr ); + prop_pointer.diph.dwHow = DIPH_BYUSAGE; + prop_pointer.diph.dwObj = MAKELONG( HID_USAGE_GENERIC_X, HID_USAGE_PAGE_GENERIC ); + prop_pointer.uData = 0xfeedcafe; + hr = IDirectInputDevice8_SetProperty( device, DIPROP_APPDATA, &prop_pointer.diph ); + todo_wine + ok( hr == DI_OK, "IDirectInputDevice8_SetProperty DIPROP_APPDATA returned %#x\n", hr ); + + prop_dword.dwData = 0xdeadbeef; + hr = IDirectInputDevice8_SetProperty( device, DIPROP_AXISMODE, &prop_dword.diph ); + todo_wine + ok( hr == DIERR_INVALIDPARAM, "IDirectInputDevice8_SetProperty DIPROP_AXISMODE returned %#x\n", hr ); + prop_dword.dwData = DIPROPAXISMODE_REL; + hr = IDirectInputDevice8_SetProperty( device, DIPROP_AXISMODE, &prop_dword.diph ); + ok( hr == DI_OK, "IDirectInputDevice8_SetProperty DIPROP_AXISMODE returned %#x\n", hr ); + + hr = IDirectInputDevice8_Acquire( device ); + ok( hr == DI_OK, "IDirectInputDevice8_Unacquire returned: %#x\n", hr ); + + prop_dword.dwData = 0xdeadbeef; + hr = IDirectInputDevice8_GetProperty( device, DIPROP_AXISMODE, &prop_dword.diph ); + todo_wine + ok( hr == DI_OK, "IDirectInputDevice8_GetProperty DIPROP_AXISMODE returned %#x\n", hr ); + todo_wine + ok( prop_dword.dwData == DIPROPAXISMODE_REL, "got %u expected %u\n", prop_dword.dwData, DIPROPAXISMODE_REL ); + + prop_dword.dwData = 0xdeadbeef; + hr = IDirectInputDevice8_GetProperty( device, DIPROP_BUFFERSIZE, &prop_dword.diph ); + ok( hr == DI_OK, "IDirectInputDevice8_GetProperty DIPROP_BUFFERSIZE returned %#x\n", hr ); + ok( prop_dword.dwData == 0x1000, "got %#x expected %#x\n", prop_dword.dwData, 0x1000 ); + + prop_pointer.diph.dwHow = DIPH_BYUSAGE; + prop_pointer.diph.dwObj = MAKELONG( HID_USAGE_GENERIC_X, HID_USAGE_PAGE_GENERIC ); + hr = IDirectInputDevice8_GetProperty( device, DIPROP_APPDATA, &prop_pointer.diph ); + todo_wine + ok( hr == DI_OK, "IDirectInputDevice8_GetProperty DIPROP_APPDATA returned %#x\n", hr ); + ok( prop_pointer.uData == 0xfeedcafe, "got %p expected %p\n", (void *)prop_pointer.uData, (void *)0xfeedcafe ); + + prop_dword.diph.dwHow = DIPH_DEVICE; + prop_dword.diph.dwObj = 0; + prop_dword.dwData = 0xdeadbeef; + hr = IDirectInputDevice8_SetProperty( device, DIPROP_FFGAIN, &prop_dword.diph ); + todo_wine + ok( hr == DIERR_INVALIDPARAM, "IDirectInputDevice8_SetProperty DIPROP_FFGAIN returned %#x\n", hr ); + prop_dword.dwData = 1000; + hr = IDirectInputDevice8_SetProperty( device, DIPROP_FFGAIN, &prop_dword.diph ); + todo_wine + ok( hr == DI_OK, "IDirectInputDevice8_SetProperty DIPROP_FFGAIN returned %#x\n", hr ); + + prop_dword.dwData = 0xdeadbeef; + hr = IDirectInputDevice8_SetProperty( device, DIPROP_CALIBRATION, &prop_dword.diph ); + todo_wine + ok( hr == DIERR_INVALIDPARAM, "IDirectInputDevice8_SetProperty DIPROP_CALIBRATION returned %#x\n", hr ); + prop_dword.dwData = 0xdeadbeef; + hr = IDirectInputDevice8_SetProperty( device, DIPROP_DEADZONE, &prop_dword.diph ); + todo_wine + ok( hr == DIERR_INVALIDPARAM, "IDirectInputDevice8_SetProperty DIPROP_DEADZONE returned %#x\n", hr ); + prop_dword.dwData = 0xdeadbeef; + hr = IDirectInputDevice8_SetProperty( device, DIPROP_SATURATION, &prop_dword.diph ); + todo_wine + ok( hr == DIERR_INVALIDPARAM, "IDirectInputDevice8_SetProperty DIPROP_SATURATION returned %#x\n", hr ); + + for (i = 0; i < ARRAY_SIZE(injected_input); ++i) + { + winetest_push_context( "state[%d]", i ); + hr = IDirectInputDevice8_GetDeviceState( device, sizeof(DIJOYSTATE2), &state ); + ok( hr == DI_OK, "IDirectInputDevice8_GetDeviceState returned: %#x\n", hr ); + todo_wine + check_member( state, expect_state_rel[i], "%d", lX ); + todo_wine + check_member( state, expect_state_rel[i], "%d", lY ); + check_member( state, expect_state_rel[i], "%d", lZ ); + check_member( state, expect_state_rel[i], "%d", rgdwPOV[0] ); + check_member( state, expect_state_rel[i], "%d", rgdwPOV[1] ); + check_member( state, expect_state_rel[i], "%#x", rgbButtons[0] ); + check_member( state, expect_state_rel[i], "%#x", rgbButtons[1] ); + check_member( state, expect_state_rel[i], "%#x", rgbButtons[2] ); + + send_hid_input( file, &injected_input[i], sizeof(*injected_input) ); + + res = WaitForSingleObject( event, 100 ); + if (i == 3) ok( res == WAIT_TIMEOUT, "WaitForSingleObject succeeded\n" ); + else ok( res == WAIT_OBJECT_0, "WaitForSingleObject failed\n" ); + ResetEvent( event ); + winetest_pop_context(); + } + + hr = IDirectInputDevice8_GetDeviceState( device, sizeof(DIJOYSTATE2), &state ); + ok( hr == DI_OK, "IDirectInputDevice8_GetDeviceState returned: %#x\n", hr ); + winetest_push_context( "state[%d]", i ); + todo_wine + check_member( state, expect_state_rel[i], "%d", lX ); + todo_wine + check_member( state, expect_state_rel[i], "%d", lY ); + check_member( state, expect_state_rel[i], "%d", lZ ); + check_member( state, expect_state_rel[i], "%d", rgdwPOV[0] ); + check_member( state, expect_state_rel[i], "%d", rgdwPOV[1] ); + check_member( state, expect_state_rel[i], "%#x", rgbButtons[0] ); + check_member( state, expect_state_rel[i], "%#x", rgbButtons[1] ); + check_member( state, expect_state_rel[i], "%#x", rgbButtons[2] ); + winetest_pop_context(); + hr = IDirectInputDevice8_Unacquire( device ); ok( hr == DI_OK, "IDirectInputDevice8_Unacquire returned: %#x\n", hr );
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput8/tests/hid.c | 167 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 167 insertions(+)
diff --git a/dlls/dinput8/tests/hid.c b/dlls/dinput8/tests/hid.c index 2af38452471..12f17b1b06b 100644 --- a/dlls/dinput8/tests/hid.c +++ b/dlls/dinput8/tests/hid.c @@ -52,6 +52,7 @@ #include "ddk/hidsdi.h" #include "ddk/hidpi.h" #include "ddk/hidport.h" +#include "hidusage.h" #include "devguid.h"
#include "wine/test.h" @@ -60,6 +61,7 @@ #include "driver_hid.h"
static HINSTANCE instance; +static BOOL localized; /* object names get translated */
#define EXPECT_VIDPID MAKELONG( 0x1209, 0x0001 ) static const WCHAR expect_vidpid_str[] = L"VID_1209&PID_0001"; @@ -3289,6 +3291,65 @@ static BOOL CALLBACK find_test_device( const DIDEVICEINSTANCEW *devinst, void *c return DIENUM_CONTINUE; }
+struct check_objects_todos +{ + BOOL ofs; + BOOL type; + BOOL collection_number; +}; + +struct check_objects_params +{ + UINT index; + UINT expect_count; + const DIDEVICEOBJECTINSTANCEW *expect_objs; + const struct check_objects_todos *todo_objs; +}; + +static BOOL CALLBACK check_objects( const DIDEVICEOBJECTINSTANCEW *obj, void *args ) +{ + static const DIDEVICEOBJECTINSTANCEW unexpected_obj = {0}; + struct check_objects_params *params = args; + const DIDEVICEOBJECTINSTANCEW *exp = params->expect_objs + params->index; + const struct check_objects_todos *todo = params->todo_objs + params->index; + + winetest_push_context( "obj[%d]", params->index ); + + ok( params->index < params->expect_count, "unexpected extra object\n" ); + if (params->index >= params->expect_count) exp = &unexpected_obj; + + check_member( *obj, *exp, "%u", dwSize ); + check_member_guid( *obj, *exp, guidType ); + todo_wine_if( todo->ofs ) + check_member( *obj, *exp, "%#x", dwOfs ); + todo_wine_if( todo->type ) + check_member( *obj, *exp, "%#x", dwType ); + check_member( *obj, *exp, "%#x", dwFlags ); + if (!localized) todo_wine check_member_wstr( *obj, *exp, tszName ); + check_member( *obj, *exp, "%u", dwFFMaxForce ); + check_member( *obj, *exp, "%u", dwFFForceResolution ); + todo_wine_if( todo->collection_number ) + check_member( *obj, *exp, "%u", wCollectionNumber ); + check_member( *obj, *exp, "%u", wDesignatorIndex ); + check_member( *obj, *exp, "%#04x", wUsagePage ); + check_member( *obj, *exp, "%#04x", wUsage ); + check_member( *obj, *exp, "%#04x", dwDimension ); + check_member( *obj, *exp, "%#04x", wExponent ); + check_member( *obj, *exp, "%u", wReportId ); + + winetest_pop_context(); + + params->index++; + return DIENUM_CONTINUE; +} + +static BOOL CALLBACK check_object_count( const DIDEVICEOBJECTINSTANCEW *obj, void *args ) +{ + DWORD *count = args; + *count = *count + 1; + return DIENUM_CONTINUE; +} + static void test_simple_joystick(void) { #include "psh_hid_macros.h" @@ -3436,7 +3497,98 @@ static void test_simple_joystick(void) .wUsagePage = HID_USAGE_PAGE_GENERIC, .wUsage = HID_USAGE_GENERIC_JOYSTICK, }; + const DIDEVICEOBJECTINSTANCEW expect_objects[] = + { + { + .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW), + .guidType = GUID_YAxis, + .dwType = DIDFT_ABSAXIS|DIDFT_MAKEINSTANCE(1), + .dwFlags = DIDOI_ASPECTPOSITION, + .tszName = L"Y Axis", + .wCollectionNumber = 1, + .wUsagePage = HID_USAGE_PAGE_GENERIC, + .wUsage = HID_USAGE_GENERIC_Y, + .wReportId = 1, + }, + { + .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW), + .guidType = GUID_XAxis, + .dwOfs = 0x4, + .dwType = DIDFT_ABSAXIS|DIDFT_MAKEINSTANCE(0), + .dwFlags = DIDOI_ASPECTPOSITION, + .tszName = L"X Axis", + .wCollectionNumber = 1, + .wUsagePage = HID_USAGE_PAGE_GENERIC, + .wUsage = HID_USAGE_GENERIC_X, + .wReportId = 1, + }, + { + .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW), + .guidType = GUID_POV, + .dwOfs = 0x8, + .dwType = DIDFT_POV|DIDFT_MAKEINSTANCE(0), + .tszName = L"Hat Switch", + .wCollectionNumber = 1, + .wUsagePage = HID_USAGE_PAGE_GENERIC, + .wUsage = HID_USAGE_GENERIC_HATSWITCH, + .wReportId = 1, + }, + { + .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW), + .guidType = GUID_Button, + .dwOfs = 0xc, + .dwType = DIDFT_PSHBUTTON|DIDFT_MAKEINSTANCE(0), + .tszName = L"Button 0", + .wCollectionNumber = 1, + .wUsagePage = HID_USAGE_PAGE_BUTTON, + .wUsage = 0x1, + .wReportId = 1, + }, + { + .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW), + .guidType = GUID_Button, + .dwOfs = 0xd, + .dwType = DIDFT_PSHBUTTON|DIDFT_MAKEINSTANCE(1), + .tszName = L"Button 1", + .wCollectionNumber = 1, + .wUsagePage = HID_USAGE_PAGE_BUTTON, + .wUsage = 0x2, + .wReportId = 1, + }, + { + .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW), + .guidType = GUID_Unknown, + .dwType = DIDFT_COLLECTION|DIDFT_NODATA|DIDFT_MAKEINSTANCE(0), + .tszName = L"Collection 0 - Joystick", + .wUsagePage = HID_USAGE_PAGE_GENERIC, + .wUsage = HID_USAGE_GENERIC_JOYSTICK, + }, + { + .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW), + .guidType = GUID_Unknown, + .dwType = DIDFT_COLLECTION|DIDFT_NODATA|DIDFT_MAKEINSTANCE(1), + .tszName = L"Collection 1 - Joystick", + .wUsagePage = HID_USAGE_PAGE_GENERIC, + .wUsage = HID_USAGE_GENERIC_JOYSTICK, + }, + }; + const struct check_objects_todos objects_todos[ARRAY_SIZE(expect_objects)] = + { + {.ofs = TRUE, .type = TRUE, .collection_number = TRUE}, + {.ofs = TRUE, .type = TRUE, .collection_number = TRUE}, + {.ofs = TRUE, .collection_number = TRUE}, + {.ofs = TRUE, .collection_number = TRUE}, + {.ofs = TRUE, .collection_number = TRUE}, + {}, + {.type = TRUE}, + };
+ struct check_objects_params check_objects_params = + { + .expect_count = ARRAY_SIZE(expect_objects), + .expect_objs = expect_objects, + .todo_objs = objects_todos, + }; DIPROPGUIDANDPATH prop_guid_path = { .diph = @@ -3763,6 +3915,20 @@ static void test_simple_joystick(void) todo_wine ok( hr == DIERR_NOTINITIALIZED, "IDirectInputDevice8_GetProperty DIPROP_APPDATA returned %#x\n", hr );
+ hr = IDirectInputDevice8_EnumObjects( device, NULL, NULL, DIDFT_ALL ); + ok( hr == DIERR_INVALIDPARAM, "IDirectInputDevice8_EnumObjects returned %#x\n", hr ); + hr = IDirectInputDevice8_EnumObjects( device, check_object_count, &res, 0x20 ); + todo_wine + ok( hr == DIERR_INVALIDPARAM, "IDirectInputDevice8_EnumObjects returned %#x\n", hr ); + res = 0; + hr = IDirectInputDevice8_EnumObjects( device, check_object_count, &res, DIDFT_AXIS | DIDFT_PSHBUTTON ); + ok( hr == DI_OK, "IDirectInputDevice8_EnumObjects returned %#x\n", hr ); + ok( res == 4, "got %u expected %u\n", res, 4 ); + hr = IDirectInputDevice8_EnumObjects( device, check_objects, &check_objects_params, DIDFT_ALL ); + ok( hr == DI_OK, "IDirectInputDevice8_EnumObjects returned %#x\n", hr ); + ok( check_objects_params.index >= check_objects_params.expect_count, "missing %u objects\n", + check_objects_params.expect_count - check_objects_params.index ); + hr = IDirectInputDevice8_SetDataFormat( device, NULL ); ok( hr == E_POINTER, "IDirectInputDevice8_SetDataFormat returned: %#x\n", hr ); hr = IDirectInputDevice8_SetDataFormat( device, &dataformat ); @@ -4392,6 +4558,7 @@ START_TEST( hid ) BOOL is_wow64;
instance = GetModuleHandleW( NULL ); + localized = GetUserDefaultLCID() != MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT); pSignerSign = (void *)GetProcAddress( LoadLibraryW( L"mssign32" ), "SignerSign" );
if (IsWow64Process( GetCurrentProcess(), &is_wow64 ) && is_wow64)
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=98204
Your paranoid android.
=== debiant2 (64 bit WoW report) ===
dinput8: hid.c:4105: Test succeeded inside todo block: got dwSequence 0xa, expected 0xa hid.c:4117: Test succeeded inside todo block: objdata[0]: got dwSequence 0xa, expected 0xa hid.c:4117: Test succeeded inside todo block: objdata[1]: got dwSequence 0xa, expected 0xa hid.c:4117: Test succeeded inside todo block: objdata[2]: got dwSequence 0xa, expected 0xa hid.c:4117: Test succeeded inside todo block: objdata[3]: got dwSequence 0xa, expected 0xa