[2/4] dinput: Keyboard and mouse implementation of BuildActionMap (try 4)

Lucas Fialho Zawacki lfzawacki at gmail.com
Fri Jul 1 23:06:37 CDT 2011


Now with an actual mouse implementation and some common code factored out.
---
 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 5a03a27..b66c947 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 f254d7f..a5f7f83 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 c697cfd..2d07f74 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);
 }
 
+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);
+}
+
+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 02813ff..89c7597 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;
 }
 
+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);
+}
+
+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 f351fb4..445e11d 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);
-- 
1.7.0.4



More information about the wine-patches mailing list