From: Rémi Bernon rbernon@codeweavers.com
--- dlls/dinput/device.c | 9 ++++++--- dlls/dinput/tests/joystick8.c | 4 ---- 2 files changed, 6 insertions(+), 7 deletions(-)
diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c index a17df9aa69d..9dd7a3f478f 100644 --- a/dlls/dinput/device.c +++ b/dlls/dinput/device.c @@ -2084,9 +2084,12 @@ static HRESULT WINAPI dinput_device_SetActionMap( IDirectInputDevice8W *iface, D
free( obj_df );
- prop_range.lMin = format->lAxisMin; - prop_range.lMax = format->lAxisMax; - IDirectInputDevice8_SetProperty( iface, DIPROP_RANGE, &prop_range.diph ); + if (format->lAxisMin != format->lAxisMax) + { + prop_range.lMin = format->lAxisMin; + prop_range.lMax = format->lAxisMax; + IDirectInputDevice8_SetProperty( iface, DIPROP_RANGE, &prop_range.diph ); + }
prop_buffer.dwData = format->dwBufferSize; IDirectInputDevice8_SetProperty( iface, DIPROP_BUFFERSIZE, &prop_buffer.diph ); diff --git a/dlls/dinput/tests/joystick8.c b/dlls/dinput/tests/joystick8.c index 48e097dcafa..22a83f911bc 100644 --- a/dlls/dinput/tests/joystick8.c +++ b/dlls/dinput/tests/joystick8.c @@ -925,18 +925,14 @@ static void test_action_map( IDirectInputDevice8W *device, HANDLE file, HANDLE e prop_range.diph.dwObj = DIDFT_ABSAXIS | DIDFT_MAKEINSTANCE( 2 ); hr = IDirectInputDevice8_GetProperty( device, DIPROP_RANGE, &prop_range.diph ); ok( hr == DI_OK, "GetProperty returned %#lx\n", hr ); - todo_wine ok( prop_range.lMin == +1000, "got lMin %+ld\n", prop_range.lMin ); - todo_wine ok( prop_range.lMax == +51000, "got lMax %+ld\n", prop_range.lMax );
prop_range.diph.dwHow = DIPH_BYUSAGE; prop_range.diph.dwObj = MAKELONG(HID_USAGE_GENERIC_X, HID_USAGE_PAGE_GENERIC); hr = IDirectInputDevice8_GetProperty( device, DIPROP_RANGE, &prop_range.diph ); ok( hr == DI_OK, "GetProperty returned %#lx\n", hr ); - todo_wine ok( prop_range.lMin == -14000, "got lMin %+ld\n", prop_range.lMin ); - todo_wine ok( prop_range.lMax == -4000, "got lMax %+ld\n", prop_range.lMax );
hr = IDirectInputDevice8_GetProperty( device, DIPROP_BUFFERSIZE, &prop_dword.diph );
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/dinput/device.c | 4 +--- dlls/dinput/tests/joystick8.c | 8 ++++---- 2 files changed, 5 insertions(+), 7 deletions(-)
diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c index 9dd7a3f478f..fb7be1e2e6d 100644 --- a/dlls/dinput/device.c +++ b/dlls/dinput/device.c @@ -2052,7 +2052,7 @@ static HRESULT WINAPI dinput_device_SetActionMap( IDirectInputDevice8W *iface, D
action_map = malloc( sizeof(ActionMap) * num_actions );
- for (i = 0; i < format->dwNumActions; i++) + for (i = 0; i < format->dwNumActions; i++, offset += sizeof(ULONG)) { if (IsEqualGUID( &impl->guid, &format->rgoAction[i].guidInstance )) { @@ -2070,9 +2070,7 @@ static HRESULT WINAPI dinput_device_SetActionMap( IDirectInputDevice8W *iface, D action_map[action].uAppData = format->rgoAction[i].uAppData; action_map[action].offset = offset; obj_df[action].dwOfs = offset; - offset += (type & DIDFT_BUTTON) ? 1 : 4; data_format.dwNumObjs++; - action++; } } diff --git a/dlls/dinput/tests/joystick8.c b/dlls/dinput/tests/joystick8.c index 22a83f911bc..1ca2975a15e 100644 --- a/dlls/dinput/tests/joystick8.c +++ b/dlls/dinput/tests/joystick8.c @@ -1046,13 +1046,13 @@ static void test_action_map( IDirectInputDevice8W *device, HANDLE file, HANDLE e
hr = IDirectInputDevice8_GetDeviceState( device, sizeof(state), state ); ok( hr == DI_OK, "GetDeviceState returned: %#lx\n", hr ); - todo_wine + todo_wine_if( i > 5 ) ok( state[0] == expect_state[i][0], "got state[0] %+ld\n", state[0] ); - todo_wine_if( i != 2 ) + todo_wine_if( i == 2 || i > 4 ) ok( state[1] == expect_state[i][1], "got state[1] %+ld\n", state[1] ); todo_wine_if( expect_state[i][2] ) ok( state[2] == expect_state[i][2], "got state[2] %+ld\n", state[2] ); - todo_wine_if( expect_state[i][3] ) + todo_wine_if( i > 5 ) ok( state[3] == expect_state[i][3], "got state[3] %+ld\n", state[3] ); todo_wine_if( expect_state[i][4] ) ok( state[4] == expect_state[i][4], "got state[4] %+ld\n", state[4] ); @@ -1082,7 +1082,7 @@ static void test_action_map( IDirectInputDevice8W *device, HANDLE file, HANDLE e while (res--) { winetest_push_context( "%lu", res ); - todo_wine + todo_wine_if( res != 1 && res != 4 ) check_member( objdata[res], expect_objdata[res], "%#lx", dwOfs ); todo_wine_if( res == 0 || res == 3 || res == 6 ) ok( objdata[res].dwData == expect_objdata[res].dwData ||
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/dinput/device.c | 50 +++++++---------------------------- dlls/dinput/tests/joystick8.c | 11 +++----- 2 files changed, 14 insertions(+), 47 deletions(-)
diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c index fb7be1e2e6d..28494c3bec6 100644 --- a/dlls/dinput/device.c +++ b/dlls/dinput/device.c @@ -1975,7 +1975,6 @@ static HRESULT WINAPI dinput_device_SetActionMap( IDirectInputDevice8W *iface, D const WCHAR *username, DWORD flags ) { struct dinput_device *impl = impl_from_IDirectInputDevice8W( iface ); - DIOBJECTDATAFORMAT *obj_df = NULL; DIDATAFORMAT data_format = { .dwSize = sizeof(DIDATAFORMAT), @@ -2011,9 +2010,8 @@ static HRESULT WINAPI dinput_device_SetActionMap( IDirectInputDevice8W *iface, D }; WCHAR username_buf[MAX_PATH]; DWORD username_len = MAX_PATH; - int i, action = 0, num_actions = 0; + int i, index, action = 0, num_actions = 0; unsigned int offset = 0; - const DIDATAFORMAT *df; ActionMap *action_map;
FIXME( "iface %p, format %p, username %s, flags %#lx stub!\n", iface, format, @@ -2021,21 +2019,6 @@ static HRESULT WINAPI dinput_device_SetActionMap( IDirectInputDevice8W *iface, D
if (!format) return DIERR_INVALIDPARAM;
- switch (GET_DIDEVICE_TYPE( impl->instance.dwDevType )) - { - case DIDEVTYPE_KEYBOARD: - case DI8DEVTYPE_KEYBOARD: - df = &c_dfDIKeyboard; - break; - case DIDEVTYPE_MOUSE: - case DI8DEVTYPE_MOUSE: - df = &c_dfDIMouse2; - break; - default: - df = &impl->device_format; - break; - } - if (impl->status == STATUS_ACQUIRED) return DIERR_ACQUIRED;
/* Count the actions */ @@ -2045,34 +2028,21 @@ static HRESULT WINAPI dinput_device_SetActionMap( IDirectInputDevice8W *iface, D
if (num_actions == 0) return DI_NOEFFECT;
- /* Construct the dataformat and actionmap */ - obj_df = malloc( sizeof(DIOBJECTDATAFORMAT) * num_actions ); - data_format.rgodf = (LPDIOBJECTDATAFORMAT)obj_df; + data_format.rgodf = malloc( sizeof(DIOBJECTDATAFORMAT) * num_actions ); data_format.dwDataSize = format->dwDataSize;
action_map = malloc( sizeof(ActionMap) * num_actions );
for (i = 0; i < format->dwNumActions; i++, offset += sizeof(ULONG)) { - if (IsEqualGUID( &impl->guid, &format->rgoAction[i].guidInstance )) - { - DWORD inst = DIDFT_GETINSTANCE( format->rgoAction[i].dwObjID ); - DWORD type = DIDFT_GETTYPE( format->rgoAction[i].dwObjID ); - LPDIOBJECTDATAFORMAT obj; - - if (type == DIDFT_PSHBUTTON) type = DIDFT_BUTTON; - if (type == DIDFT_RELAXIS) type = DIDFT_AXIS; + if (!IsEqualGUID( &impl->guid, &format->rgoAction[i].guidInstance )) continue; + if ((index = dinput_device_object_index_from_id( iface, format->rgoAction[i].dwObjID )) < 0) continue;
- if (!(obj = dataformat_to_odf_by_type( df, inst, type ))) continue; - - memcpy( &obj_df[action], obj, df->dwObjSize ); - - action_map[action].uAppData = format->rgoAction[i].uAppData; - action_map[action].offset = offset; - obj_df[action].dwOfs = offset; - data_format.dwNumObjs++; - action++; - } + action_map[action].uAppData = format->rgoAction[i].uAppData; + action_map[action].offset = offset; + data_format.rgodf[data_format.dwNumObjs] = impl->device_format.rgodf[index]; + data_format.rgodf[data_format.dwNumObjs].dwOfs = offset; + data_format.dwNumObjs++; }
IDirectInputDevice8_SetDataFormat( iface, &data_format ); @@ -2080,7 +2050,7 @@ static HRESULT WINAPI dinput_device_SetActionMap( IDirectInputDevice8W *iface, D impl->action_map = action_map; impl->num_actions = num_actions;
- free( obj_df ); + free( data_format.rgodf );
if (format->lAxisMin != format->lAxisMax) { diff --git a/dlls/dinput/tests/joystick8.c b/dlls/dinput/tests/joystick8.c index 1ca2975a15e..40fd3d23e29 100644 --- a/dlls/dinput/tests/joystick8.c +++ b/dlls/dinput/tests/joystick8.c @@ -1046,13 +1046,11 @@ static void test_action_map( IDirectInputDevice8W *device, HANDLE file, HANDLE e
hr = IDirectInputDevice8_GetDeviceState( device, sizeof(state), state ); ok( hr == DI_OK, "GetDeviceState returned: %#lx\n", hr ); - todo_wine_if( i > 5 ) ok( state[0] == expect_state[i][0], "got state[0] %+ld\n", state[0] ); - todo_wine_if( i == 2 || i > 4 ) + todo_wine_if( i == 2 || i == 5 ) ok( state[1] == expect_state[i][1], "got state[1] %+ld\n", state[1] ); todo_wine_if( expect_state[i][2] ) ok( state[2] == expect_state[i][2], "got state[2] %+ld\n", state[2] ); - todo_wine_if( i > 5 ) ok( state[3] == expect_state[i][3], "got state[3] %+ld\n", state[3] ); todo_wine_if( expect_state[i][4] ) ok( state[4] == expect_state[i][4], "got state[4] %+ld\n", state[4] ); @@ -1060,7 +1058,6 @@ static void test_action_map( IDirectInputDevice8W *device, HANDLE file, HANDLE e ok( state[5] == expect_state[i][5], "got state[5] %+ld\n", state[5] ); todo_wine_if( expect_state[i][6] ) ok( state[6] == expect_state[i][6], "got state[6] %+ld\n", state[6] ); - todo_wine_if( expect_state[i][7] ) ok( state[7] == expect_state[i][7] || broken(state[7] == -45 && expect_state[i][7] == -43) /* 32-bit rounding */, "got state[7] %+ld\n", state[7] ); @@ -1082,13 +1079,13 @@ static void test_action_map( IDirectInputDevice8W *device, HANDLE file, HANDLE e while (res--) { winetest_push_context( "%lu", res ); - todo_wine_if( res != 1 && res != 4 ) + todo_wine check_member( objdata[res], expect_objdata[res], "%#lx", dwOfs ); - todo_wine_if( res == 0 || res == 3 || res == 6 ) + todo_wine ok( objdata[res].dwData == expect_objdata[res].dwData || broken(objdata[res].dwData == -45 && expect_objdata[res].dwData == -43) /* 32-bit rounding */, "got dwData %+ld\n", objdata[res].dwData ); - todo_wine_if( res != 1 && res != 4 ) + todo_wine check_member( objdata[res], expect_objdata[res], "%#Ix", uAppData ); winetest_pop_context(); }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/dinput/device.c | 1 + dlls/dinput/tests/joystick8.c | 9 +-------- 2 files changed, 2 insertions(+), 8 deletions(-)
diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c index 28494c3bec6..e493149a474 100644 --- a/dlls/dinput/device.c +++ b/dlls/dinput/device.c @@ -2035,6 +2035,7 @@ static HRESULT WINAPI dinput_device_SetActionMap( IDirectInputDevice8W *iface, D
for (i = 0; i < format->dwNumActions; i++, offset += sizeof(ULONG)) { + if (format->rgoAction[i].dwFlags & DIA_APPNOMAP) continue; if (!IsEqualGUID( &impl->guid, &format->rgoAction[i].guidInstance )) continue; if ((index = dinput_device_object_index_from_id( iface, format->rgoAction[i].dwObjID )) < 0) continue;
diff --git a/dlls/dinput/tests/joystick8.c b/dlls/dinput/tests/joystick8.c index 40fd3d23e29..8561c4f2848 100644 --- a/dlls/dinput/tests/joystick8.c +++ b/dlls/dinput/tests/joystick8.c @@ -1047,16 +1047,11 @@ static void test_action_map( IDirectInputDevice8W *device, HANDLE file, HANDLE e hr = IDirectInputDevice8_GetDeviceState( device, sizeof(state), state ); ok( hr == DI_OK, "GetDeviceState returned: %#lx\n", hr ); ok( state[0] == expect_state[i][0], "got state[0] %+ld\n", state[0] ); - todo_wine_if( i == 2 || i == 5 ) ok( state[1] == expect_state[i][1], "got state[1] %+ld\n", state[1] ); - todo_wine_if( expect_state[i][2] ) ok( state[2] == expect_state[i][2], "got state[2] %+ld\n", state[2] ); ok( state[3] == expect_state[i][3], "got state[3] %+ld\n", state[3] ); - todo_wine_if( expect_state[i][4] ) ok( state[4] == expect_state[i][4], "got state[4] %+ld\n", state[4] ); - todo_wine_if( expect_state[i][5] ) ok( state[5] == expect_state[i][5], "got state[5] %+ld\n", state[5] ); - todo_wine_if( expect_state[i][6] ) ok( state[6] == expect_state[i][6], "got state[6] %+ld\n", state[6] ); ok( state[7] == expect_state[i][7] || broken(state[7] == -45 && expect_state[i][7] == -43) /* 32-bit rounding */, @@ -1079,13 +1074,11 @@ static void test_action_map( IDirectInputDevice8W *device, HANDLE file, HANDLE e while (res--) { winetest_push_context( "%lu", res ); - todo_wine check_member( objdata[res], expect_objdata[res], "%#lx", dwOfs ); - todo_wine ok( objdata[res].dwData == expect_objdata[res].dwData || broken(objdata[res].dwData == -45 && expect_objdata[res].dwData == -43) /* 32-bit rounding */, "got dwData %+ld\n", objdata[res].dwData ); - todo_wine + todo_wine_if( res != 0 && res != 3 && res != 6 ) check_member( objdata[res], expect_objdata[res], "%#Ix", uAppData ); winetest_pop_context(); }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/dinput/device.c | 48 +++++++++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 21 deletions(-)
diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c index e493149a474..162e4c451fb 100644 --- a/dlls/dinput/device.c +++ b/dlls/dinput/device.c @@ -2013,14 +2013,13 @@ static HRESULT WINAPI dinput_device_SetActionMap( IDirectInputDevice8W *iface, D int i, index, action = 0, num_actions = 0; unsigned int offset = 0; ActionMap *action_map; + HRESULT hr;
FIXME( "iface %p, format %p, username %s, flags %#lx stub!\n", iface, format, debugstr_w(username), flags );
if (!format) return DIERR_INVALIDPARAM;
- if (impl->status == STATUS_ACQUIRED) return DIERR_ACQUIRED; - /* Count the actions */ for (i = 0; i < format->dwNumActions; i++) if (IsEqualGUID( &impl->guid, &format->rgoAction[i].guidInstance )) @@ -2046,33 +2045,40 @@ static HRESULT WINAPI dinput_device_SetActionMap( IDirectInputDevice8W *iface, D data_format.dwNumObjs++; }
- IDirectInputDevice8_SetDataFormat( iface, &data_format ); + EnterCriticalSection( &impl->crit );
- impl->action_map = action_map; - impl->num_actions = num_actions; + if (FAILED(hr = IDirectInputDevice8_SetDataFormat( iface, &data_format ))) + WARN( "Failed to set data format from action map, hr %#lx\n", hr ); + else + { + impl->action_map = action_map; + impl->num_actions = num_actions;
- free( data_format.rgodf ); + if (format->lAxisMin != format->lAxisMax) + { + prop_range.lMin = format->lAxisMin; + prop_range.lMax = format->lAxisMax; + IDirectInputDevice8_SetProperty( iface, DIPROP_RANGE, &prop_range.diph ); + }
- if (format->lAxisMin != format->lAxisMax) - { - prop_range.lMin = format->lAxisMin; - prop_range.lMax = format->lAxisMax; - IDirectInputDevice8_SetProperty( iface, DIPROP_RANGE, &prop_range.diph ); - } + prop_buffer.dwData = format->dwBufferSize; + IDirectInputDevice8_SetProperty( iface, DIPROP_BUFFERSIZE, &prop_buffer.diph );
- prop_buffer.dwData = format->dwBufferSize; - IDirectInputDevice8_SetProperty( iface, DIPROP_BUFFERSIZE, &prop_buffer.diph ); + if (username == NULL) GetUserNameW( username_buf, &username_len ); + else lstrcpynW( username_buf, username, MAX_PATH );
- if (username == NULL) GetUserNameW( username_buf, &username_len ); - else lstrcpynW( username_buf, username, MAX_PATH ); + if (flags & DIDSAM_NOUSER) prop_username.wsz[0] = '\0'; + else lstrcpynW( prop_username.wsz, username_buf, ARRAY_SIZE(prop_username.wsz) ); + dinput_device_set_username( impl, &prop_username );
- if (flags & DIDSAM_NOUSER) prop_username.wsz[0] = '\0'; - else lstrcpynW( prop_username.wsz, username_buf, ARRAY_SIZE(prop_username.wsz) ); - dinput_device_set_username( impl, &prop_username ); + save_mapping_settings( iface, format, username_buf ); + }
- save_mapping_settings( iface, format, username_buf ); + LeaveCriticalSection( &impl->crit );
- return DI_OK; + if (FAILED(hr)) free( action_map ); + free( data_format.rgodf ); + return hr; }
static HRESULT WINAPI dinput_device_GetImageInfo( IDirectInputDevice8W *iface, DIDEVICEIMAGEINFOHEADERW *header )
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/dinput/device.c | 157 ++++++++++++---------------------- dlls/dinput/device_private.h | 11 +-- dlls/dinput/tests/joystick8.c | 12 --- 3 files changed, 54 insertions(+), 126 deletions(-)
diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c index 162e4c451fb..16c4409b9b3 100644 --- a/dlls/dinput/device.c +++ b/dlls/dinput/device.c @@ -273,6 +273,9 @@ static HRESULT dinput_device_init_user_format( struct dinput_device *impl, const user_obj = user_format->rgodf + user_format->dwNumObjs; while (user_obj-- > user_format->rgodf) user_obj->dwType |= DIDFT_OPTIONAL;
+ for (i = 0; i < device_format->dwNumObjs; i++) + impl->object_properties[i].app_data = -1; + for (i = 0; i < format->dwNumObjs; ++i) { match_obj = format->rgodf + i; @@ -297,23 +300,6 @@ failed: return DIERR_INVALIDPARAM; }
-static int id_to_offset( struct dinput_device *impl, int id ) -{ - DIDATAFORMAT *user_format = &impl->user_format; - DIOBJECTDATAFORMAT *user_obj; - - if (!user_format->rgodf) return -1; - - user_obj = user_format->rgodf + impl->device_format.dwNumObjs; - while (user_obj-- > user_format->rgodf) - { - if (!user_obj->dwType) continue; - if ((user_obj->dwType & 0x00ffffff) == (id & 0x00ffffff)) return user_obj->dwOfs; - } - - return -1; -} - int dinput_device_object_index_from_id( IDirectInputDevice8W *iface, DWORD id ) { struct dinput_device *impl = impl_from_IDirectInputDevice8W( iface ); @@ -443,50 +429,11 @@ static BOOL load_mapping_settings( struct dinput_device *This, LPDIACTIONFORMATW return mapped > 0; }
-static BOOL set_app_data( struct dinput_device *dev, int offset, UINT_PTR app_data ) -{ - int num_actions = dev->num_actions; - ActionMap *action_map = dev->action_map, *target_map = NULL; - - if (num_actions == 0) - { - num_actions = 1; - action_map = malloc( sizeof(ActionMap) ); - if (!action_map) return FALSE; - target_map = &action_map[0]; - } - else - { - int i; - for (i = 0; i < num_actions; i++) - { - if (dev->action_map[i].offset != offset) continue; - target_map = &dev->action_map[i]; - break; - } - - if (!target_map) - { - num_actions++; - action_map = realloc( action_map, sizeof(ActionMap) * num_actions ); - if (!action_map) return FALSE; - target_map = &action_map[num_actions-1]; - } - } - - target_map->offset = offset; - target_map->uAppData = app_data; - - dev->action_map = action_map; - dev->num_actions = num_actions; - - return TRUE; -} - void queue_event( IDirectInputDevice8W *iface, int index, DWORD data, DWORD time, DWORD seq ) { static ULONGLONG notify_ms = 0; struct dinput_device *This = impl_from_IDirectInputDevice8W( iface ); + struct object_properties *properties = This->object_properties + index; const DIOBJECTDATAFORMAT *user_obj = This->user_format.rgodf + index; ULONGLONG time_ms = GetTickCount64(); int next_pos; @@ -513,22 +460,7 @@ void queue_event( IDirectInputDevice8W *iface, int index, DWORD data, DWORD time This->data_queue[This->queue_head].dwData = data; This->data_queue[This->queue_head].dwTimeStamp = time; This->data_queue[This->queue_head].dwSequence = seq; - This->data_queue[This->queue_head].uAppData = -1; - - /* Set uAppData by means of action mapping */ - if (This->num_actions > 0) - { - int i; - for (i=0; i < This->num_actions; i++) - { - if (This->action_map[i].offset == user_obj->dwOfs) - { - TRACE( "Offset %lu mapped to uAppData %#Ix\n", user_obj->dwOfs, This->action_map[i].uAppData ); - This->data_queue[This->queue_head].uAppData = This->action_map[i].uAppData; - break; - } - } - } + This->data_queue[This->queue_head].uAppData = properties->app_data;
This->queue_head = next_pos; /* Send event if asked */ @@ -604,10 +536,6 @@ static HRESULT WINAPI dinput_device_SetDataFormat( IDirectInputDevice8W *iface,
EnterCriticalSection(&This->crit);
- free( This->action_map ); - This->action_map = NULL; - This->num_actions = 0; - dinput_device_release_user_format( This ); res = dinput_device_init_user_format( This, format );
@@ -707,8 +635,6 @@ void dinput_device_internal_release( struct dinput_device *impl ) free( impl->device_format.rgodf ); dinput_device_release_user_format( impl );
- free( impl->action_map ); - dinput_internal_release( impl->dinput ); impl->crit.DebugInfo->Spare[0] = 0; DeleteCriticalSection( &impl->crit ); @@ -1060,13 +986,6 @@ static HRESULT check_property( struct dinput_device *impl, const GUID *guid, con return DI_OK; }
-static BOOL find_object( struct dinput_device *device, UINT index, struct hid_value_caps *caps, - const DIDEVICEOBJECTINSTANCEW *instance, void *data ) -{ - *(DIDEVICEOBJECTINSTANCEW *)data = *instance; - return DIENUM_STOP; -} - struct get_object_property_params { IDirectInputDevice8W *iface; @@ -1137,6 +1056,12 @@ static BOOL get_object_property( struct dinput_device *device, UINT index, struc lstrcpynW( value->wsz, instance->tszName, ARRAY_SIZE(value->wsz) ); return DIENUM_STOP; } + case (DWORD_PTR)DIPROP_APPDATA: + { + DIPROPPOINTER *value = (DIPROPPOINTER *)params->header; + value->uData = properties->app_data; + return DIENUM_STOP; + } }
return DIENUM_STOP; @@ -1172,6 +1097,7 @@ static HRESULT dinput_device_get_property( IDirectInputDevice8W *iface, const GU case (DWORD_PTR)DIPROP_GRANULARITY: case (DWORD_PTR)DIPROP_KEYNAME: case (DWORD_PTR)DIPROP_CALIBRATIONMODE: + case (DWORD_PTR)DIPROP_APPDATA: hr = impl->vtbl->enum_objects( iface, &filter, object_mask, get_object_property, ¶ms ); if (FAILED(hr)) return hr; if (hr == DIENUM_CONTINUE) return DIERR_NOTFOUND; @@ -1283,6 +1209,12 @@ static BOOL set_object_property( struct dinput_device *device, UINT index, struc properties->calibration_mode = value->dwData; return DIENUM_CONTINUE; } + case (DWORD_PTR)DIPROP_APPDATA: + { + DIPROPPOINTER *value = (DIPROPPOINTER *)params->header; + properties->app_data = value->uData; + return DIENUM_CONTINUE; + } }
return DIENUM_STOP; @@ -1328,8 +1260,6 @@ static HRESULT dinput_device_set_property( IDirectInputDevice8W *iface, const GU { struct set_object_property_params params = {.iface = iface, .header = header, .property = LOWORD( guid )}; struct dinput_device *impl = impl_from_IDirectInputDevice8W( iface ); - DWORD object_mask = DIDFT_AXIS | DIDFT_BUTTON | DIDFT_POV; - DIDEVICEOBJECTINSTANCEW instance; DIPROPHEADER filter; HRESULT hr;
@@ -1401,13 +1331,8 @@ static HRESULT dinput_device_set_property( IDirectInputDevice8W *iface, const GU } case (DWORD_PTR)DIPROP_APPDATA: { - const DIPROPPOINTER *value = (const DIPROPPOINTER *)header; - int user_offset; - hr = impl->vtbl->enum_objects( iface, &filter, object_mask, find_object, &instance ); + hr = impl->vtbl->enum_objects( iface, &filter, DIDFT_ALL, set_object_property, ¶ms ); if (FAILED(hr)) return hr; - if (hr == DIENUM_CONTINUE) return DIERR_OBJECTNOTFOUND; - if ((user_offset = id_to_offset( impl, instance.dwType )) < 0) return DIERR_OBJECTNOTFOUND; - if (!set_app_data( impl, user_offset, value->uData )) return DIERR_OUTOFMEMORY; return DI_OK; } default: @@ -1971,9 +1896,38 @@ static HRESULT WINAPI dinput_device_BuildActionMap( IDirectInputDevice8W *iface, return DI_OK; }
+static BOOL init_object_app_data( struct dinput_device *device, UINT index, struct hid_value_caps *caps, + const DIDEVICEOBJECTINSTANCEW *instance, void *data ) +{ + struct object_properties *properties; + const DIACTIONFORMATW *format = data; + const DIACTIONW *action = format->rgoAction + format->dwNumActions; + + if (index == -1) return DIENUM_STOP; + if (instance->wUsagePage == HID_USAGE_PAGE_PID) return DIENUM_CONTINUE; + + properties = device->object_properties + index; + properties->app_data = 0; + + while (action-- > format->rgoAction) + { + if (action->dwObjID != instance->dwType) continue; + properties->app_data = action->uAppData; + break; + } + + return DIENUM_CONTINUE; +} + static HRESULT WINAPI dinput_device_SetActionMap( IDirectInputDevice8W *iface, DIACTIONFORMATW *format, const WCHAR *username, DWORD flags ) { + static const DIPROPHEADER filter = + { + .dwSize = sizeof(filter), + .dwHeaderSize = sizeof(filter), + .dwHow = DIPH_DEVICE, + }; struct dinput_device *impl = impl_from_IDirectInputDevice8W( iface ); DIDATAFORMAT data_format = { @@ -2010,9 +1964,8 @@ static HRESULT WINAPI dinput_device_SetActionMap( IDirectInputDevice8W *iface, D }; WCHAR username_buf[MAX_PATH]; DWORD username_len = MAX_PATH; - int i, index, action = 0, num_actions = 0; + int i, index, num_actions = 0; unsigned int offset = 0; - ActionMap *action_map; HRESULT hr;
FIXME( "iface %p, format %p, username %s, flags %#lx stub!\n", iface, format, @@ -2027,19 +1980,15 @@ static HRESULT WINAPI dinput_device_SetActionMap( IDirectInputDevice8W *iface, D
if (num_actions == 0) return DI_NOEFFECT;
- data_format.rgodf = malloc( sizeof(DIOBJECTDATAFORMAT) * num_actions ); + if (!(data_format.rgodf = malloc( sizeof(DIOBJECTDATAFORMAT) * num_actions ))) return DIERR_OUTOFMEMORY; data_format.dwDataSize = format->dwDataSize;
- action_map = malloc( sizeof(ActionMap) * num_actions ); - for (i = 0; i < format->dwNumActions; i++, offset += sizeof(ULONG)) { if (format->rgoAction[i].dwFlags & DIA_APPNOMAP) continue; if (!IsEqualGUID( &impl->guid, &format->rgoAction[i].guidInstance )) continue; if ((index = dinput_device_object_index_from_id( iface, format->rgoAction[i].dwObjID )) < 0) continue;
- action_map[action].uAppData = format->rgoAction[i].uAppData; - action_map[action].offset = offset; data_format.rgodf[data_format.dwNumObjs] = impl->device_format.rgodf[index]; data_format.rgodf[data_format.dwNumObjs].dwOfs = offset; data_format.dwNumObjs++; @@ -2051,8 +2000,8 @@ static HRESULT WINAPI dinput_device_SetActionMap( IDirectInputDevice8W *iface, D WARN( "Failed to set data format from action map, hr %#lx\n", hr ); else { - impl->action_map = action_map; - impl->num_actions = num_actions; + if (FAILED(impl->vtbl->enum_objects( iface, &filter, DIDFT_ALL, init_object_app_data, format ))) + WARN( "Failed to initialize action map app data\n" );
if (format->lAxisMin != format->lAxisMax) { @@ -2076,7 +2025,6 @@ static HRESULT WINAPI dinput_device_SetActionMap( IDirectInputDevice8W *iface, D
LeaveCriticalSection( &impl->crit );
- if (FAILED(hr)) free( action_map ); free( data_format.rgodf ); return hr; } @@ -2196,6 +2144,7 @@ static BOOL enum_objects_init( struct dinput_device *impl, UINT index, struct hi .range_min = DIPROPRANGE_NOMIN, .range_max = DIPROPRANGE_NOMAX, .granularity = 1, + .app_data = -1, }; DIDATAFORMAT *format = &impl->device_format; DIOBJECTDATAFORMAT *object_format; diff --git a/dlls/dinput/device_private.h b/dlls/dinput/device_private.h index 65453f6313d..5563618ff12 100644 --- a/dlls/dinput/device_private.h +++ b/dlls/dinput/device_private.h @@ -28,12 +28,6 @@ #include "wine/list.h" #include "dinput_private.h"
-typedef struct -{ - unsigned int offset; - UINT_PTR uAppData; -} ActionMap; - struct dinput_device; struct hid_value_caps;
@@ -72,6 +66,7 @@ struct object_properties LONG range_max; LONG deadzone; LONG saturation; + UINT_PTR app_data; DWORD calibration_mode; DWORD granularity; }; @@ -113,10 +108,6 @@ struct dinput_device DIDATAFORMAT device_format; DIDATAFORMAT user_format;
- /* Action mapping */ - int num_actions; /* number of actions mapped */ - ActionMap *action_map; /* array of mappings */ - /* internal device callbacks */ HANDLE read_event; const struct dinput_device_vtbl *vtbl; diff --git a/dlls/dinput/tests/joystick8.c b/dlls/dinput/tests/joystick8.c index 8561c4f2848..c3866e4e177 100644 --- a/dlls/dinput/tests/joystick8.c +++ b/dlls/dinput/tests/joystick8.c @@ -917,7 +917,6 @@ static void test_action_map( IDirectInputDevice8W *device, HANDLE file, HANDLE e 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, "GetProperty returned %#lx\n", hr ); ok( prop_pointer.uData == 0, "got uData %#Ix\n", prop_pointer.uData );
@@ -965,23 +964,18 @@ static void test_action_map( IDirectInputDevice8W *device, HANDLE file, HANDLE e prop_pointer.diph.dwHow = DIPH_BYID; prop_pointer.diph.dwObj = DIDFT_ABSAXIS | DIDFT_MAKEINSTANCE( 3 ); hr = IDirectInputDevice8_GetProperty( device, DIPROP_APPDATA, &prop_pointer.diph ); - todo_wine ok( hr == DIERR_NOTFOUND, "GetProperty returned %#lx\n", hr );
prop_pointer.diph.dwHow = DIPH_BYID; prop_pointer.diph.dwObj = DIDFT_ABSAXIS | DIDFT_MAKEINSTANCE( 2 ); hr = IDirectInputDevice8_GetProperty( device, DIPROP_APPDATA, &prop_pointer.diph ); - todo_wine ok( hr == DI_OK, "GetProperty returned %#lx\n", hr ); - todo_wine ok( prop_pointer.uData == 6, "got uData %#Ix\n", prop_pointer.uData );
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, "GetProperty returned %#lx\n", hr ); - todo_wine ok( prop_pointer.uData == 8, "got uData %#Ix\n", prop_pointer.uData );
prop_range.diph.dwHow = DIPH_BYID; @@ -1078,7 +1072,6 @@ static void test_action_map( IDirectInputDevice8W *device, HANDLE file, HANDLE e ok( objdata[res].dwData == expect_objdata[res].dwData || broken(objdata[res].dwData == -45 && expect_objdata[res].dwData == -43) /* 32-bit rounding */, "got dwData %+ld\n", objdata[res].dwData ); - todo_wine_if( res != 0 && res != 3 && res != 6 ) check_member( objdata[res], expect_objdata[res], "%#Ix", uAppData ); winetest_pop_context(); } @@ -1095,9 +1088,7 @@ static void test_action_map( IDirectInputDevice8W *device, HANDLE file, HANDLE e 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, "GetProperty returned %#lx\n", hr ); - todo_wine ok( prop_pointer.uData == 8, "got uData %#Ix\n", prop_pointer.uData );
hr = IDirectInputDevice8_SetDataFormat( device, &c_dfDIJoystick2 ); @@ -1106,9 +1097,7 @@ static void test_action_map( IDirectInputDevice8W *device, HANDLE file, HANDLE e 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, "GetProperty returned %#lx\n", hr ); - todo_wine ok( prop_pointer.uData == -1, "got uData %#Ix\n", prop_pointer.uData );
prop_range.diph.dwHow = DIPH_BYID; @@ -2705,7 +2694,6 @@ static void test_simple_joystick( DWORD version ) 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_if( version >= 0x0800 ) ok( hr == (version < 0x0800 ? DIERR_UNSUPPORTED : DI_OK), "GetProperty DIPROP_APPDATA returned %#lx\n", hr ); if (hr == DI_OK) ok( prop_pointer.uData == 0xfeedcafe, "got %p\n", (void *)prop_pointer.uData );
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/dinput/device.c | 14 +++++--------- dlls/dinput/tests/joystick8.c | 4 ---- 2 files changed, 5 insertions(+), 13 deletions(-)
diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c index 16c4409b9b3..2817ca9839b 100644 --- a/dlls/dinput/device.c +++ b/dlls/dinput/device.c @@ -1964,8 +1964,8 @@ static HRESULT WINAPI dinput_device_SetActionMap( IDirectInputDevice8W *iface, D }; WCHAR username_buf[MAX_PATH]; DWORD username_len = MAX_PATH; - int i, index, num_actions = 0; unsigned int offset = 0; + int i, index; HRESULT hr;
FIXME( "iface %p, format %p, username %s, flags %#lx stub!\n", iface, format, @@ -1973,14 +1973,7 @@ static HRESULT WINAPI dinput_device_SetActionMap( IDirectInputDevice8W *iface, D
if (!format) return DIERR_INVALIDPARAM;
- /* Count the actions */ - for (i = 0; i < format->dwNumActions; i++) - if (IsEqualGUID( &impl->guid, &format->rgoAction[i].guidInstance )) - num_actions++; - - if (num_actions == 0) return DI_NOEFFECT; - - if (!(data_format.rgodf = malloc( sizeof(DIOBJECTDATAFORMAT) * num_actions ))) return DIERR_OUTOFMEMORY; + if (!(data_format.rgodf = malloc( sizeof(DIOBJECTDATAFORMAT) * format->dwNumActions ))) return DIERR_OUTOFMEMORY; data_format.dwDataSize = format->dwDataSize;
for (i = 0; i < format->dwNumActions; i++, offset += sizeof(ULONG)) @@ -2026,6 +2019,9 @@ static HRESULT WINAPI dinput_device_SetActionMap( IDirectInputDevice8W *iface, D LeaveCriticalSection( &impl->crit );
free( data_format.rgodf ); + + if (FAILED(hr)) return hr; + if (!data_format.dwNumObjs) return DI_NOEFFECT; return hr; }
diff --git a/dlls/dinput/tests/joystick8.c b/dlls/dinput/tests/joystick8.c index c3866e4e177..6e8a9292f84 100644 --- a/dlls/dinput/tests/joystick8.c +++ b/dlls/dinput/tests/joystick8.c @@ -824,9 +824,7 @@ static void test_action_map( IDirectInputDevice8W *device, HANDLE file, HANDLE e
memset( prop_username.wsz, 0, sizeof(prop_username.wsz) ); hr = IDirectInputDevice_GetProperty( device, DIPROP_USERNAME, &prop_username.diph ); - todo_wine ok( hr == DI_OK, "GetProperty returned %#lx\n", hr ); - todo_wine ok( !wcscmp( prop_username.wsz, username ), "got username %s\n", debugstr_w(prop_username.wsz) );
hr = IDirectInputDevice8_SetActionMap( device, &voice_action_format, NULL, DIDSAM_DEFAULT ); @@ -837,9 +835,7 @@ static void test_action_map( IDirectInputDevice8W *device, HANDLE file, HANDLE e
memset( prop_username.wsz, 0, sizeof(prop_username.wsz) ); hr = IDirectInputDevice_GetProperty( device, DIPROP_USERNAME, &prop_username.diph ); - todo_wine ok( hr == DI_OK, "GetProperty returned %#lx\n", hr ); - todo_wine ok( !wcscmp( prop_username.wsz, username ), "got username %s\n", debugstr_w(prop_username.wsz) );
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/dinput/device.c | 1 + dlls/dinput/tests/joystick8.c | 1 - 2 files changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c index 2817ca9839b..0df0199317b 100644 --- a/dlls/dinput/device.c +++ b/dlls/dinput/device.c @@ -1972,6 +1972,7 @@ static HRESULT WINAPI dinput_device_SetActionMap( IDirectInputDevice8W *iface, D debugstr_w(username), flags );
if (!format) return DIERR_INVALIDPARAM; + if (flags != DIDSAM_DEFAULT && flags != DIDSAM_FORCESAVE && flags != DIDSAM_NOUSER) return DIERR_INVALIDPARAM;
if (!(data_format.rgodf = malloc( sizeof(DIOBJECTDATAFORMAT) * format->dwNumActions ))) return DIERR_OUTOFMEMORY; data_format.dwDataSize = format->dwDataSize; diff --git a/dlls/dinput/tests/joystick8.c b/dlls/dinput/tests/joystick8.c index 6e8a9292f84..7947e6e33cc 100644 --- a/dlls/dinput/tests/joystick8.c +++ b/dlls/dinput/tests/joystick8.c @@ -807,7 +807,6 @@ static void test_action_map( IDirectInputDevice8W *device, HANDLE file, HANDLE e ok( hr == DIERR_INVALIDPARAM, "SetActionMap returned %#lx\n", hr ); flags = DIDSAM_FORCESAVE | DIDSAM_NOUSER; hr = IDirectInputDevice8_SetActionMap( device, &action_format_1, NULL, flags ); - todo_wine ok( hr == DIERR_INVALIDPARAM, "SetActionMap returned %#lx\n", hr );
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/dinput/device.c | 1 + dlls/dinput/tests/joystick8.c | 5 ----- 2 files changed, 1 insertion(+), 5 deletions(-)
diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c index 0df0199317b..41baa630989 100644 --- a/dlls/dinput/device.c +++ b/dlls/dinput/device.c @@ -2022,6 +2022,7 @@ static HRESULT WINAPI dinput_device_SetActionMap( IDirectInputDevice8W *iface, D free( data_format.rgodf );
if (FAILED(hr)) return hr; + if (flags == DIDSAM_FORCESAVE) return DI_SETTINGSNOTSAVED; if (!data_format.dwNumObjs) return DI_NOEFFECT; return hr; } diff --git a/dlls/dinput/tests/joystick8.c b/dlls/dinput/tests/joystick8.c index 7947e6e33cc..a74dab6dc52 100644 --- a/dlls/dinput/tests/joystick8.c +++ b/dlls/dinput/tests/joystick8.c @@ -818,7 +818,6 @@ static void test_action_map( IDirectInputDevice8W *device, HANDLE file, HANDLE e /* first SetActionMap call for a user always return DI_SETTINGSNOTSAVED */
hr = IDirectInputDevice8_SetActionMap( device, &voice_action_format, NULL, DIDSAM_FORCESAVE ); - todo_wine ok( hr == DI_SETTINGSNOTSAVED, "SetActionMap returned %#lx\n", hr );
memset( prop_username.wsz, 0, sizeof(prop_username.wsz) ); @@ -829,7 +828,6 @@ static void test_action_map( IDirectInputDevice8W *device, HANDLE file, HANDLE e hr = IDirectInputDevice8_SetActionMap( device, &voice_action_format, NULL, DIDSAM_DEFAULT ); ok( hr == DI_NOEFFECT, "SetActionMap returned %#lx\n", hr ); hr = IDirectInputDevice8_SetActionMap( device, &voice_action_format, NULL, DIDSAM_FORCESAVE ); - todo_wine ok( hr == DI_SETTINGSNOTSAVED, "SetActionMap returned %#lx\n", hr );
memset( prop_username.wsz, 0, sizeof(prop_username.wsz) ); @@ -874,10 +872,8 @@ static void test_action_map( IDirectInputDevice8W *device, HANDLE file, HANDLE e /* DIDSAM_FORCESAVE always returns DI_SETTINGSNOTSAVED */
hr = IDirectInputDevice8_SetActionMap( device, &action_format, L"username", DIDSAM_FORCESAVE ); - todo_wine ok( hr == DI_SETTINGSNOTSAVED, "SetActionMap returned %#lx\n", hr ); hr = IDirectInputDevice8_SetActionMap( device, &action_format, L"username", DIDSAM_FORCESAVE ); - todo_wine ok( hr == DI_SETTINGSNOTSAVED, "SetActionMap returned %#lx\n", hr ); check_diactionformatw( &action_format, &expect_action_format_1 );
@@ -946,7 +942,6 @@ static void test_action_map( IDirectInputDevice8W *device, HANDLE file, HANDLE e ok( hr == DI_OK, "SetActionMap returned %#lx\n", hr ); check_diactionformatw( &action_format, &expect_action_format_2_filled ); hr = IDirectInputDevice8_SetActionMap( device, &action_format, L"username", DIDSAM_FORCESAVE ); - todo_wine ok( hr == DI_SETTINGSNOTSAVED, "SetActionMap returned %#lx\n", hr ); check_diactionformatw( &action_format, &expect_action_format_2_filled );