[3/4] dinput: SetActionMap constructing a dataformat for keyboard and mouse (try 4)

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


---
 dlls/dinput/device.c         |    3 --
 dlls/dinput/device_private.h |    3 ++
 dlls/dinput/keyboard.c       |   73 ++++++++++++++++++++++++++++++++++++++-
 dlls/dinput/mouse.c          |   77 ++++++++++++++++++++++++++++++++++++++++-
 dlls/dinput8/tests/device.c  |    8 ++--
 5 files changed, 153 insertions(+), 11 deletions(-)

diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c
index b66c947..16326b4 100644
--- a/dlls/dinput/device.c
+++ b/dlls/dinput/device.c
@@ -1440,13 +1440,10 @@ HRESULT WINAPI IDirectInputDevice8WImpl_SetActionMap(LPDIRECTINPUTDEVICE8W iface
 						     LPCWSTR lpszUserName,
 						     DWORD dwFlags)
 {
-    IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface);
     DIPROPDWORD dp;
 
     FIXME("(%p)->(%p,%s,%08x): semi-stub !\n", iface, lpdiaf, debugstr_w(lpszUserName), dwFlags);
 
-    if (This->acquired) return DIERR_ACQUIRED;
-
     if (lpdiaf->dwBufferSize > 0)
     {
         dp.diph.dwSize = sizeof(DIPROPDWORD);
diff --git a/dlls/dinput/device_private.h b/dlls/dinput/device_private.h
index a5f7f83..1bbc281 100644
--- a/dlls/dinput/device_private.h
+++ b/dlls/dinput/device_private.h
@@ -71,6 +71,9 @@ struct IDirectInputDeviceImpl
     BOOL                        overflow;    /* return DI_BUFFEROVERFLOW in 'GetDeviceData' */
 
     DataFormat                  data_format; /* user data format and wine to user format converter */
+
+    /* Action mapping */
+    int                         num_actions; /* number of actions mapped */
 };
 
 extern BOOL get_app_key(HKEY*, HKEY*) DECLSPEC_HIDDEN;
diff --git a/dlls/dinput/keyboard.c b/dlls/dinput/keyboard.c
index 2d07f74..6ef49fe 100644
--- a/dlls/dinput/keyboard.c
+++ b/dlls/dinput/keyboard.c
@@ -578,6 +578,75 @@ HRESULT WINAPI SysKeyboardAImpl_BuildActionMap(LPDIRECTINPUTDEVICE8A iface,
     return hr;
 }
 
+HRESULT WINAPI SysKeyboardWImpl_SetActionMap(LPDIRECTINPUTDEVICE8W iface,
+                                             LPDIACTIONFORMATW lpdiaf,
+                                             LPCWSTR lpszUserName,
+                                             DWORD dwFlags)
+{
+    SysKeyboardImpl *This = impl_from_IDirectInputDevice8W(iface);
+    DIDATAFORMAT data_format;
+    DIOBJECTDATAFORMAT *obj_df = NULL;
+    int i, action = 0, num_actions = 0;
+
+    if (This->base.acquired) return DIERR_ACQUIRED;
+
+    data_format.dwSize = sizeof(data_format);
+    data_format.dwObjSize = sizeof(DIOBJECTDATAFORMAT);
+    data_format.dwFlags = DIDF_ABSAXIS;
+    data_format.dwDataSize = lpdiaf->dwDataSize;
+
+    /* count the actions */
+    for (i=0; i < lpdiaf->dwNumActions; i++)
+        if (IsEqualGUID(&This->base.guid, &lpdiaf->rgoAction[i].guidInstance))
+            num_actions++;
+
+    if (num_actions == 0) return DI_NOEFFECT;
+
+    This->base.num_actions = num_actions;
+
+    /* Construct the dataformat and actionmap */
+    obj_df = HeapAlloc(GetProcessHeap(), 0, sizeof(DIOBJECTDATAFORMAT)*num_actions);
+    data_format.rgodf = (LPDIOBJECTDATAFORMAT)obj_df;
+    data_format.dwNumObjs = num_actions;
+
+    for (i = 0; i < lpdiaf->dwNumActions; i++)
+    {
+        if (IsEqualGUID(&This->base.guid, &lpdiaf->rgoAction[i].guidInstance))
+        {
+            int instance = DIDFT_GETINSTANCE(lpdiaf->rgoAction[i].dwObjID);
+            memcpy(&obj_df[action], &c_dfDIKeyboard.rgodf[instance], c_dfDIKeyboard.dwObjSize);
+
+            obj_df[action].dwOfs = action;
+            action++;
+        }
+    }
+
+    IDirectInputDevice8_SetDataFormat(iface, &data_format);
+
+    HeapFree(GetProcessHeap(), 0, obj_df);
+
+    return IDirectInputDevice8WImpl_SetActionMap(iface, lpdiaf, lpszUserName, dwFlags);
+}
+
+HRESULT WINAPI SysKeyboardAImpl_SetActionMap(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_SetActionMap(&This->base.IDirectInputDevice8W_iface, &diafW, NULL, dwFlags);
+
+    HeapFree(GetProcessHeap(), 0, diafW.rgoAction);
+
+    return hr;
+}
+
 static const IDirectInputDevice8AVtbl SysKeyboardAvt =
 {
     IDirectInputDevice2AImpl_QueryInterface,
@@ -610,7 +679,7 @@ static const IDirectInputDevice8AVtbl SysKeyboardAvt =
     IDirectInputDevice7AImpl_EnumEffectsInFile,
     IDirectInputDevice7AImpl_WriteEffectToFile,
     SysKeyboardAImpl_BuildActionMap,
-    IDirectInputDevice8AImpl_SetActionMap,
+    SysKeyboardAImpl_SetActionMap,
     IDirectInputDevice8AImpl_GetImageInfo
 };
 
@@ -646,6 +715,6 @@ static const IDirectInputDevice8WVtbl SysKeyboardWvt =
     IDirectInputDevice7WImpl_EnumEffectsInFile,
     IDirectInputDevice7WImpl_WriteEffectToFile,
     SysKeyboardWImpl_BuildActionMap,
-    IDirectInputDevice8WImpl_SetActionMap,
+    SysKeyboardWImpl_SetActionMap,
     IDirectInputDevice8WImpl_GetImageInfo
 };
diff --git a/dlls/dinput/mouse.c b/dlls/dinput/mouse.c
index 89c7597..dd0cf29 100644
--- a/dlls/dinput/mouse.c
+++ b/dlls/dinput/mouse.c
@@ -825,6 +825,79 @@ HRESULT WINAPI SysMouseAImpl_BuildActionMap(LPDIRECTINPUTDEVICE8A iface,
     return hr;
 }
 
+HRESULT WINAPI SysMouseWImpl_SetActionMap(LPDIRECTINPUTDEVICE8W iface,
+                                          LPDIACTIONFORMATW lpdiaf,
+                                          LPCWSTR lpszUserName,
+                                          DWORD dwFlags)
+{
+    SysMouseImpl *This = impl_from_IDirectInputDevice8W(iface);
+    DIDATAFORMAT data_format;
+    DIOBJECTDATAFORMAT *obj_df = NULL;
+    int i, action = 0, num_actions = 0;
+
+    if (This->base.acquired) return DIERR_ACQUIRED;
+
+    /* count the actions */
+    for (i=0; i < lpdiaf->dwNumActions; i++)
+        if (IsEqualGUID(&This->base.guid, &lpdiaf->rgoAction[i].guidInstance))
+            num_actions++;
+
+    if (num_actions == 0) return DI_NOEFFECT;
+
+    data_format.dwSize = sizeof(data_format);
+    data_format.dwObjSize = sizeof(DIOBJECTDATAFORMAT);
+    data_format.dwFlags = DIDF_ABSAXIS;
+    data_format.dwDataSize = lpdiaf->dwDataSize;
+
+    This->base.num_actions = num_actions;
+
+    /* Constructing the dataformat and actionmap */
+    obj_df = HeapAlloc(GetProcessHeap(), 0, sizeof(DIOBJECTDATAFORMAT)*num_actions);
+    data_format.rgodf = (LPDIOBJECTDATAFORMAT)obj_df;
+    data_format.dwNumObjs = num_actions;
+
+    for (i = 0; i < lpdiaf->dwNumActions; i++)
+    {
+        unsigned int offset = 0;
+
+        if (IsEqualGUID(&This->base.guid, &lpdiaf->rgoAction[i].guidInstance))
+        {
+            int instance = DIDFT_GETINSTANCE(lpdiaf->rgoAction[i].dwObjID);
+            memcpy(&obj_df[action], &c_dfDIMouse.rgodf[instance], c_dfDIMouse.dwObjSize);
+
+            obj_df[action].dwOfs = offset;
+            offset += (obj_df[action].dwType & DIDFT_BUTTON) ? 1 : 4;
+
+            action++;
+        }
+    }
+
+    IDirectInputDevice8_SetDataFormat(iface, &data_format);
+
+    HeapFree(GetProcessHeap(), 0, obj_df);
+
+    return IDirectInputDevice8WImpl_SetActionMap(iface, lpdiaf, lpszUserName, dwFlags);
+}
+
+HRESULT WINAPI SysMouseAImpl_SetActionMap(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_SetActionMap(&This->base.IDirectInputDevice8W_iface, &diafW, NULL, dwFlags);
+
+    HeapFree(GetProcessHeap(), 0, diafW.rgoAction);
+
+    return hr;
+}
+
 static const IDirectInputDevice8AVtbl SysMouseAvt =
 {
     IDirectInputDevice2AImpl_QueryInterface,
@@ -857,7 +930,7 @@ static const IDirectInputDevice8AVtbl SysMouseAvt =
     IDirectInputDevice7AImpl_EnumEffectsInFile,
     IDirectInputDevice7AImpl_WriteEffectToFile,
     SysMouseAImpl_BuildActionMap,
-    IDirectInputDevice8AImpl_SetActionMap,
+    SysMouseAImpl_SetActionMap,
     IDirectInputDevice8AImpl_GetImageInfo
 };
 
