[prev in list] [next in list] [prev in thread] [next in thread] 

List:       wine-devel
Subject:    Re: GSoC: dinput8 Action Mapping
From:       Lucas Zawacki <lfzawacki () gmail ! com>
Date:       2011-07-29 20:48:43
Message-ID: CAChKjCG1fr8fEKYX9omYW-Tnjcx5sggxYo=9hWE5NY2Mub0JEQ () mail ! gmail ! com
[Download RAW message or body]

Hello!

Here's a lot of patches with a ConfigureDevices implementation. These
patches can be tested with this app I built that uses ConfigureDevices
to set up a joystick action mapping
(https://github.com/downloads/lfzawacki/dinput-samples/dolphin-plugin.exe)
. I also tested it with the Rally Trophy and Star Sonata games.

Any advice on the dialog code is appreciated, it's the first time I've
coded something like this and may have missed some things.

This implementation still lacks some things:

* Implement username property for devices
* Tracking down a bug with Rally Trophy that makes the mouse disappear
while inside the ConfigureDevices dialog.
* Implement the "Sort Assigned" checkbox
* Some fixes to the code

I'll let the code resting here while I keep working on this stuff.

Cheers :)

["0001-dinput-Added-ConfigureDevices-A-to-W-crosscall.patch" (text/x-patch)]

From 77b1cf702bfba082f130d9a28e8d8a1e18433411 Mon Sep 17 00:00:00 2001
From: Lucas Fialho Zawacki <lfzawacki@gmail.com>
Date: Thu, 28 Jul 2011 16:05:44 -0300
Subject: [PATCH 1/8] dinput: Added ConfigureDevices A to W crosscall

I had to switch the position of the two implementations so that the A version could
effectively call the W one.

---
 dlls/dinput/dinput_main.c |   61 ++++++++++++++++++++++++++++++++++----------
 1 files changed, 47 insertions(+), 14 deletions(-)

diff --git a/dlls/dinput/dinput_main.c b/dlls/dinput/dinput_main.c
index d07295d..cb71a50 100644
--- a/dlls/dinput/dinput_main.c
+++ b/dlls/dinput/dinput_main.c
@@ -999,28 +999,61 @@ static HRESULT WINAPI \
IDirectInput8WImpl_EnumDevicesBySemantics(  return DI_OK;
 }
 
