Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52061 Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput8/tests/driver_hid.c | 13 ++- dlls/dinput8/tests/driver_hid.h | 1 + dlls/dinput8/tests/hid.c | 135 ++++++++++++++++++++++++++++++-- 3 files changed, 137 insertions(+), 12 deletions(-)
diff --git a/dlls/dinput8/tests/driver_hid.c b/dlls/dinput8/tests/driver_hid.c index 2201fd07080..db7b3185906 100644 --- a/dlls/dinput8/tests/driver_hid.c +++ b/dlls/dinput8/tests/driver_hid.c @@ -122,7 +122,7 @@ static void expect_queue_reset( struct expect_queue *queue, void *buffer, unsign else { todo_wine_if( tmp->todo ) - ok( 0, "missing (code %#x id %u len %u)\n", tmp->code, tmp->report_id, tmp->report_len ); + ok( tmp->wine_only, "missing (code %#x id %u len %u)\n", tmp->code, tmp->report_id, tmp->report_len ); } winetest_pop_context(); tmp++; @@ -198,7 +198,7 @@ static void expect_queue_next( struct expect_queue *queue, ULONG code, HID_XFER_ while (tmp < queue->end) { if (running_under_wine && !tmp->todo) break; - if (!running_under_wine && !tmp->broken) break; + if (!running_under_wine && !tmp->broken && !tmp->wine_only) break; if (tmp->code == code && tmp->report_id == id && tmp->report_len == len && (!compare_buf || RtlCompareMemory( tmp->report_buf, buf, len ) == len)) break; @@ -209,6 +209,11 @@ static void expect_queue_next( struct expect_queue *queue, ULONG code, HID_XFER_ else tmp = &queue->spurious; *expect = *tmp;
+ while (queue->pos < queue->end) + { + if (running_under_wine || !queue->pos->wine_only) break; + queue->pos++; + } if (queue->pos == queue->end && (irp = queue->pending_wait)) { queue->pending_wait = NULL; @@ -227,7 +232,7 @@ static void expect_queue_next( struct expect_queue *queue, ULONG code, HID_XFER_
winetest_push_context( "%s expect[%d]", tmp->context, tmp - queue->buffer ); todo_wine_if( tmp->todo ) - ok( 1, "found code %#x id %u len %u\n", tmp->code, tmp->report_id, tmp->report_len ); + ok( !tmp->wine_only, "found code %#x id %u len %u\n", tmp->code, tmp->report_id, tmp->report_len ); winetest_pop_context();
tmp = missing; @@ -242,7 +247,7 @@ static void expect_queue_next( struct expect_queue *queue, ULONG code, HID_XFER_ else { todo_wine_if( tmp->todo ) - ok( 0, "missing (code %#x id %u len %u)\n", tmp->code, tmp->report_id, tmp->report_len ); + ok( tmp->wine_only, "missing (code %#x id %u len %u)\n", tmp->code, tmp->report_id, tmp->report_len ); } winetest_pop_context(); tmp++; diff --git a/dlls/dinput8/tests/driver_hid.h b/dlls/dinput8/tests/driver_hid.h index ffd45bd2e35..191c0c7bae2 100644 --- a/dlls/dinput8/tests/driver_hid.h +++ b/dlls/dinput8/tests/driver_hid.h @@ -50,6 +50,7 @@ struct hid_expect DWORD ret_status; BYTE todo; /* missing on wine */ BYTE broken; /* missing on some win versions */ + BYTE wine_only; BYTE report_id; BYTE report_len; BYTE report_buf[128]; diff --git a/dlls/dinput8/tests/hid.c b/dlls/dinput8/tests/hid.c index f1342c5714d..884a0100abe 100644 --- a/dlls/dinput8/tests/hid.c +++ b/dlls/dinput8/tests/hid.c @@ -743,7 +743,8 @@ static inline void check_hidp_value_caps_( int line, HIDP_VALUE_CAPS *caps, cons } }
-static BOOL sync_ioctl( HANDLE file, DWORD code, void *in_buf, DWORD in_len, void *out_buf, DWORD *ret_len, DWORD timeout ) +#define sync_ioctl( a, b, c, d, e, f, g ) sync_ioctl_( __LINE__, a, b, c, d, e, f, g ) +static BOOL sync_ioctl_( int line, HANDLE file, DWORD code, void *in_buf, DWORD in_len, void *out_buf, DWORD *ret_len, DWORD timeout ) { DWORD res, out_len = ret_len ? *ret_len : 0; OVERLAPPED ovl = {0}; @@ -754,9 +755,9 @@ static BOOL sync_ioctl( HANDLE file, DWORD code, void *in_buf, DWORD in_len, voi if (!ret && GetLastError() == ERROR_IO_PENDING) { res = WaitForSingleObject( ovl.hEvent, timeout ); - ok( res == WAIT_OBJECT_0, "WaitForSingleObject returned %#x\n", res ); + ok_(__FILE__, line)( res == WAIT_OBJECT_0, "WaitForSingleObject returned %#x\n", res ); ret = GetOverlappedResult( file, &ovl, &out_len, FALSE ); - ok( ret, "GetOverlappedResult returned %u\n", GetLastError() ); + ok_(__FILE__, line)( ret, "GetOverlappedResult returned %u\n", GetLastError() ); } CloseHandle( ovl.hEvent );
@@ -779,17 +780,17 @@ static void set_hid_expect_( int line, HANDLE file, struct hid_expect *expect, D for (i = 0; i < expect_size / sizeof(struct hid_expect); ++i) snprintf( expect[i].context, ARRAY_SIZE(expect[i].context), "%s:%d", source_file, line );
- ret = sync_ioctl( file, IOCTL_WINETEST_HID_SET_EXPECT, expect, expect_size, NULL, 0, INFINITE ); - ok( ret, "IOCTL_WINETEST_HID_SET_EXPECT failed, last error %u\n", GetLastError() ); + ret = sync_ioctl_( line, file, IOCTL_WINETEST_HID_SET_EXPECT, expect, expect_size, NULL, 0, INFINITE ); + ok_(__FILE__, line)( ret, "IOCTL_WINETEST_HID_SET_EXPECT failed, last error %u\n", GetLastError() ); }
#define wait_hid_expect( a, b ) wait_hid_expect_( __LINE__, a, b ) static void wait_hid_expect_( int line, HANDLE file, DWORD timeout ) { - BOOL ret = sync_ioctl( file, IOCTL_WINETEST_HID_WAIT_EXPECT, NULL, 0, NULL, 0, timeout ); - ok( ret, "IOCTL_WINETEST_HID_WAIT_EXPECT failed, last error %u\n", GetLastError() ); + BOOL ret = sync_ioctl_( line, file, IOCTL_WINETEST_HID_WAIT_EXPECT, NULL, 0, NULL, 0, timeout ); + ok_(__FILE__, line)( ret, "IOCTL_WINETEST_HID_WAIT_EXPECT failed, last error %u\n", GetLastError() );
- set_hid_expect( file, NULL, 0 ); + set_hid_expect_( line, file, NULL, 0 ); }
#define send_hid_input( a, b, c ) send_hid_input_( __LINE__, a, b, c ) @@ -5601,6 +5602,91 @@ static void test_periodic_effect( IDirectInputDevice8W *device, HANDLE file, DWO .report_buf = {0x02,0x01,0x01,0x01}, }, }; + struct hid_expect expect_download_2[] = + { + /* set periodic */ + { + .code = IOCTL_HID_WRITE_REPORT, + .report_id = 5, + .report_len = 2, + .report_buf = {0x05,0x19}, + }, + /* set envelope */ + { + .code = IOCTL_HID_WRITE_REPORT, + .report_id = 6, + .report_len = 7, + .report_buf = {0x06,0x19,0x4c,0x02,0x00,0x04,0x00}, + }, + /* update effect */ + { + .code = IOCTL_HID_WRITE_REPORT, + .report_id = 3, + .report_len = 11, + .report_buf = {0x03,0x01,0x02,0x08,0x01,0x00,version >= 0x700 ? 0x06 : 0x00,0x00,0x01,0x55,0xd5}, + }, + }; + struct hid_expect expect_update[] = + { + /* set periodic */ + { + .code = IOCTL_HID_WRITE_REPORT, + .report_id = 5, + .report_len = 2, + .report_buf = {0x05,0x19}, + .wine_only = TRUE, .todo = TRUE, + }, + /* set envelope */ + { + .code = IOCTL_HID_WRITE_REPORT, + .report_id = 6, + .report_len = 7, + .report_buf = {0x06,0x19,0x4c,0x02,0x00,0x04,0x00}, + .wine_only = TRUE, .todo = TRUE, + }, + /* update effect */ + { + .code = IOCTL_HID_WRITE_REPORT, + .report_id = 3, + .report_len = 11, + .report_buf = {0x03,0x01,0x02,0x08,0xff,0xff,version >= 0x700 ? 0x06 : 0x00,0x00,0x01,0x55,0xd5}, + .todo = TRUE, + }, + /* update effect */ + { + .code = IOCTL_HID_WRITE_REPORT, + .report_id = 3, + .report_len = 11, + .report_buf = {0x03,0x01,0x02,0x08,0x00,0x00,version >= 0x700 ? 0x06 : 0x00,0x00,0x01,0x55,0xd5}, + .wine_only = TRUE, .todo = TRUE, + }, + }; + struct hid_expect expect_set_envelope[] = + { + /* set periodic */ + { + .code = IOCTL_HID_WRITE_REPORT, + .report_id = 5, + .report_len = 2, + .report_buf = {0x05,0x19}, + .wine_only = TRUE, .todo = TRUE, + }, + /* set envelope */ + { + .code = IOCTL_HID_WRITE_REPORT, + .report_id = 6, + .report_len = 7, + .report_buf = {0x06,0x19,0x4c,0x01,0x00,0x04,0x00}, + }, + /* update effect */ + { + .code = IOCTL_HID_WRITE_REPORT, + .report_id = 3, + .report_len = 11, + .report_buf = {0x03,0x01,0x02,0x08,0x00,0x00,version >= 0x700 ? 0x06 : 0x00,0x00,0x01,0x55,0xd5}, + .wine_only = TRUE, .todo = TRUE, + }, + }; struct hid_expect expect_start = { .code = IOCTL_HID_WRITE_REPORT, @@ -6409,6 +6495,39 @@ static void test_periodic_effect( IDirectInputDevice8W *device, HANDLE file, DWO winetest_pop_context(); }
+ hr = IDirectInputDevice8_CreateEffect( device, &GUID_Sine, NULL, &effect, NULL ); + ok( hr == DI_OK, "CreateEffect returned %#x\n", hr ); + + set_hid_expect( file, expect_download_2, sizeof(expect_download_2) ); + flags = version >= 0x700 ? DIEP_ALLPARAMS : DIEP_ALLPARAMS_DX5; + hr = IDirectInputEffect_SetParameters( effect, &expect_desc, flags ); + ok( hr == DI_OK, "SetParameters returned %#x\n", hr ); + set_hid_expect( file, NULL, 0 ); + desc = expect_desc; + desc.dwDuration = INFINITE; + desc.dwTriggerButton = DIDFT_PSHBUTTON | DIDFT_MAKEINSTANCE( 0 ) | DIDFT_FFEFFECTTRIGGER, + hr = IDirectInputEffect_SetParameters( effect, &desc, DIEP_NODOWNLOAD|DIEP_DURATION|DIEP_TRIGGERBUTTON ); + ok( hr == DI_DOWNLOADSKIPPED, "SetParameters returned %#x\n", hr ); + set_hid_expect( file, expect_update, sizeof(expect_update) ); + hr = IDirectInputEffect_SetParameters( effect, &expect_desc, 0 ); + ok( hr == DI_OK, "SetParameters returned %#x\n", hr ); + wait_hid_expect( file, 100 ); /* these updates are sent asynchronously */ + + desc = expect_desc; + desc.lpEnvelope = &envelope; + desc.lpEnvelope->dwAttackTime = 1000; + hr = IDirectInputEffect_SetParameters( effect, &desc, DIEP_NODOWNLOAD|DIEP_ENVELOPE ); + ok( hr == DI_DOWNLOADSKIPPED, "SetParameters returned %#x\n", hr ); + set_hid_expect( file, expect_set_envelope, sizeof(expect_set_envelope) ); + hr = IDirectInputEffect_SetParameters( effect, &expect_desc, 0 ); + ok( hr == DI_OK, "SetParameters returned %#x\n", hr ); + wait_hid_expect( file, 100 ); /* these updates are sent asynchronously */ + + set_hid_expect( file, &expect_stop, sizeof(expect_stop) ); + ref = IDirectInputEffect_Release( effect ); + ok( ref == 0, "Release returned %d\n", ref ); + set_hid_expect( file, NULL, 0 ); + set_hid_expect( file, expect_reset, sizeof(expect_reset) ); hr = IDirectInputDevice8_Unacquire( device ); ok( hr == DI_OK, "Acquire returned: %#x\n", hr );