Hey guys, how are you doing? I've got some patches for you.

The first is a refactoring of the BuildActionMap implementations for
keyboard and mouse. I think with 'semantic_to_obj_id' the mapping is
pretty much correct for  keyboard and mouse and it's being done "the
right way".

The second patch is much like one I sent some time ago, it's
SetActionMap for keyboard and mouse, this time (hopefully) with the
dataformat stuff done right too. I've split it up in a third patch,
which implements the "action mapping" per se.

Anyway, tomorrow I'll code some mouse tests to be sure that this is working.

Cheers
From 37e5a1e6d51778ee0d5c0f3081dad8ca1431968f Mon Sep 17 00:00:00 2001
From: Lucas Fialho Zawacki <lfzawa...@gmail.com>
Date: Fri, 10 Jun 2011 21:43:53 -0300
Subject: dinput: Keyboard and mouse implementation of BuildActionMap (try 4)

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       |   60 ++++++++++++++++++++++++++++++++++++++++-
 dlls/dinput/mouse.c          |   57 ++++++++++++++++++++++++++++++++++++++-
 dlls/dinput8/tests/device.c  |    8 +++---
 5 files changed, 149 insertions(+), 10 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..204510a 100644
--- a/dlls/dinput/keyboard.c
+++ b/dlls/dinput/keyboard.c
@@ -524,6 +524,62 @@ 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);
+            if (obj_id != -1)
+            {
+                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 +611,7 @@ static const IDirectInputDevice8AVtbl SysKeyboardAvt =
     IDirectInputDevice2AImpl_SendDeviceData,
     IDirectInputDevice7AImpl_EnumEffectsInFile,
     IDirectInputDevice7AImpl_WriteEffectToFile,
-    IDirectInputDevice8AImpl_BuildActionMap,
+    SysKeyboardAImpl_BuildActionMap,
     IDirectInputDevice8AImpl_SetActionMap,
     IDirectInputDevice8AImpl_GetImageInfo
 };
@@ -591,7 +647,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..65f6099 100644
--- a/dlls/dinput/mouse.c
+++ b/dlls/dinput/mouse.c
@@ -773,6 +773,59 @@ 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);
+            if (obj_id != -1)
+            {
+                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 +858,7 @@ static const IDirectInputDevice8AVtbl SysMouseAvt =
     IDirectInputDevice2AImpl_SendDeviceData,
     IDirectInputDevice7AImpl_EnumEffectsInFile,
     IDirectInputDevice7AImpl_WriteEffectToFile,
-    IDirectInputDevice8AImpl_BuildActionMap,
+    SysMouseAImpl_BuildActionMap,
     IDirectInputDevice8AImpl_SetActionMap,
     IDirectInputDevice8AImpl_GetImageInfo
 };
@@ -841,7 +894,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 4841a1f..f746932 100644
--- a/dlls/dinput8/tests/device.c
+++ b/dlls/dinput8/tests/device.c
@@ -109,9 +109,9 @@ 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 (obj_instance == obj_expected, "Action not mapped correctly instance=%08x expected=%08x\n", obj_instance, obj_expected);
-    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 (obj_instance == obj_expected, "Action not mapped correctly instance=%08x expected=%08x\n", obj_instance, obj_expected);
+    ok (IsEqualGUID(&assigned_to, &ddi.guidInstance), "Action and device GUID do not match action=%d\n", action_index);
 }
 
 static BOOL CALLBACK enumeration_callback(
@@ -236,7 +236,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

From 27f08e686e4b048829e96f9427a96dbcdc88b7ad Mon Sep 17 00:00:00 2001
From: Lucas Fialho Zawacki <lfzawa...@gmail.com>
Date: Sat, 11 Jun 2011 15:45:52 -0300
Subject: dinput: SetActionMap constructing a dataformat for keyboard and mouse

---
 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 204510a..6f3b7ae 100644
--- a/dlls/dinput/keyboard.c
+++ b/dlls/dinput/keyboard.c
@@ -580,6 +580,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,
@@ -612,7 +681,7 @@ static const IDirectInputDevice8AVtbl SysKeyboardAvt =
     IDirectInputDevice7AImpl_EnumEffectsInFile,
     IDirectInputDevice7AImpl_WriteEffectToFile,
     SysKeyboardAImpl_BuildActionMap,
-    IDirectInputDevice8AImpl_SetActionMap,
+    SysKeyboardAImpl_SetActionMap,
     IDirectInputDevice8AImpl_GetImageInfo
 };
 
