From 83aded2754c86a31edc4498c2060580706b52a4c Mon Sep 17 00:00:00 2001 From: Lucas Fialho Zawacki Date: Sat, 2 Jul 2011 01:06:37 -0300 Subject: [PATCH] dinput: Keyboard and mouse implementation of BuildActionMap. --- dlls/dinput/device.c | 32 ++++++++++++++++++-- dlls/dinput/device_private.h | 2 ++ dlls/dinput/keyboard.c | 58 ++++++++++++++++++++++++++++++++++-- dlls/dinput/mouse.c | 55 ++++++++++++++++++++++++++++++++-- dlls/dinput8/tests/device.c | 10 +++---- 5 files changed, 146 insertions(+), 11 deletions(-) diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c index 5a03a27730a..b66c9470c25 100644 --- a/dlls/dinput/device.c +++ b/dlls/dinput/device.c @@ -547,6 +547,34 @@ int find_property(const DataFormat *df, LPCDIPROPHEADER ph) return -1; } +DWORD semantic_to_obj_id(IDirectInputDeviceImpl* This, DWORD dwSemantic) +{ + DWORD type = (0x0000ff00 & dwSemantic) >> 8; + DWORD offset = 0x000000ff & dwSemantic; + DWORD obj_instance = 0; + DWORD found = 0; + int i; + + for (i = 0; i < This->data_format.wine_df->dwNumObjs; i++) + { + LPDIOBJECTDATAFORMAT odf = dataformat_to_odf(This->data_format.wine_df, i); + + if (odf->dwOfs == offset) + { + obj_instance = DIDFT_GETINSTANCE(odf->dwType); + found = 1; + break; + } + } + + if (!found) return 0; + + if (type & DIDFT_AXIS) type = DIDFT_RELAXIS; + if (type & DIDFT_BUTTON) type = DIDFT_PSHBUTTON; + + return type | (0x0000ff00 & (obj_instance << 8)); +} + /****************************************************************************** * queue_event - add new event to the ring queue */ @@ -1359,7 +1387,7 @@ HRESULT WINAPI IDirectInputDevice8AImpl_BuildActionMap(LPDIRECTINPUTDEVICE8A ifa LPCSTR lpszUserName, DWORD dwFlags) { - FIXME("(%p)->(%p,%s,%08x): stub !\n", iface, lpdiaf, lpszUserName, dwFlags); + FIXME("(%p)->(%p,%s,%08x): semi-stub !\n", iface, lpdiaf, lpszUserName, dwFlags); #define X(x) if (dwFlags & x) FIXME("\tdwFlags =|"#x"\n"); X(DIDBAM_DEFAULT) X(DIDBAM_PRESERVE) @@ -1375,7 +1403,7 @@ HRESULT WINAPI IDirectInputDevice8WImpl_BuildActionMap(LPDIRECTINPUTDEVICE8W ifa LPCWSTR lpszUserName, DWORD dwFlags) { - FIXME("(%p)->(%p,%s,%08x): stub !\n", iface, lpdiaf, debugstr_w(lpszUserName), dwFlags); + FIXME("(%p)->(%p,%s,%08x): semi-stub !\n", iface, lpdiaf, debugstr_w(lpszUserName), dwFlags); #define X(x) if (dwFlags & x) FIXME("\tdwFlags =|"#x"\n"); X(DIDBAM_DEFAULT) X(DIDBAM_PRESERVE) diff --git a/dlls/dinput/device_private.h b/dlls/dinput/device_private.h index f254d7f1d53..a5f7f83c64d 100644 --- a/dlls/dinput/device_private.h +++ b/dlls/dinput/device_private.h @@ -114,6 +114,8 @@ extern void _dump_OBJECTINSTANCEW(const DIDEVICEOBJECTINSTANCEW *ddoi) DECLSPEC extern void _dump_DIDATAFORMAT(const DIDATAFORMAT *df) DECLSPEC_HIDDEN; extern const char *_dump_dinput_GUID(const GUID *guid) DECLSPEC_HIDDEN; +extern DWORD semantic_to_obj_id(IDirectInputDeviceImpl* This, DWORD dwSemantic) DECLSPEC_HIDDEN; + /* And the stubs */ extern HRESULT WINAPI IDirectInputDevice2AImpl_Acquire(LPDIRECTINPUTDEVICE8A iface) DECLSPEC_HIDDEN; extern HRESULT WINAPI IDirectInputDevice2WImpl_Acquire(LPDIRECTINPUTDEVICE8W iface) DECLSPEC_HIDDEN; diff --git a/dlls/dinput/keyboard.c b/dlls/dinput/keyboard.c index c697cfd9d95..d54f80c3f66 100644 --- a/dlls/dinput/keyboard.c +++ b/dlls/dinput/keyboard.c @@ -524,6 +524,60 @@ static HRESULT WINAPI SysKeyboardAImpl_GetProperty(LPDIRECTINPUTDEVICE8A iface, return SysKeyboardWImpl_GetProperty(IDirectInputDevice8W_from_impl(This), rguid, pdiph); } +static HRESULT WINAPI SysKeyboardWImpl_BuildActionMap(LPDIRECTINPUTDEVICE8W iface, + LPDIACTIONFORMATW lpdiaf, + LPCWSTR lpszUserName, + DWORD dwFlags) +{ + SysKeyboardImpl *This = impl_from_IDirectInputDevice8W(iface); + int i, has_actions = 0; + + FIXME("(%p)->(%p,%s,%08x): semi-stub !\n", iface, lpdiaf, debugstr_w(lpszUserName), dwFlags); + + for (i=0; i < lpdiaf->dwNumActions; i++) + { + if ((lpdiaf->rgoAction[i].dwSemantic & DIKEYBOARD_MASK) == DIKEYBOARD_MASK) + { + DWORD obj_id = semantic_to_obj_id(&This->base, lpdiaf->rgoAction[i].dwSemantic); + + lpdiaf->rgoAction[i].dwObjID = obj_id; + lpdiaf->rgoAction[i].guidInstance = This->base.guid; + lpdiaf->rgoAction[i].dwHow = DIAH_DEFAULT; + has_actions = 1; + } + else if (!(dwFlags & DIDBAM_PRESERVE)) + { + /* we must clear action data belonging to other devices */ + memset(&lpdiaf->rgoAction[i].guidInstance, 0, sizeof(GUID)); + lpdiaf->rgoAction[i].dwHow = DIAH_UNMAPPED; + } + } + + if (!has_actions) return DI_NOEFFECT; + + return IDirectInputDevice8WImpl_BuildActionMap(iface, lpdiaf, lpszUserName, dwFlags); +} + +static HRESULT WINAPI SysKeyboardAImpl_BuildActionMap(LPDIRECTINPUTDEVICE8A iface, + LPDIACTIONFORMATA lpdiaf, + LPCSTR lpszUserName, + DWORD dwFlags) +{ + SysKeyboardImpl *This = impl_from_IDirectInputDevice8A(iface); + DIACTIONFORMATW diafW; + HRESULT hr; + + diafW.rgoAction = HeapAlloc(GetProcessHeap(), 0, sizeof(DIACTIONW)*lpdiaf->dwNumActions); + _copy_diactionformatAtoW(&diafW, lpdiaf); + + hr = SysKeyboardWImpl_BuildActionMap(&This->base.IDirectInputDevice8W_iface, &diafW, NULL, dwFlags); + + _copy_diactionformatWtoA(lpdiaf, &diafW); + HeapFree(GetProcessHeap(), 0, diafW.rgoAction); + + return hr; +} + static const IDirectInputDevice8AVtbl SysKeyboardAvt = { IDirectInputDevice2AImpl_QueryInterface, @@ -555,7 +609,7 @@ static const IDirectInputDevice8AVtbl SysKeyboardAvt = IDirectInputDevice2AImpl_SendDeviceData, IDirectInputDevice7AImpl_EnumEffectsInFile, IDirectInputDevice7AImpl_WriteEffectToFile, - IDirectInputDevice8AImpl_BuildActionMap, + SysKeyboardAImpl_BuildActionMap, IDirectInputDevice8AImpl_SetActionMap, IDirectInputDevice8AImpl_GetImageInfo }; @@ -591,7 +645,7 @@ static const IDirectInputDevice8WVtbl SysKeyboardWvt = IDirectInputDevice2WImpl_SendDeviceData, IDirectInputDevice7WImpl_EnumEffectsInFile, IDirectInputDevice7WImpl_WriteEffectToFile, - IDirectInputDevice8WImpl_BuildActionMap, + SysKeyboardWImpl_BuildActionMap, IDirectInputDevice8WImpl_SetActionMap, IDirectInputDevice8WImpl_GetImageInfo }; diff --git a/dlls/dinput/mouse.c b/dlls/dinput/mouse.c index 02813ff1863..ff53a7e8ee3 100644 --- a/dlls/dinput/mouse.c +++ b/dlls/dinput/mouse.c @@ -773,6 +773,57 @@ static HRESULT WINAPI SysMouseWImpl_GetDeviceInfo(LPDIRECTINPUTDEVICE8W iface, L return DI_OK; } +static HRESULT WINAPI SysMouseWImpl_BuildActionMap(LPDIRECTINPUTDEVICE8W iface, + LPDIACTIONFORMATW lpdiaf, + LPCWSTR lpszUserName, + DWORD dwFlags) +{ + SysMouseImpl *This = impl_from_IDirectInputDevice8W(iface); + int i, has_actions = 0; + + for (i=0; i < lpdiaf->dwNumActions; i++) + { + if ((lpdiaf->rgoAction[i].dwSemantic & DIMOUSE_MASK) == DIMOUSE_MASK) + { + DWORD obj_id = semantic_to_obj_id(&This->base, lpdiaf->rgoAction[i].dwSemantic); + + lpdiaf->rgoAction[i].dwObjID = obj_id; + lpdiaf->rgoAction[i].guidInstance = This->base.guid; + lpdiaf->rgoAction[i].dwHow = DIAH_DEFAULT; + has_actions = 1; + } + else if (!(dwFlags & DIDBAM_PRESERVE)) + { + /* we must clear action data belonging to other devices */ + memset(&lpdiaf->rgoAction[i].guidInstance, 0, sizeof(GUID)); + lpdiaf->rgoAction[i].dwHow = DIAH_UNMAPPED; + } + } + + if (!has_actions) return DI_NOEFFECT; + + return IDirectInputDevice8WImpl_BuildActionMap(iface, lpdiaf, lpszUserName, dwFlags); +} + +static HRESULT WINAPI SysMouseAImpl_BuildActionMap(LPDIRECTINPUTDEVICE8A iface, + LPDIACTIONFORMATA lpdiaf, + LPCSTR lpszUserName, + DWORD dwFlags) +{ + SysMouseImpl *This = impl_from_IDirectInputDevice8A(iface); + DIACTIONFORMATW diafW; + HRESULT hr; + + diafW.rgoAction = HeapAlloc(GetProcessHeap(), 0, sizeof(DIACTIONW)*lpdiaf->dwNumActions); + _copy_diactionformatAtoW(&diafW, lpdiaf); + + hr = SysMouseWImpl_BuildActionMap(&This->base.IDirectInputDevice8W_iface, &diafW, NULL, dwFlags); + + _copy_diactionformatWtoA(lpdiaf, &diafW); + HeapFree(GetProcessHeap(), 0, diafW.rgoAction); + + return hr; +} static const IDirectInputDevice8AVtbl SysMouseAvt = { @@ -805,7 +856,7 @@ static const IDirectInputDevice8AVtbl SysMouseAvt = IDirectInputDevice2AImpl_SendDeviceData, IDirectInputDevice7AImpl_EnumEffectsInFile, IDirectInputDevice7AImpl_WriteEffectToFile, - IDirectInputDevice8AImpl_BuildActionMap, + SysMouseAImpl_BuildActionMap, IDirectInputDevice8AImpl_SetActionMap, IDirectInputDevice8AImpl_GetImageInfo }; @@ -841,7 +892,7 @@ static const IDirectInputDevice8WVtbl SysMouseWvt = IDirectInputDevice2WImpl_SendDeviceData, IDirectInputDevice7WImpl_EnumEffectsInFile, IDirectInputDevice7WImpl_WriteEffectToFile, - IDirectInputDevice8WImpl_BuildActionMap, + SysMouseWImpl_BuildActionMap, IDirectInputDevice8WImpl_SetActionMap, IDirectInputDevice8WImpl_GetImageInfo }; diff --git a/dlls/dinput8/tests/device.c b/dlls/dinput8/tests/device.c index f351fb4c11d..445e11dba0c 100644 --- a/dlls/dinput8/tests/device.c +++ b/dlls/dinput8/tests/device.c @@ -118,10 +118,10 @@ static void test_build_action_map( how = actions[action_index].dwHow; assigned_to = actions[action_index].guidInstance; - todo_wine ok (how == DIAH_USERCONFIG || how == DIAH_DEFAULT, "Action was not set dwHow=%08x\n", how); - todo_wine ok (instance == expected_inst, "Action not mapped correctly instance=%08x expected=%08x\n", instance, expected_inst); - todo_wine ok (type == expected_type, "Action type not mapped correctly type=%08x expected=%08x\n", type, expected_type); - todo_wine ok (IsEqualGUID(&assigned_to, &ddi.guidInstance), "Action and device GUID do not match action=%d\n", action_index); + ok (how == DIAH_USERCONFIG || how == DIAH_DEFAULT, "Action was not set dwHow=%08x\n", how); + ok (instance == expected_inst, "Action not mapped correctly instance=%08x expected=%08x\n", instance, expected_inst); + ok (type == expected_type, "Action type not mapped correctly type=%08x expected=%08x\n", type, expected_type); + ok (IsEqualGUID(&assigned_to, &ddi.guidInstance), "Action and device GUID do not match action=%d\n", action_index); } static BOOL CALLBACK enumeration_callback( @@ -246,7 +246,7 @@ static void test_action_mapping(void) af.dwNumActions = DITEST_KEYBOARDSPACE; hr = IDirectInputDevice8_BuildActionMap(data.keyboard, data.lpdiaf, NULL, DIDBAM_INITIALIZE); - todo_wine ok (hr == DI_NOEFFECT, "BuildActionMap should have no effect with no actions hr=%08x\n", hr); + ok (hr == DI_NOEFFECT, "BuildActionMap should have no effect with no actions hr=%08x\n", hr); hr = IDirectInputDevice8_SetActionMap(data.keyboard, data.lpdiaf, NULL, 0); todo_wine ok (hr == DI_NOEFFECT, "SetActionMap should have no effect with no actions to map hr=%08x\n", hr);