-static HRESULT WINAPI IDirectInput8AImpl_ConfigureDevices(
-      LPDIRECTINPUT8A iface, LPDICONFIGUREDEVICESCALLBACK lpdiCallback,
-      LPDICONFIGUREDEVICESPARAMSA lpdiCDParams, DWORD dwFlags, LPVOID pvRefData
+static HRESULT WINAPI IDirectInput8WImpl_ConfigureDevices(
+      LPDIRECTINPUT8W iface, LPDICONFIGUREDEVICESCALLBACK lpdiCallback,
+      LPDICONFIGUREDEVICESPARAMSW lpdiCDParams, DWORD dwFlags, LPVOID pvRefData
 )
 {
-      IDirectInputImpl *This = impl_from_IDirectInput8A( iface );
+    IDirectInputImpl *This = impl_from_IDirectInput8W(iface);
 
-      FIXME("(this=%p,%p,%p,%04x,%p): stub\n", This, lpdiCallback, lpdiCDParams,
-            dwFlags, pvRefData);
-      return 0;
+    FIXME("(this=%p,%p,%p,%04x,%p): stub\n", This, lpdiCallback, lpdiCDParams, \
dwFlags, pvRefData); +
+    return DI_OK;
 }
 
-static HRESULT WINAPI IDirectInput8WImpl_ConfigureDevices(
-      LPDIRECTINPUT8W iface, LPDICONFIGUREDEVICESCALLBACK lpdiCallback,
-      LPDICONFIGUREDEVICESPARAMSW lpdiCDParams, DWORD dwFlags, LPVOID pvRefData
+static HRESULT WINAPI IDirectInput8AImpl_ConfigureDevices(
+      LPDIRECTINPUT8A iface, LPDICONFIGUREDEVICESCALLBACK lpdiCallback,
+      LPDICONFIGUREDEVICESPARAMSA lpdiCDParams, DWORD dwFlags, LPVOID pvRefData
 )
 {
-      IDirectInputImpl *This = impl_from_IDirectInput8W( iface );
+    IDirectInputImpl *This = impl_from_IDirectInput8A(iface);
+    DIACTIONFORMATW diafW;
+    DICONFIGUREDEVICESPARAMSW diCDParamsW;
+    HRESULT hr;
+    int i;
+
+     FIXME("(this=%p,%p,%p,%04x,%p): stub\n", This, lpdiCallback, lpdiCDParams, \
dwFlags, pvRefData); +
+    /* Copy parameters */
+    diCDParamsW.dwSize = sizeof(DICONFIGUREDEVICESPARAMSW);
+    diCDParamsW.dwcFormats = lpdiCDParams->dwcFormats;
+    diCDParamsW.lprgFormats = &diafW;
+    diCDParamsW.hwnd = lpdiCDParams->hwnd;
+
+    diafW.rgoAction = HeapAlloc(GetProcessHeap(), 0, \
sizeof(DIACTIONW)*lpdiCDParams->lprgFormats->dwNumActions); +    \
_copy_diactionformatAtoW(&diafW, lpdiCDParams->lprgFormats); +
+    /* Copy action names */
+    for (i=0; i < diafW.dwNumActions; i++)
+    {
+        const char* from = \
lpdiCDParams->lprgFormats->rgoAction[i].u.lptszActionName; +        WCHAR *to = \
HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*MAX_PATH); +        \
MultiByteToWideChar(CP_ACP, 0, from , -1, to , MAX_PATH); +        \
diafW.rgoAction[i].u.lptszActionName = to; +    }
+
+    hr = IDirectInput8WImpl_ConfigureDevices(&This->IDirectInput8W_iface, \
lpdiCallback, &diCDParamsW, dwFlags, pvRefData); +
+    /* Copy back configuration */
+    _copy_diactionformatWtoA(lpdiCDParams->lprgFormats, &diafW);
+
+    /* Free memory */
+    for (i=0; i < diafW.dwNumActions; i++)
+        HeapFree(GetProcessHeap(), 0, (LPVOID) \
diafW.rgoAction[i].u.lptszActionName); +
+    HeapFree(GetProcessHeap(), 0, diafW.rgoAction);
 
-      FIXME("(this=%p,%p,%p,%04x,%p): stub\n", This, lpdiCallback, lpdiCDParams,
-            dwFlags, pvRefData);
-      return 0;
+    return hr;
 }
 
 static const IDirectInput7AVtbl ddi7avt = {
-- 
1.7.0.4


["0002-dinput-Added-ConfigureDevices-dialog.patch" (text/x-patch)]

From 9313c779540742adedf6984c01b2e073672a93d3 Mon Sep 17 00:00:00 2001
From: Lucas Fialho Zawacki <lfzawacki@gmail.com>
Date: Thu, 28 Jul 2011 16:45:42 -0300
Subject: [PATCH 2/8] dinput: Added ConfigureDevices dialog

---
 dlls/dinput/Makefile.in                  |    7 ++--
 dlls/dinput/configure_devices.c          |   43 ++++++++++++++++++++++++++++
 dlls/dinput/configure_devices.rc         |   45 ++++++++++++++++++++++++++++++
 dlls/dinput/configure_devices_resource.h |   17 +++++++++++
 dlls/dinput/dinput_main.c                |    3 +-
 dlls/dinput/dinput_private.h             |    2 +
 6 files changed, 113 insertions(+), 4 deletions(-)
 create mode 100644 dlls/dinput/configure_devices.c
 create mode 100644 dlls/dinput/configure_devices.rc
 create mode 100644 dlls/dinput/configure_devices_resource.h

diff --git a/dlls/dinput/Makefile.in b/dlls/dinput/Makefile.in
index 24502e6..817658e 100644
--- a/dlls/dinput/Makefile.in
+++ b/dlls/dinput/Makefile.in
@@ -1,6 +1,6 @@
 MODULE    = dinput.dll
 IMPORTLIB = dinput
-IMPORTS   = dxguid uuid ole32 user32 advapi32
+IMPORTS   = dxguid uuid ole32 user32 advapi32 comctl32
 EXTRALIBS = @IOKITLIB@
 
 C_SRCS = \
@@ -13,12 +13,13 @@ C_SRCS = \
 	joystick_linuxinput.c \
 	joystick_osx.c \
 	keyboard.c \
-	mouse.c
+	mouse.c \
+	configure_devices.c
 
 IMPLIB_SRCS = data_formats.c
 
 IDL_R_SRCS = dinput_classes.idl
 
-RC_SRCS = version.rc
+RC_SRCS = version.rc configure_devices.rc
 
 @MAKE_DLL_RULES@
diff --git a/dlls/dinput/configure_devices.c b/dlls/dinput/configure_devices.c
new file mode 100644
index 0000000..1e20b86
--- /dev/null
+++ b/dlls/dinput/configure_devices.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2011 Lucas Fialho Zawacki
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "wine/debug.h"
+#include "wine/unicode.h"
+#include "objbase.h"
+#include "dinput_private.h"
+#include "device_private.h"
+#include "configure_devices_resource.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(dinput);
+
+static HINSTANCE g_hinstance;
+
+HRESULT _configure_devices(LPDIRECTINPUT8W iface,
+                           LPDICONFIGUREDEVICESCALLBACK lpdiCallback,
+                           LPDICONFIGUREDEVICESPARAMSW lpdiCDParams,
+                           DWORD dwFlags,
+                           LPVOID pvRefData,
+                           HINSTANCE hinstance)
+{
+    InitCommonControls();
+
+    g_hinstance = hinstance;
+    DialogBoxParamW(g_hinstance, (LPCWSTR) MAKEINTRESOURCE(IDD_CONFIGUREDEVICES), \
lpdiCDParams->hwnd, 0, 0); +
+    return DI_OK;
+}
diff --git a/dlls/dinput/configure_devices.rc b/dlls/dinput/configure_devices.rc
new file mode 100644
index 0000000..d721ddd
--- /dev/null
+++ b/dlls/dinput/configure_devices.rc
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2011 Lucas Fialho Zawacki
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "configure_devices_resource.h"
+
+STRINGTABLE
+BEGIN
+    IDS_NOACTION           "-"
+    IDS_ACTIONCOLUMN       "Action"
+    IDS_OBJECTCOLUMN       "Object"
+END
+
+IDD_CONFIGUREDEVICES DIALOG 0, 0, 270, 260
+STYLE DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_VISIBLE
+CAPTION "Configure Devices"
+FONT 8, "Ms Shell Dlg"
+{
+    DEFPUSHBUTTON   "OK", IDOK, 10, 236, 50, 14
+    DEFPUSHBUTTON   "Cancel", IDCANCEL, 65, 236, 50, 14
+    DEFPUSHBUTTON   "Reset", IDRESET, 210, 236, 50, 14
+    COMBOBOX        IDC_PLAYERCOMBO, 10, 50, 90, 30, CBS_DROPDOWNLIST | \
CBS_HASSTRINGS +    COMBOBOX        IDC_CONTROLLERCOMBO, 10, 20, 90, 30, \
CBS_DROPDOWNLIST | CBS_HASSTRINGS +    LTEXT           "Player", IDC_PLAYERTEXT, 10, \
40, 21, 8, SS_LEFT +    LTEXT           "Device", IDC_DEVICETEXT, 10, 10, 22, 8, \
SS_LEFT +    LTEXT           "Actions", IDC_ACTIONTEXT, 10, 70, 24, 8, SS_LEFT
+    LTEXT           "Mapping", IDC_MAPPINGTEXT, 120, 8, 28, 8, SS_LEFT
+    LISTBOX         IDC_ACTIONLIST, 10, 80, 90, 130, WS_TABSTOP | WS_VSCROLL | \
LBS_NOINTEGRALHEIGHT | LBS_MULTICOLUMN | LBS_NOTIFY +    AUTOCHECKBOX    "Sort \
Assigned", IDC_CHECKBOXSORT, 120, 215, 60, 8 +    CONTROL         "Listview", \
IDC_DEVICEOBJECTSLIST,  "SysListView32", LVS_REPORT | LVS_AUTOARRANGE | LVS_ALIGNLEFT \
| LVS_SHOWSELALWAYS | LVS_SINGLESEL | WS_BORDER | WS_TABSTOP, 120, 20, 140, 190 +}
diff --git a/dlls/dinput/configure_devices_resource.h \
b/dlls/dinput/configure_devices_resource.h new file mode 100644
index 0000000..cf597ab
--- /dev/null
+++ b/dlls/dinput/configure_devices_resource.h
@@ -0,0 +1,17 @@
+#include <shlobj.h>
+
+#define IDD_CONFIGUREDEVICES                    100
+#define IDC_DEVICETEXT                          1000
+#define IDRESET                                 1001
+#define IDC_ACTIONTEXT                          1002
+#define IDC_PLAYERTEXT                          1005
+#define IDC_DEVICEOBJECTSTEXT                   1006
+#define IDC_CONTROLLERCOMBO                     1009
+#define IDC_PLAYERCOMBO                         1010
+#define IDC_ACTIONLIST                          1012
+#define IDC_DEVICEOBJECTSLIST                   1013
+#define IDC_CHECKBOXSORT                        1014
+#define IDC_MAPPINGTEXT                         1015
+#define IDS_NOACTION                            1016
+#define IDS_ACTIONCOLUMN                        1017
+#define IDS_OBJECTCOLUMN                        1018
diff --git a/dlls/dinput/dinput_main.c b/dlls/dinput/dinput_main.c
index cb71a50..7bc975b 100644
--- a/dlls/dinput/dinput_main.c
+++ b/dlls/dinput/dinput_main.c
@@ -1008,7 +1008,8 @@ static HRESULT WINAPI IDirectInput8WImpl_ConfigureDevices(
 
     FIXME("(this=%p,%p,%p,%04x,%p): stub\n", This, lpdiCallback, lpdiCDParams, \
dwFlags, pvRefData);  
-    return DI_OK;
+    /* Call helper function in configure_devices.c to do the real work */
+    return _configure_devices(iface, lpdiCallback, lpdiCDParams, dwFlags, pvRefData, \
DINPUT_instance);  }
 
 static HRESULT WINAPI IDirectInput8AImpl_ConfigureDevices(
diff --git a/dlls/dinput/dinput_private.h b/dlls/dinput/dinput_private.h
index 3c4776e..773b6c0 100644
--- a/dlls/dinput/dinput_private.h
+++ b/dlls/dinput/dinput_private.h
@@ -67,6 +67,8 @@ extern void _dump_diactionformatA(LPDIACTIONFORMATA) \
DECLSPEC_HIDDEN;  extern void _copy_diactionformatAtoW(LPDIACTIONFORMATW, \
LPDIACTIONFORMATA) DECLSPEC_HIDDEN;  extern void \
_copy_diactionformatWtoA(LPDIACTIONFORMATA, LPDIACTIONFORMATW) DECLSPEC_HIDDEN;  
+extern HRESULT _configure_devices(LPDIRECTINPUT8W iface, \
LPDICONFIGUREDEVICESCALLBACK lpdiCallback, LPDICONFIGUREDEVICESPARAMSW lpdiCDParams, \
DWORD dwFlags, LPVOID pvRefData, HINSTANCE hinstance) DECLSPEC_HIDDEN; +
 #define IS_DIPROP(x)    (((ULONG_PTR)(x) >> 16) == 0)
 
 #define DIKEYBOARD_MASK    0x81000000
-- 
1.7.0.4


["0003-dinput-Added-enumerated-devices-to-ConfigureDevices-.patch" (text/x-patch)]

From 1fcc4d3640edbb2efc8f77c66f9be71625eb7937 Mon Sep 17 00:00:00 2001
From: Lucas Fialho Zawacki <lfzawacki@gmail.com>
Date: Thu, 28 Jul 2011 18:32:45 -0300
Subject: [PATCH 3/8] dinput: Added enumerated devices to ConfigureDevices dialog

---
 dlls/dinput/configure_devices.c |  117 ++++++++++++++++++++++++++++++++++++++-
 1 files changed, 116 insertions(+), 1 deletions(-)

diff --git a/dlls/dinput/configure_devices.c b/dlls/dinput/configure_devices.c
index 1e20b86..6d081f0 100644
--- a/dlls/dinput/configure_devices.c
+++ b/dlls/dinput/configure_devices.c
@@ -25,8 +25,120 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(dinput);
 
+typedef struct {
+    int nobjects;
+    LPDIRECTINPUTDEVICE8W lpdid;
+    DIDEVICEINSTANCEW ddi;
+    DIDEVICEOBJECTINSTANCEW ddo[256];
+} DeviceData;
+
+typedef struct {
+    int ndevices;
+    DeviceData *devices;
+} DIDevicesData;
+
+typedef struct {
+    LPDIRECTINPUT8W lpDI;
+    LPDICONFIGUREDEVICESPARAMSW params;
+    DWORD flags;
+} ConfigureDevicesData;
+
 static HINSTANCE g_hinstance;
 
+/*
+ * Enumeration callback functions
+ */
+static BOOL CALLBACK count_devices(LPCDIDEVICEINSTANCEW lpddi, LPDIRECTINPUTDEVICE8W \
lpdid, DWORD dwFlags, DWORD dwRemaining, LPVOID pvRef) +{
+    DIDevicesData *data = (DIDevicesData*) pvRef;
+
+    data->ndevices++;
+    return DIENUM_CONTINUE;
+}
+
+static BOOL CALLBACK collect_devices(LPCDIDEVICEINSTANCEW lpddi, \
LPDIRECTINPUTDEVICE8W lpdid, DWORD dwFlags, DWORD dwRemaining, LPVOID pvRef) +{
+    DIDevicesData *data = (DIDevicesData*) pvRef;
+    DeviceData *device = &data->devices[data->ndevices];
+    device->lpdid = lpdid;
+    device->ddi = *lpddi;
+
+    IDirectInputDevice_AddRef(lpdid);
+
+    data->ndevices++;
+    return DIENUM_CONTINUE;
+}
+
+/*
+ * Utility functions
+ */
+static void init_devices(HWND dialog, LPDIRECTINPUT8W lpDI, DIDevicesData *data, \
LPDIACTIONFORMATW lpdiaf) +{
+    int i;
+
+    /* Count devices */
+    IDirectInput8_EnumDevicesBySemantics(lpDI, NULL, lpdiaf, count_devices, (LPVOID) \
data, 0); +
+    /* Allocate devices */
+    data->devices = (DeviceData*) HeapAlloc(GetProcessHeap(), 0, sizeof(DeviceData) \
* data->ndevices); +
+    /* Collect and insert */
+    data->ndevices = 0;
+    IDirectInput8_EnumDevicesBySemantics(lpDI, NULL, lpdiaf, collect_devices, \
(LPVOID) data, 0); +
+    for (i=0; i < data->ndevices; i++)
+        SendDlgItemMessageW(dialog, IDC_CONTROLLERCOMBO, CB_ADDSTRING, 0, (LPARAM) \
data->devices[i].ddi.tszProductName ); +}
+
+static void destroy_devices(DIDevicesData *data)
+{
+    int i;
+    for (i=0; i < data->ndevices; i++)
+        IDirectInputDevice8_Release(data->devices[i].lpdid);
+
+    HeapFree(GetProcessHeap(), 0, data->devices);
+}
+
+static INT_PTR CALLBACK ConfigureDevicesDlgProc(HWND dialog, UINT uMsg, WPARAM \
wParam, LPARAM lParam) +{
+    static LPDIACTIONFORMATW lpdiaf;
+    static DIDevicesData devices_data;
+    static ConfigureDevicesData *conf_data;
+
+    switch(uMsg)
+    {
+        case WM_INITDIALOG:
+            /* Initialize action format and enumerate devices */
+            conf_data = (ConfigureDevicesData*) lParam;
+            lpdiaf = conf_data->params->lprgFormats;
+
+            init_devices(dialog, conf_data->lpDI, &devices_data, lpdiaf);
+
+            break;
+
+        case WM_COMMAND:
+
+            switch( LOWORD( wParam ) )
+            {
+                case IDOK:
+                    EndDialog(dialog, 0);
+                    destroy_devices(&devices_data);
+                    break;
+
+                case IDCANCEL:
+                    EndDialog(dialog, 0);
+                    destroy_devices(&devices_data);
+                    break;
+
+                case IDRESET:
+                    break;
+            }
+        break;
+    }
+
+    return FALSE;
+}
+
 HRESULT _configure_devices(LPDIRECTINPUT8W iface,
                            LPDICONFIGUREDEVICESCALLBACK lpdiCallback,
                            LPDICONFIGUREDEVICESPARAMSW lpdiCDParams,
@@ -34,10 +146,13 @@ HRESULT _configure_devices(LPDIRECTINPUT8W iface,
                            LPVOID pvRefData,
                            HINSTANCE hinstance)
 {
+    ConfigureDevicesData data = { iface, lpdiCDParams, dwFlags };
+
     InitCommonControls();
 
     g_hinstance = hinstance;
-    DialogBoxParamW(g_hinstance, (LPCWSTR) MAKEINTRESOURCE(IDD_CONFIGUREDEVICES), \
lpdiCDParams->hwnd, 0, 0); +
+    DialogBoxParamW(g_hinstance, (LPCWSTR) MAKEINTRESOURCE(IDD_CONFIGUREDEVICES), \
lpdiCDParams->hwnd, ConfigureDevicesDlgProc, (LPARAM) &data);  
     return DI_OK;
 }
-- 
1.7.0.4


["0004-dinput-Added-object-action-enumeration-to-ConfigureD.patch" (text/x-patch)]

From a0f6d394f3a1a083ee76ed276fca79b24ef8e953 Mon Sep 17 00:00:00 2001
From: Lucas Fialho Zawacki <lfzawacki@gmail.com>
Date: Thu, 28 Jul 2011 19:03:31 -0300
Subject: [PATCH 4/8] dinput: Added object/action enumeration to ConfigureDevices \
dialog

---
 dlls/dinput/configure_devices.c |  121 +++++++++++++++++++++++++++++++++++++++
 1 files changed, 121 insertions(+), 0 deletions(-)

diff --git a/dlls/dinput/configure_devices.c b/dlls/dinput/configure_devices.c
index 6d081f0..312eda1 100644
--- a/dlls/dinput/configure_devices.c
+++ b/dlls/dinput/configure_devices.c
@@ -48,6 +48,16 @@ static HINSTANCE g_hinstance;
 /*
  * Enumeration callback functions
  */
+static BOOL CALLBACK collect_objects(LPCDIDEVICEOBJECTINSTANCEW lpddo, LPVOID pvRef)
+{
+    DeviceData *data = (DeviceData*) pvRef;
+
+    data->ddo[data->nobjects] = *lpddo;
+
+    data->nobjects++;
+    return DIENUM_CONTINUE;
+}
+
 static BOOL CALLBACK count_devices(LPCDIDEVICEINSTANCEW lpddi, LPDIRECTINPUTDEVICE8W \
lpdid, DWORD dwFlags, DWORD dwRemaining, LPVOID pvRef)  {
     DIDevicesData *data = (DIDevicesData*) pvRef;
@@ -65,13 +75,64 @@ static BOOL CALLBACK collect_devices(LPCDIDEVICEINSTANCEW lpddi, \
LPDIRECTINPUTDE  
     IDirectInputDevice_AddRef(lpdid);
 
+    device->nobjects = 0;
+    IDirectInputDevice_EnumObjects(lpdid, collect_objects, (LPVOID) device, \
DIDFT_ALL); +
     data->ndevices++;
     return DIENUM_CONTINUE;
 }
 
 /*
+ * Listview utility functions
+ */
+static void init_listview_columns(HWND dialog)
+{
+    LVCOLUMNW listColumn;
+    RECT viewRect;
+    int width;
+    WCHAR column[MAX_PATH];
+
+    GetClientRect(GetDlgItem(dialog, IDC_DEVICEOBJECTSLIST), &viewRect);
+    width = (viewRect.right - viewRect.left)/2;
+
+    LoadStringW(g_hinstance, IDS_OBJECTCOLUMN, column, \
sizeof(column)/sizeof(column[0])); +    listColumn.mask = LVCF_TEXT | LVCF_WIDTH | \
LVCF_SUBITEM; +    listColumn.pszText = column;
+    listColumn.cchTextMax = lstrlenW(listColumn.pszText);
+    listColumn.cx = width;
+
+    SendDlgItemMessageW (dialog, IDC_DEVICEOBJECTSLIST, LVM_INSERTCOLUMNW, 0, \
(LPARAM) &listColumn); +
+    LoadStringW(g_hinstance, IDS_ACTIONCOLUMN, column, \
sizeof(column)/sizeof(column[0])); +    listColumn.cx = width;
+    listColumn.pszText = column;
+    listColumn.cchTextMax = lstrlenW(listColumn.pszText);
+
+    SendDlgItemMessageW(dialog, IDC_DEVICEOBJECTSLIST, LVM_INSERTCOLUMNW, 1, \
(LPARAM) &listColumn); +}
+
+static void lv_set_item_text(HWND dialog, int item, int subItem, WCHAR *text)
+{
+    LVITEMW lvItem;
+    if (item < 0 || subItem < 0) return;
+    lvItem.mask = LVIF_TEXT;
+    lvItem.iItem = item;
+    lvItem.iSubItem = subItem;
+    lvItem.pszText = text;
+    lvItem.cchTextMax = lstrlenW(lvItem.pszText);
+
+    SendDlgItemMessageW(dialog, IDC_DEVICEOBJECTSLIST, LVM_SETITEMW, 0, (LPARAM) \
&lvItem); +}
+
+/*
  * Utility functions
  */
+static DeviceData* get_cur_device(HWND dialog, DIDevicesData *data)
+{
+    int sel = SendDlgItemMessageW(dialog, IDC_CONTROLLERCOMBO, CB_GETCURSEL, 0, 0);
+    return &data->devices[sel];
+}
+
 static void init_devices(HWND dialog, LPDIRECTINPUT8W lpDI, DIDevicesData *data, \
LPDIACTIONFORMATW lpdiaf)  {
     int i;
@@ -90,6 +151,54 @@ static void init_devices(HWND dialog, LPDIRECTINPUT8W lpDI, \
                DIDevicesData *data,
         SendDlgItemMessageW(dialog, IDC_CONTROLLERCOMBO, CB_ADDSTRING, 0, (LPARAM) \
data->devices[i].ddi.tszProductName );  }
 
+static void fill_device_object_list(HWND dialog, DeviceData *device, \
LPDIACTIONFORMATW lpdiaf) +{
+    LVITEMW item;
+    WCHAR no_action[MAX_PATH];
+    int i, j;
+
+    LoadStringW(g_hinstance, IDS_NOACTION, no_action, \
sizeof(no_action)/sizeof(no_action[0])); +
+    /* Clean the listview */
+    SendDlgItemMessageW(dialog, IDC_DEVICEOBJECTSLIST, LVM_DELETEALLITEMS, 0, 0);
+
+    /* Add each object */
+    for (i=0; i < device->nobjects; i++)
+    {
+        WCHAR *action_text = no_action;
+        int action = -1;
+
+        item.mask = LVIF_TEXT | LVIF_PARAM;
+        item.iItem = i;
+        item.iSubItem = 0;
+        item.pszText = device->ddo[i].tszName;
+        item.cchTextMax = lstrlenW(item.pszText);
+
+        /* Search for an assigned action  for this device */
+        for (j=0; j < lpdiaf->dwNumActions; j++)
+        {
+            if (IsEqualGUID(&lpdiaf->rgoAction[j].guidInstance, \
&device->ddi.guidInstance) && +                lpdiaf->rgoAction[j].dwObjID == \
device->ddo[i].dwType) +            {
+                action = j;
+                break;
+            }
+        }
+
+        /* Keep action index in the listview item */
+        item.lParam = (LPARAM) action;
+
+        /* Add the item */
+        SendDlgItemMessageW(dialog, IDC_DEVICEOBJECTSLIST, LVM_INSERTITEMW, 0, \
(LPARAM) &item); +
+        if (action != -1)
+            action_text = (WCHAR*) lpdiaf->rgoAction[action].lptszActionName;
+
+        /* Object/Action text */
+        lv_set_item_text(dialog, i, 1, action_text);
+    }
+}
+
 static void destroy_devices(DIDevicesData *data)
 {
     int i;
@@ -112,6 +221,7 @@ static INT_PTR CALLBACK ConfigureDevicesDlgProc(HWND dialog, UINT \
uMsg, WPARAM w  conf_data = (ConfigureDevicesData*) lParam;
             lpdiaf = conf_data->params->lprgFormats;
 
+            init_listview_columns(dialog);
             init_devices(dialog, conf_data->lpDI, &devices_data, lpdiaf);
 
             break;
@@ -120,6 +230,17 @@ static INT_PTR CALLBACK ConfigureDevicesDlgProc(HWND dialog, \
UINT uMsg, WPARAM w  
             switch( LOWORD( wParam ) )
             {
+
+                case IDC_CONTROLLERCOMBO:
+
+                    switch (HIWORD(wParam))
+                    {
+                        case CBN_SELCHANGE:
+                            fill_device_object_list(dialog, get_cur_device(dialog, \
&devices_data), lpdiaf); +                            break;
+                    }
+                    break;
+
                 case IDOK:
                     EndDialog(dialog, 0);
                     destroy_devices(&devices_data);
-- 
1.7.0.4


["0005-dinput-Added-display-of-available-actions-to-Configu.patch" (text/x-patch)]

From f36cfa42e2d4e4facbbe25636a705a39eeed3e18 Mon Sep 17 00:00:00 2001
From: Lucas Fialho Zawacki <lfzawacki@gmail.com>
Date: Thu, 28 Jul 2011 19:28:24 -0300
Subject: [PATCH 5/8] dinput: Added display of available actions to ConfigureDevices \
dialog

---
 dlls/dinput/configure_devices.c |   46 +++++++++++++++++++++++++++++++++++++++
 1 files changed, 46 insertions(+), 0 deletions(-)

diff --git a/dlls/dinput/configure_devices.c b/dlls/dinput/configure_devices.c
index 312eda1..1a05fa3 100644
--- a/dlls/dinput/configure_devices.c
+++ b/dlls/dinput/configure_devices.c
@@ -111,6 +111,11 @@ static void init_listview_columns(HWND dialog)
     SendDlgItemMessageW(dialog, IDC_DEVICEOBJECTSLIST, LVM_INSERTCOLUMNW, 1, \
(LPARAM) &listColumn);  }
 
+static int lv_get_cur_item(HWND dialog)
+{
+    return SendDlgItemMessageW(dialog, IDC_DEVICEOBJECTSLIST, LVM_GETNEXTITEM, -1, \
LVNI_SELECTED); +}
+
 static void lv_set_item_text(HWND dialog, int item, int subItem, WCHAR *text)
 {
     LVITEMW lvItem;
@@ -208,6 +213,35 @@ static void destroy_devices(DIDevicesData *data)
     HeapFree(GetProcessHeap(), 0, data->devices);
 }
 
+static void show_suitable_actions(HWND dialog, DeviceData* device, LPDIACTIONFORMATW \
lpdiaf) +{
+    int i, added = 0;
+    int obj = lv_get_cur_item(dialog);
+
+    if (obj < 0) return;
+
+    SendDlgItemMessageW(dialog, IDC_ACTIONLIST, LB_RESETCONTENT, 0, 0);
+
+    for (i=0; i < lpdiaf->dwNumActions; i++)
+    {
+        /* Skip keyboard actions for non keyboards */
+        if (GET_DIDEVICE_TYPE(device->ddi.dwDevType) != DI8DEVTYPE_KEYBOARD &&
+            (lpdiaf->rgoAction[i].dwSemantic & DIKEYBOARD_MASK) == DIKEYBOARD_MASK) \
continue; +
+        /* Skip mouse actions for non mouses */
+        if (GET_DIDEVICE_TYPE(device->ddi.dwDevType) != DI8DEVTYPE_MOUSE &&
+            (lpdiaf->rgoAction[i].dwSemantic & DIMOUSE_MASK) == DIMOUSE_MASK) \
continue; +
+        /* Add action string and index in the action format to the list entry */
+        if (DIDFT_GETINSTANCE(lpdiaf->rgoAction[i].dwSemantic) & \
DIDFT_GETTYPE(device->ddo[obj].dwType)) +        {
+            SendDlgItemMessageW(dialog, IDC_ACTIONLIST, LB_ADDSTRING, 0, \
(LPARAM)lpdiaf->rgoAction[i].lptszActionName); +            \
SendDlgItemMessageW(dialog, IDC_ACTIONLIST, LB_SETITEMDATA, added, (LPARAM) i); +     \
added++; +        }
+    }
+}
+
 static INT_PTR CALLBACK ConfigureDevicesDlgProc(HWND dialog, UINT uMsg, WPARAM \
wParam, LPARAM lParam)  {
     static LPDIACTIONFORMATW lpdiaf;
@@ -226,6 +260,18 @@ static INT_PTR CALLBACK ConfigureDevicesDlgProc(HWND dialog, \
UINT uMsg, WPARAM w  
             break;
 
+        case WM_NOTIFY:
+
+            switch (((LPNMHDR)lParam)->code)
+            {
+                case LVN_ITEMCHANGED:
+                    show_suitable_actions(dialog, get_cur_device(dialog, \
&devices_data), lpdiaf); +                    break;
+
+            }
+            break;
+
+
         case WM_COMMAND:
 
             switch( LOWORD( wParam ) )
-- 
1.7.0.4


["0006-dinput-Added-possibility-to-change-the-action-mappin.patch" (text/x-patch)]

From 009243ffe518c695cf5d54773d8bcd54b729ebd8 Mon Sep 17 00:00:00 2001
From: Lucas Fialho Zawacki <lfzawacki@gmail.com>
Date: Thu, 28 Jul 2011 19:56:39 -0300
Subject: [PATCH 6/8] dinput: Added possibility to change the action mapping in the \
ConfigureDevices dialog

---
 dlls/dinput/configure_devices.c |   51 +++++++++++++++++++++++++++++++++++++++
 1 files changed, 51 insertions(+), 0 deletions(-)

diff --git a/dlls/dinput/configure_devices.c b/dlls/dinput/configure_devices.c
index 1a05fa3..29e7811 100644
--- a/dlls/dinput/configure_devices.c
+++ b/dlls/dinput/configure_devices.c
@@ -116,6 +116,17 @@ static int lv_get_cur_item(HWND dialog)
     return SendDlgItemMessageW(dialog, IDC_DEVICEOBJECTSLIST, LVM_GETNEXTITEM, -1, \
LVNI_SELECTED);  }
 
+static int lv_get_item_data(HWND dialog, int index)
+{
+    LVITEMW item;
+    item.iItem = index;
+    item.iSubItem = 0;
+
+    SendDlgItemMessageW(dialog, IDC_DEVICEOBJECTSLIST, LVM_GETITEMW , 0, \
(LPARAM)&item); +
+    return item.lParam;
+}
+
 static void lv_set_item_text(HWND dialog, int item, int subItem, WCHAR *text)
 {
     LVITEMW lvItem;
@@ -242,11 +253,35 @@ static void show_suitable_actions(HWND dialog, DeviceData* \
device, LPDIACTIONFOR  }
 }
 
+static void assign_action(HWND dialog, DeviceData* device, LPDIACTIONFORMATW lpdiaf)
+{
+    int sel = SendDlgItemMessageW(dialog, IDC_ACTIONLIST, LB_GETCURSEL, 0, 0);
+    int action = SendDlgItemMessageW(dialog, IDC_ACTIONLIST, LB_GETITEMDATA, sel, \
0); +    int obj = lv_get_cur_item(dialog);
+    int old_action = lv_get_item_data(dialog, obj);
+
+    DIDEVICEOBJECTINSTANCEW ddo = device->ddo[obj];
+
+    /* Clear old action */
+    if (old_action != action)
+    {
+        lpdiaf->rgoAction[old_action].dwObjID = 0;
+        lpdiaf->rgoAction[old_action].guidInstance = GUID_NULL;
+        lpdiaf->rgoAction[old_action].dwHow = DIAH_UNMAPPED;
+    }
+
+    /* Set new action */
+    lpdiaf->rgoAction[action].dwObjID = ddo.dwType;
+    lpdiaf->rgoAction[action].guidInstance = device->ddi.guidInstance;
+    lpdiaf->rgoAction[action].dwHow = DIAH_USERCONFIG;
+}
+
 static INT_PTR CALLBACK ConfigureDevicesDlgProc(HWND dialog, UINT uMsg, WPARAM \
wParam, LPARAM lParam)  {
     static LPDIACTIONFORMATW lpdiaf;
     static DIDevicesData devices_data;
     static ConfigureDevicesData *conf_data;
+    static int display_only = 0;
 
     switch(uMsg)
     {
@@ -255,6 +290,8 @@ static INT_PTR CALLBACK ConfigureDevicesDlgProc(HWND dialog, UINT \
uMsg, WPARAM w  conf_data = (ConfigureDevicesData*) lParam;
             lpdiaf = conf_data->params->lprgFormats;
 
+            if (!(conf_data->flags & DICD_EDIT)) display_only = 1;
+
             init_listview_columns(dialog);
             init_devices(dialog, conf_data->lpDI, &devices_data, lpdiaf);
 
@@ -277,6 +314,20 @@ static INT_PTR CALLBACK ConfigureDevicesDlgProc(HWND dialog, \
UINT uMsg, WPARAM w  switch( LOWORD( wParam ) )
             {
 
+                case IDC_ACTIONLIST:
+
+                    switch (HIWORD(wParam))
+                    {
+                        case LBN_DBLCLK:
+                            /* Ignore this if app did not ask for editing */
+                            if (display_only) break;
+
+                            assign_action(dialog, get_cur_device(dialog, \
&devices_data), lpdiaf); +                            fill_device_object_list(dialog, \
get_cur_device(dialog, &devices_data), lpdiaf); +                            break;
+                    }
+                    break;
+
                 case IDC_CONTROLLERCOMBO:
 
                     switch (HIWORD(wParam))
-- 
1.7.0.4


["0007-dinput-Working-CANCEL-and-RESET-buttons-in-Configure.patch" (text/x-patch)]

From ceec7adba404d61b65a3372aca7ae46bca2a511a Mon Sep 17 00:00:00 2001
From: Lucas Fialho Zawacki <lfzawacki@gmail.com>
Date: Fri, 29 Jul 2011 03:13:05 -0300
Subject: [PATCH 7/8] dinput: Working CANCEL and RESET buttons in ConfigureDevices \
dialog.

---
 dlls/dinput/configure_devices.c |   20 ++++++++++++++++++++
 1 files changed, 20 insertions(+), 0 deletions(-)

diff --git a/dlls/dinput/configure_devices.c b/dlls/dinput/configure_devices.c
index 29e7811..6432136 100644
--- a/dlls/dinput/configure_devices.c
+++ b/dlls/dinput/configure_devices.c
@@ -276,9 +276,22 @@ static void assign_action(HWND dialog, DeviceData* device, \
LPDIACTIONFORMATW lpd  lpdiaf->rgoAction[action].dwHow = DIAH_USERCONFIG;
 }
 
+static void copy_actions(LPDIACTIONFORMATW to, LPDIACTIONFORMATW from)
+{
+    int i;
+    for (i=0; i < from->dwNumActions; i++)
+    {
+        to->rgoAction[i].guidInstance = from->rgoAction[i].guidInstance;
+        to->rgoAction[i].dwObjID = from->rgoAction[i].dwObjID;
+        to->rgoAction[i].dwHow = from->rgoAction[i].dwHow;
+        to->rgoAction[i].lptszActionName = from->rgoAction[i].lptszActionName;
+    }
+}
+
 static INT_PTR CALLBACK ConfigureDevicesDlgProc(HWND dialog, UINT uMsg, WPARAM \
wParam, LPARAM lParam)  {
     static LPDIACTIONFORMATW lpdiaf;
+    static DIACTIONFORMATW original_diaf;
     static DIDevicesData devices_data;
     static ConfigureDevicesData *conf_data;
     static int display_only = 0;
@@ -290,6 +303,10 @@ static INT_PTR CALLBACK ConfigureDevicesDlgProc(HWND dialog, \
UINT uMsg, WPARAM w  conf_data = (ConfigureDevicesData*) lParam;
             lpdiaf = conf_data->params->lprgFormats;
 
+            original_diaf.dwNumActions = lpdiaf->dwNumActions;
+            original_diaf.rgoAction = HeapAlloc(GetProcessHeap(), 0, \
sizeof(DIACTIONW) * lpdiaf->dwNumActions); +            copy_actions(&original_diaf, \
lpdiaf); +
             if (!(conf_data->flags & DICD_EDIT)) display_only = 1;
 
             init_listview_columns(dialog);
@@ -344,11 +361,14 @@ static INT_PTR CALLBACK ConfigureDevicesDlgProc(HWND dialog, \
UINT uMsg, WPARAM w  break;
 
                 case IDCANCEL:
+                    copy_actions(lpdiaf, &original_diaf);
                     EndDialog(dialog, 0);
                     destroy_devices(&devices_data);
                     break;
 
                 case IDRESET:
+                    copy_actions(lpdiaf, &original_diaf);
+                    fill_device_object_list(dialog, get_cur_device(dialog, \
&devices_data), lpdiaf);  break;
             }
         break;
-- 
1.7.0.4


["0008-dinput-In-BuildActionMap-don-t-assign-objects-to-act.patch" (text/x-patch)]

From 0ce62bf9c28e1fe76d723f62c468d00f43bbaa0a Mon Sep 17 00:00:00 2001
From: Lucas Fialho Zawacki <lfzawacki@gmail.com>
Date: Fri, 29 Jul 2011 16:36:31 -0300
Subject: [PATCH 8/8] dinput: In BuildActionMap, don't assign objects to actions mapped by an user

---
 dlls/dinput/joystick.c |    2 ++
 dlls/dinput/keyboard.c |    2 ++
 dlls/dinput/mouse.c    |    2 ++
 3 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/dlls/dinput/joystick.c b/dlls/dinput/joystick.c
index 2d8a818..e3babc6 100644
--- a/dlls/dinput/joystick.c
+++ b/dlls/dinput/joystick.c
@@ -445,6 +445,8 @@ HRESULT WINAPI JoystickWGenericImpl_BuildActionMap(LPDIRECTINPUTDEVICE8W iface,
         DWORD type = 0x000000ff & (lpdiaf->rgoAction[i].dwSemantic >> 8);
         DWORD genre = 0xff000000 & lpdiaf->rgoAction[i].dwSemantic;
 
+        if (lpdiaf->rgoAction[i].dwHow == DIAH_USERCONFIG) continue;
+
         /* Only consider actions of the right genre */
         if (lpdiaf->dwGenre != genre && genre != DIGENRE_ANY) continue;
 
diff --git a/dlls/dinput/keyboard.c b/dlls/dinput/keyboard.c
index 3c93bcd..4354a68 100644
--- a/dlls/dinput/keyboard.c
+++ b/dlls/dinput/keyboard.c
@@ -536,6 +536,8 @@ static HRESULT WINAPI SysKeyboardWImpl_BuildActionMap(LPDIRECTINPUTDEVICE8W ifac
 
     for (i=0; i < lpdiaf->dwNumActions; i++)
     {
+        if (lpdiaf->rgoAction[i].dwHow == DIAH_USERCONFIG) continue;
+
         if ((lpdiaf->rgoAction[i].dwSemantic & DIKEYBOARD_MASK) == DIKEYBOARD_MASK)
         {
             DWORD obj_id = semantic_to_obj_id(&This->base, lpdiaf->rgoAction[i].dwSemantic);
diff --git a/dlls/dinput/mouse.c b/dlls/dinput/mouse.c
index fb724d5..eeb749a 100644
--- a/dlls/dinput/mouse.c
+++ b/dlls/dinput/mouse.c
@@ -783,6 +783,8 @@ static HRESULT WINAPI SysMouseWImpl_BuildActionMap(LPDIRECTINPUTDEVICE8W iface,
 
     for (i=0; i < lpdiaf->dwNumActions; i++)
     {
+        if (lpdiaf->rgoAction[i].dwHow == DIAH_USERCONFIG) continue;
+
         if ((lpdiaf->rgoAction[i].dwSemantic & DIMOUSE_MASK) == DIMOUSE_MASK)
         {
             DWORD obj_id = semantic_to_obj_id(&This->base, lpdiaf->rgoAction[i].dwSemantic);
-- 
1.7.0.4





[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic