From 8797a33bcd643fecbe4167cbf0f3880759ee3096 Mon Sep 17 00:00:00 2001
From: Lucas Fialho Zawacki <lfzawacki@gmail.com>
Date: Fri, 10 Jun 2011 16:40:54 -0300
Subject: dinput: SetActionMap setting the device buffer and data format.

---
 dlls/dinput/device.c        |   42 ++++++++++++++++++++++++++++++++++++++----
 dlls/dinput8/tests/device.c |   35 +++++++++++++++++++++++++++++++++++
 2 files changed, 73 insertions(+), 4 deletions(-)

diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c
index 397e70e..b457b27 100644
--- a/dlls/dinput/device.c
+++ b/dlls/dinput/device.c
@@ -1391,8 +1391,25 @@ HRESULT WINAPI IDirectInputDevice8AImpl_SetActionMap(LPDIRECTINPUTDEVICE8A iface
 						     LPCSTR lpszUserName,
 						     DWORD dwFlags)
 {
-    FIXME("(%p)->(%p,%s,%08x): stub !\n", iface, lpdiaf, lpszUserName, dwFlags);
-    
+    IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8A(iface);
+    DIPROPDWORD dp;
+
+    FIXME("(%p)->(%p,%s,%08x): semi-stub !\n", iface, lpdiaf, lpszUserName, dwFlags);
+
+    if (This->acquired) return DIERR_ACQUIRED;
+
+    IDirectInputDevice8_SetDataFormat(iface, This->data_format.wine_df);
+
+    if (lpdiaf->dwBufferSize > 0)
+    {
+        memset(&dp,0,sizeof(dp));
+        dp.diph.dwSize = sizeof(DIPROPDWORD);
+        dp.dwData = lpdiaf->dwBufferSize;
+        dp.diph.dwHeaderSize = sizeof(DIPROPHEADER);
+        dp.diph.dwHow = DIPH_DEVICE;
+        IDirectInputDevice8_SetProperty(iface,DIPROP_BUFFERSIZE,&dp.diph);
+    }
+
     return DI_OK;
 }
 
@@ -1401,8 +1418,25 @@ HRESULT WINAPI IDirectInputDevice8WImpl_SetActionMap(LPDIRECTINPUTDEVICE8W iface
 						     LPCWSTR lpszUserName,
 						     DWORD dwFlags)
 {
-    FIXME("(%p)->(%p,%s,%08x): stub !\n", iface, lpdiaf, debugstr_w(lpszUserName), 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;
+
+    IDirectInputDevice8_SetDataFormat(iface, This->data_format.wine_df);
+
+    if (lpdiaf->dwBufferSize > 0)
+    {
+        memset(&dp,0,sizeof(dp));
+        dp.diph.dwSize = sizeof(DIPROPDWORD);
+        dp.dwData = lpdiaf->dwBufferSize;
+        dp.diph.dwHeaderSize = sizeof(DIPROPHEADER);
+        dp.diph.dwHow = DIPH_DEVICE;
+        IDirectInputDevice8_SetProperty(iface,DIPROP_BUFFERSIZE,&dp.diph);
+    }
+
     return DI_OK;
 }
 
diff --git a/dlls/dinput8/tests/device.c b/dlls/dinput8/tests/device.c
index 256c275..5074831 100644
--- a/dlls/dinput8/tests/device.c
+++ b/dlls/dinput8/tests/device.c
@@ -57,6 +57,8 @@ static BOOL CALLBACK enumeration_callback(
     DWORD dwRemaining,
     LPVOID pvRef)
 {
+    HRESULT hr;
+    DIPROPDWORD dp;
     struct enum_data *data = pvRef;
     if (!data) return DIENUM_CONTINUE;
 
@@ -79,6 +81,38 @@ static BOOL CALLBACK enumeration_callback(
         ok (dwFlags & DIEDBS_MAPPEDPRI1, "Mouse should be mapped as pri1 dwFlags=%08x\n",dwFlags);
     }
 
+    /* Building and setting an action map */
+    /* It should not use any pre-stored mappings so we use DIDBAM_INITIALIZE */
+    hr = IDirectInputDevice8_BuildActionMap(lpdid,data->lpdiaf,NULL,DIDBAM_INITIALIZE);
+    ok (SUCCEEDED(hr), "BuildActionMap failed hr=%08x\n",hr);
+
+    /* Device has no data format and thus can't be acquired */
+    hr = IDirectInputDevice8_Acquire(lpdid);
+    ok (hr == DIERR_INVALIDPARAM, "Device was acquired before SetActionMap hr=%08x\n",hr);
+
+    hr = IDirectInputDevice8_SetActionMap(lpdid,data->lpdiaf,NULL,0);
+    ok (SUCCEEDED(hr), "SetActionMap failed hr=%08x\n",hr);
+
+    /* Test buffer size */
+    memset(&dp,0,sizeof(dp));
+    dp.diph.dwSize = sizeof(dp);
+    dp.diph.dwHeaderSize = sizeof(DIPROPHEADER);
+    dp.diph.dwHow  = DIPH_DEVICE;
+
+    hr = IDirectInputDevice_GetProperty(lpdid, DIPROP_BUFFERSIZE, &dp.diph);
+    ok (SUCCEEDED(hr), "GetProperty failed hr=%08x\n",hr);
+    ok (dp.dwData == data->lpdiaf->dwBufferSize,"SetActionMap must set the buffer, buffersize=%d\n", dp.dwData);
+
+    /* SetActionMap has set the data format so now it should work */
+    hr = IDirectInputDevice8_Acquire(lpdid);
+    ok (SUCCEEDED(hr), "Acquire failed hr=%08x\n",hr);
+
+    if (SUCCEEDED(hr))
+    {
+        hr = IDirectInputDevice8_SetActionMap(lpdid,data->lpdiaf,NULL,0);
+        ok (hr == DIERR_ACQUIRED, "SetActionMap succeeded with an acquired device hr=%08x\n",hr);
+    }
+
     return DIENUM_CONTINUE;
 }
 
@@ -119,6 +153,7 @@ static void test_action_mapping(void)
     af.rgoAction = actionMapping;
     af.guidActionMap = ACTION_MAPPING_GUID;
     af.dwGenre = 0x01000000; /* DIVIRTUAL_DRIVING_RACE */
+    af.dwBufferSize = 32;
 
     hr = IDirectInput8_EnumDevicesBySemantics(pDI,0, &af, enumeration_callback, &data, 0);
     ok(SUCCEEDED(hr), "EnumDevicesBySemantics failed: hr=%08x\n",hr);
-- 
1.7.0.4

