[PATCH 6/6] dinput: SetActionMap internal action mapping and GetDeviceData uAppData retrieval (try 3)

Lucas Fialho Zawacki lfzawacki at gmail.com
Tue Jun 28 11:56:46 CDT 2011


Removed unecessary DIACTIONFORMAT copy in SetActionMap in keyboard and mouse versions.

---
 dlls/dinput/device.c         |   19 +++++++++--
 dlls/dinput/device_private.h |   10 +++++
 dlls/dinput/keyboard.c       |   77 ++++++++++++++++++++++++++++++++++++++++-
 dlls/dinput/mouse.c          |   48 +++++++++++++++++++++++++-
 dlls/dinput8/tests/device.c  |   10 +++---
 5 files changed, 152 insertions(+), 12 deletions(-)

diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c
index d243de1..d04e3b7 100644
--- a/dlls/dinput/device.c
+++ b/dlls/dinput/device.c
@@ -576,6 +576,22 @@ void queue_event(LPDIRECTINPUTDEVICE8A iface, int inst_id, DWORD data, DWORD tim
     This->data_queue[This->queue_head].dwData      = data;
     This->data_queue[This->queue_head].dwTimeStamp = time;
     This->data_queue[This->queue_head].dwSequence  = seq;
+
+    /* 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 == ofs)
+            {
+                This->data_queue[This->queue_head].uAppData = This->action_map[i].uAppData;
+                TRACE("Offset %d mapped to uAppData %lu\n", ofs, This->action_map[i].uAppData);
+                break;
+            }
+        }
+    }
+
     This->queue_head = next_pos;
     /* Send event if asked */
 }
@@ -1412,13 +1428,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 f254d7f..e25a66d 100644
--- a/dlls/dinput/device_private.h
+++ b/dlls/dinput/device_private.h
@@ -47,6 +47,12 @@ typedef struct
     LPDIDATAFORMAT              user_df;     /* user defined data format */
 } DataFormat;
 
+typedef struct
+{
+    unsigned int offset;
+    UINT_PTR uAppData;
+} ActionMap;
+
 /* Device implementation */
 typedef struct IDirectInputDeviceImpl IDirectInputDeviceImpl;
 struct IDirectInputDeviceImpl
@@ -71,6 +77,10 @@ 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 */
+    ActionMap                  *action_map;  /* array of mappings */
 };
 
 extern BOOL get_app_key(HKEY*, HKEY*) DECLSPEC_HIDDEN;
diff --git a/dlls/dinput/keyboard.c b/dlls/dinput/keyboard.c
index 523bf0a..704bcd9 100644
--- a/dlls/dinput/keyboard.c
+++ b/dlls/dinput/keyboard.c
@@ -583,6 +583,79 @@ 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;
+    This->base.action_map = HeapAlloc(GetProcessHeap(), 0, sizeof(ActionMap)*num_actions);
+
+    /* construct the action map */
+    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);
+
+            This->base.action_map[action].uAppData = lpdiaf->rgoAction[i].uAppData;
+            This->base.action_map[action].offset = action;
+
+            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,
@@ -615,7 +688,7 @@ static const IDirectInputDevice8AVtbl SysKeyboardAvt =
     IDirectInputDevice7AImpl_EnumEffectsInFile,
     IDirectInputDevice7AImpl_WriteEffectToFile,
     SysKeyboardAImpl_BuildActionMap,
-    IDirectInputDevice8AImpl_SetActionMap,
+    SysKeyboardAImpl_SetActionMap,
     IDirectInputDevice8AImpl_GetImageInfo
 };
 
@@ -651,6 +724,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 a293740..c8b2045 100644
--- a/dlls/dinput/mouse.c
+++ b/dlls/dinput/mouse.c
@@ -825,6 +825,50 @@ 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);
+    int i, num_actions = 0;
+
+    FIXME("(%p)->(%p,%s,%08x): semi-stub !\n", iface, lpdiaf, debugstr_w(lpszUserName), dwFlags);
+
+    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;
+
+    /* We can get the data format right after the mapping is right */
+    IDirectInputDevice8_SetDataFormat(iface, &c_dfDIMouse);
+
+    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 +901,7 @@ static const IDirectInputDevice8AVtbl SysMouseAvt =
     IDirectInputDevice7AImpl_EnumEffectsInFile,
     IDirectInputDevice7AImpl_WriteEffectToFile,
     SysMouseAImpl_BuildActionMap,
-    IDirectInputDevice8AImpl_SetActionMap,
+    SysMouseAImpl_SetActionMap,
     IDirectInputDevice8AImpl_GetImageInfo
 };
 
@@ -893,6 +937,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 3b02d45..9048b6f 100644
--- a/dlls/dinput8/tests/device.c
+++ b/dlls/dinput8/tests/device.c
@@ -68,7 +68,7 @@ static void test_keyboard_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);
 
     keybd_event( key, 0, 0, 0);
 
@@ -82,7 +82,7 @@ static void test_keyboard_input(
     }
 
     ok (data_size == 1, "GetDeviceData did not read any event\n");
-    todo_wine ok (obj_data.uAppData == expected, "Retrieval of action failed uAppData=%lu expected=%d\n", obj_data.uAppData, expected);
+    ok (obj_data.uAppData == expected, "Retrieval of action failed uAppData=%lu expected=%d\n", obj_data.uAppData, expected);
 }
 
 static void test_build_action_map(
@@ -169,11 +169,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;
 }
@@ -239,7 +239,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