@@ -893,6 +966,6 @@ static const IDirectInputDevice8WVtbl SysMouseWvt =
     IDirectInputDevice7WImpl_EnumEffectsInFile,
     IDirectInputDevice7WImpl_WriteEffectToFile,
     SysMouseWImpl_BuildActionMap,
-    IDirectInputDevice8WImpl_SetActionMap,
+    SysMouseWImpl_SetActionMap,
     IDirectInputDevice8WImpl_GetImageInfo
 };
diff --git a/dlls/dinput8/tests/device.c b/dlls/dinput8/tests/device.c
index 445e11d..479ae34 100644
--- a/dlls/dinput8/tests/device.c
+++ b/dlls/dinput8/tests/device.c
@@ -72,7 +72,7 @@ static void test_device_input(
     DWORD data_size = 1;
 
     hr = IDirectInputDevice8_Acquire(lpdid);
-    todo_wine ok (SUCCEEDED(hr), "Failed to acquire device hr=%08x\n", hr);
+    ok (SUCCEEDED(hr), "Failed to acquire device hr=%08x\n", hr);
 
     if (event_type == INPUT_KEYBOARD)
         keybd_event( event, 0, 0, 0);
@@ -179,11 +179,11 @@ static BOOL CALLBACK enumeration_callback(
 
     /* SetActionMap has set the data format so now it should work */
     hr = IDirectInputDevice8_Acquire(lpdid);
-    todo_wine ok (SUCCEEDED(hr), "Acquire failed hr=%08x\n", hr);
+    ok (SUCCEEDED(hr), "Acquire failed hr=%08x\n", hr);
 
     /* SetActionMap should not work on an acquired device */
     hr = IDirectInputDevice8_SetActionMap(lpdid, data->lpdiaf, NULL, 0);
-    todo_wine ok (hr == DIERR_ACQUIRED, "SetActionMap succeeded with an acquired device hr=%08x\n", hr);
+    ok (hr == DIERR_ACQUIRED, "SetActionMap succeeded with an acquired device hr=%08x\n", hr);
 
     return DIENUM_CONTINUE;
 }
@@ -249,7 +249,7 @@ static void test_action_mapping(void)
         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);
+        ok (hr == DI_NOEFFECT, "SetActionMap should have no effect with no actions to map hr=%08x\n", hr);
 
         af.dwDataSize = 4 * sizeof(actionMapping) / sizeof(actionMapping[0]);
         af.dwNumActions = sizeof(actionMapping) / sizeof(actionMapping[0]);
-- 
1.7.0.4



More information about the wine-patches mailing list