@@ -648,6 +717,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 65f6099..91d59ac 100644
--- a/dlls/dinput/mouse.c
+++ b/dlls/dinput/mouse.c
@@ -827,6 +827,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,
@@ -859,7 +932,7 @@ static const IDirectInputDevice8AVtbl SysMouseAvt =
     IDirectInputDevice7AImpl_EnumEffectsInFile,
     IDirectInputDevice7AImpl_WriteEffectToFile,
     SysMouseAImpl_BuildActionMap,
-    IDirectInputDevice8AImpl_SetActionMap,
+    SysMouseAImpl_SetActionMap,
     IDirectInputDevice8AImpl_GetImageInfo
 };
 
@@ -895,6 +968,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 f746932..a98c44c 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);
 
@@ -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

From 62014c988f06c728f6e6fa8e0417f3301c4b39a5 Mon Sep 17 00:00:00 2001
From: Lucas Fialho Zawacki <lfzawa...@gmail.com>
Date: Thu, 30 Jun 2011 02:42:11 -0300
Subject: dinput: SetActionMap setting up and retrieving mapped data.

---
 dlls/dinput/device.c         |   16 ++++++++++++++++
 dlls/dinput/device_private.h |    7 +++++++
 dlls/dinput/keyboard.c       |    4 ++++
 dlls/dinput/mouse.c          |    4 ++++
 dlls/dinput8/tests/device.c  |    2 +-
 5 files changed, 32 insertions(+), 1 deletions(-)

diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c
index 16326b4..e3d0521 100644
--- a/dlls/dinput/device.c
+++ b/dlls/dinput/device.c
@@ -604,6 +604,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)
+            {
+                TRACE("Offset %d mapped to uAppData %lu\n", ofs, This->action_map[i].uAppData);
+                This->data_queue[This->queue_head].uAppData = This->action_map[i].uAppData;
+                break;
+            }
+        }
+    }
+
     This->queue_head = next_pos;
     /* Send event if asked */
 }
diff --git a/dlls/dinput/device_private.h b/dlls/dinput/device_private.h
index 1bbc281..503698a 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
@@ -74,6 +80,7 @@ struct IDirectInputDeviceImpl
 
     /* 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 6f3b7ae..f089deb 100644
--- a/dlls/dinput/keyboard.c
+++ b/dlls/dinput/keyboard.c
@@ -611,6 +611,8 @@ HRESULT WINAPI SysKeyboardWImpl_SetActionMap(LPDIRECTINPUTDEVICE8W iface,
     data_format.rgodf = (LPDIOBJECTDATAFORMAT)obj_df;
     data_format.dwNumObjs = num_actions;
 
+    This->base.action_map = HeapAlloc(GetProcessHeap(), 0, sizeof(ActionMap)*num_actions);
+
     for (i = 0; i < lpdiaf->dwNumActions; i++)
     {
         if (IsEqualGUID(&This->base.guid, &lpdiaf->rgoAction[i].guidInstance))
@@ -618,6 +620,8 @@ HRESULT WINAPI SysKeyboardWImpl_SetActionMap(LPDIRECTINPUTDEVICE8W iface,
             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++;
         }
diff --git a/dlls/dinput/mouse.c b/dlls/dinput/mouse.c
index 91d59ac..0eaed61 100644
--- a/dlls/dinput/mouse.c
+++ b/dlls/dinput/mouse.c
@@ -858,6 +858,8 @@ HRESULT WINAPI SysMouseWImpl_SetActionMap(LPDIRECTINPUTDEVICE8W iface,
     data_format.rgodf = (LPDIOBJECTDATAFORMAT)obj_df;
     data_format.dwNumObjs = num_actions;
 
+    This->base.action_map = HeapAlloc(GetProcessHeap(), 0, sizeof(ActionMap)*num_actions);
+
     for (i = 0; i < lpdiaf->dwNumActions; i++)
     {
         unsigned int offset = 0;
@@ -867,6 +869,8 @@ HRESULT WINAPI SysMouseWImpl_SetActionMap(LPDIRECTINPUTDEVICE8W iface,
             int instance = DIDFT_GETINSTANCE(lpdiaf->rgoAction[i].dwObjID);
             memcpy(&obj_df[action], &c_dfDIMouse.rgodf[instance], c_dfDIMouse.dwObjSize);
 
+            This->base.action_map[action].uAppData = lpdiaf->rgoAction[i].uAppData;
+            This->base.action_map[action].offset = offset;
             obj_df[action].dwOfs = offset;
             offset += (obj_df[action].dwType & DIDFT_BUTTON) ? 1 : 4;
 
diff --git a/dlls/dinput8/tests/device.c b/dlls/dinput8/tests/device.c
index a98c44c..0fc0426 100644
--- a/dlls/dinput8/tests/device.c
+++ b/dlls/dinput8/tests/device.c
@@ -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(
-- 
1.7.0.4



Reply via email to