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

Lucas Fialho Zawacki lfzawacki at gmail.com
Wed Jun 22 14:07:31 CDT 2011


SetActionMap now finds the actions based on the guidInstance of the DIACTION member, because it
must have been set before by the BuildActionMap method.

---
 dlls/dinput/device.c         |   19 ++++++++--
 dlls/dinput/device_private.h |   10 +++++
 dlls/dinput/keyboard.c       |   79 ++++++++++++++++++++++++++++++++++++++++-
 dlls/dinput/mouse.c          |   49 +++++++++++++++++++++++++-
 4 files changed, 150 insertions(+), 7 deletions(-)

diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c
index 1d17b3f..e4730f3 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 */
 }
@@ -1414,13 +1430,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 ed1512b..66b3498 100644
--- a/dlls/dinput/keyboard.c
+++ b/dlls/dinput/keyboard.c
@@ -584,6 +584,81 @@ 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);
+
+    _copy_diactionformatWtoA(lpdiaf, &diafW);
+
+    HeapFree(GetProcessHeap(), 0, diafW.rgoAction);
+
+    return hr;
+}
+
 static const IDirectInputDevice8AVtbl SysKeyboardAvt =
 {
     IDirectInputDevice2AImpl_QueryInterface,
@@ -616,7 +691,7 @@ static const IDirectInputDevice8AVtbl SysKeyboardAvt =
     IDirectInputDevice7AImpl_EnumEffectsInFile,
     IDirectInputDevice7AImpl_WriteEffectToFile,
     SysKeyboardAImpl_BuildActionMap,
-    IDirectInputDevice8AImpl_SetActionMap,
+    SysKeyboardAImpl_SetActionMap,
     IDirectInputDevice8AImpl_GetImageInfo
 };
 
@@ -652,6 +727,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 554c291..8ae2270 100644
--- a/dlls/dinput/mouse.c
+++ b/dlls/dinput/mouse.c
@@ -826,6 +826,51 @@ 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);
+    _copy_diactionformatWtoA(lpdiaf, &diafW);
+
+    HeapFree(GetProcessHeap(), 0, diafW.rgoAction);
+
+    return hr;
+}
+
 static const IDirectInputDevice8AVtbl SysMouseAvt =
 {
     IDirectInputDevice2AImpl_QueryInterface,
@@ -858,7 +903,7 @@ static const IDirectInputDevice8AVtbl SysMouseAvt =
     IDirectInputDevice7AImpl_EnumEffectsInFile,
     IDirectInputDevice7AImpl_WriteEffectToFile,
     SysMouseAImpl_BuildActionMap,
-    IDirectInputDevice8AImpl_SetActionMap,
+    SysMouseAImpl_SetActionMap,
     IDirectInputDevice8AImpl_GetImageInfo
 };
 
@@ -894,6 +939,6 @@ static const IDirectInputDevice8WVtbl SysMouseWvt =
     IDirectInputDevice7WImpl_EnumEffectsInFile,
     IDirectInputDevice7WImpl_WriteEffectToFile,
     SysMouseWImpl_BuildActionMap,
-    IDirectInputDevice8WImpl_SetActionMap,
+    SysMouseWImpl_SetActionMap,
     IDirectInputDevice8WImpl_GetImageInfo
 };
-- 
1.7.0.4



More information about the wine-patches mailing list