Hey guys. So last week I finally got a good understanding of dinput as a whole and nailed some trivial cases of action mapping, the ones with the keyboard. I'm sending a series of patches so everyone can take a look before I try commiting them. Please note that these contain a partial implementation of EnumDevicesBySemantics, BuildActionMap and SetActionMap, and also they're only the A versions. There are some tests for EnumDevicesBySemantics. I'm not too sure of how to code the tests that require user input...
I hope it's not a nuisance to read the code split in 7 files, if you guys want I can merge it in one big diff.
On a bright note, this patchset results in the input working for these two games:
* http://appdb.winehq.org/objectManager.php?sClass=application&iId=3678 * http://appdb.winehq.org/objectManager.php?sClass=application&iId=7919
Cheers :)
On Sun, May 29, 2011 at 07:18:03PM -0300, Lucas Zawacki wrote:
Hey guys. So last week I finally got a good understanding of dinput as a whole and nailed some trivial cases of action mapping, the ones with the keyboard. I'm sending a series of patches so everyone can take a look before I try commiting them. Please note that these contain a partial implementation of EnumDevicesBySemantics, BuildActionMap and SetActionMap, and also they're only the A versions. There are some tests for EnumDevicesBySemantics. I'm not too sure of how to code the tests that require user input...
I hope it's not a nuisance to read the code split in 7 files, if you guys want I can merge it in one big diff.
Its ok.
In general changes should be in small patches, and should ensure for every patch in the sequence (in sequence): - wine builds - make test still runs
I looked over your patches and as much as I can make out, they look fine :)
Ciao, Marcus
On a bright note, this patchset results in the input working for these two games:
- http://appdb.winehq.org/objectManager.php?sClass=application&iId=3678
- http://appdb.winehq.org/objectManager.php?sClass=application&iId=7919
Cheers :)
From 551a2f3bea643add493d50a5580f7c2a3c2f7566 Mon Sep 17 00:00:00 2001 From: Lucas Fialho Zawacki lfzawacki@gmail.com Date: Sat, 28 May 2011 14:56:28 -0300 Subject: dinput8/tests: Organized it a little and added a test for the EnumDevicesBySemantics callback.
dlls/dinput8/tests/device.c | 37 +++++++++++++++++++++++++------------ 1 files changed, 25 insertions(+), 12 deletions(-)
diff --git a/dlls/dinput8/tests/device.c b/dlls/dinput8/tests/device.c index c18a83a..eca22a9 100644 --- a/dlls/dinput8/tests/device.c +++ b/dlls/dinput8/tests/device.c @@ -27,6 +27,23 @@ #include "initguid.h" #include "dinput.h"
+/* Dummy GUID */ +static const GUID ACTION_MAPPING_GUID = { 0x1, 0x2, 0x3, { 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb } };
+static DIACTION actionMapping[]= +{
- /* axis */
- { 0, 0x01008A01 /* DIAXIS_DRIVINGR_STEER */ , 0, { "Steer" } },
- /* button */
- { 1, 0x01000C01 /* DIBUTTON_DRIVINGR_SHIFTUP */ , 0, { "Upshift" } },
- /* keyboard mapping */
- { 2, DIKEYBOARD_SPACE , 0, { "Missiles" } }
+};
+/* This will set the number of devices, incrementing it
- each time a new one is enumerated
+*/ static BOOL CALLBACK enum_by_semantics( LPCDIDEVICEINSTANCE lpddi, LPDIRECTINPUTDEVICE8 lpdid, @@ -34,6 +51,10 @@ static BOOL CALLBACK enum_by_semantics( DWORD dwRemaining, LPVOID pvRef) {
- int *ndevices = pvRef;
- if (ndevices != NULL) *ndevices += 1;
- return DIENUM_CONTINUE;
}
@@ -44,17 +65,7 @@ static void test_action_mapping(void) HINSTANCE hinst = GetModuleHandle(NULL); LPDIRECTINPUT8 pDI = NULL; DIACTIONFORMAT af;
- /* Dummy GUID */
- const GUID ACTION_MAPPING_GUID = { 0x1, 0x2, 0x3, { 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb } };
- DIACTION actionMapping[]=
- {
/* axis */
{ 0, 0x01008A01 /* DIAXIS_DRIVINGR_STEER */ , 0, { "Steer" } },
/* button */
{ 1, 0x01000C01 /* DIBUTTON_DRIVINGR_SHIFTUP */ , 0, { "Upshift" } }
- };
int ndevices = 0;
hr = CoCreateInstance(&CLSID_DirectInput8, 0, 1, &IID_IDirectInput8A, (LPVOID*)&pDI); if (hr == DIERR_OLDDIRECTINPUTVERSION ||
@@ -86,9 +97,10 @@ static void test_action_mapping(void) af.dwGenre = 0x01000000; /* DIVIRTUAL_DRIVING_RACE */
hr = IDirectInput8_EnumDevicesBySemantics(pDI,0, &af,
enum_by_semantics, 0, 0);
enum_by_semantics, &ndevices, 0);
ok(SUCCEEDED(hr), "EnumDevicesBySemantics failed: hr=%08x\n",hr);
todo_wine ok (ndevices > 0, "EnumDevicesBySemantics did not call the callback. hr=%08x ndevices=%d\n", hr, ndevices);
/* The call fails with a zeroed GUID */ memset(&af.guidActionMap, 0, sizeof(GUID));
@@ -107,3 +119,4 @@ START_TEST(device)
CoUninitialize();
}
-- 1.7.0.4
From 1829925b178b3c2eb45fe4ea1956a226e6f91628 Mon Sep 17 00:00:00 2001 From: Lucas Fialho Zawacki lfzawacki@gmail.com Date: Sun, 29 May 2011 16:49:45 -0300 Subject: dinput: Implement a simple version of EnumDevicesBySemanticsA which enumerates only the keyboard.
dlls/dinput/dinput_main.c | 46 ++++++++++++++++++++++++++++++++++++++------ 1 files changed, 39 insertions(+), 7 deletions(-)
diff --git a/dlls/dinput/dinput_main.c b/dlls/dinput/dinput_main.c index d3727bc..2d572bf 100644 --- a/dlls/dinput/dinput_main.c +++ b/dlls/dinput/dinput_main.c @@ -120,7 +120,7 @@ static struct list direct_input_list = LIST_INIT( direct_input_list ); */ HRESULT WINAPI DirectInputCreateEx( HINSTANCE hinst, DWORD dwVersion, REFIID riid, LPVOID *ppDI,
- LPUNKNOWN punkOuter)
- LPUNKNOWN punkOuter)
{ IDirectInputImpl* This;
@@ -282,7 +282,7 @@ static HRESULT WINAPI IDirectInputAImpl_EnumDevices( } } }
- return 0;
} /****************************************************************************** @@ -290,7 +290,7 @@ static HRESULT WINAPI IDirectInputAImpl_EnumDevices( */ static HRESULT WINAPI IDirectInputWImpl_EnumDevices( LPDIRECTINPUT7W iface, DWORD dwDevType, LPDIENUMDEVICESCALLBACKW lpCallback,
- LPVOID pvRef, DWORD dwFlags)
- LPVOID pvRef, DWORD dwFlags)
{ IDirectInputImpl *This = impl_from_IDirectInput7W( iface ); DIDEVICEINSTANCEW devInstance; @@ -313,7 +313,7 @@ static HRESULT WINAPI IDirectInputWImpl_EnumDevices( } } }
- return 0;
}
@@ -416,7 +416,7 @@ static HRESULT WINAPI IDirectInputWImpl_QueryInterface(LPDIRECTINPUT7W iface, RE
static HRESULT WINAPI IDirectInputAImpl_Initialize(LPDIRECTINPUT7A iface, HINSTANCE hinst, DWORD x) { TRACE("(this=%p,%p,%x)\n",iface, hinst, x);
- /* Initialize can return: DIERR_BETADIRECTINPUTVERSION, DIERR_OLDDIRECTINPUTVERSION and DI_OK.
- Since we already initialized the device, return DI_OK. In the past we returned DIERR_ALREADYINITIALIZED
- which broke applications like Tomb Raider Legend because it isn't a legal return value.
@@ -674,6 +674,9 @@ static HRESULT WINAPI IDirectInput8WImpl_FindDevice(LPDIRECTINPUT8W iface, REFGU return IDirectInput2WImpl_FindDevice( &This->IDirectInput7W_iface, rguid, pszName, pguidInstance ); }
+/***********************************************************************
EnumDevicesBySemanticsA
- */
static HRESULT WINAPI IDirectInput8AImpl_EnumDevicesBySemantics( LPDIRECTINPUT8A iface, LPCSTR ptszUserName, LPDIACTIONFORMATA lpdiActionFormat, LPDIENUMDEVICESBYSEMANTICSCBA lpCallback, @@ -681,8 +684,13 @@ static HRESULT WINAPI IDirectInput8AImpl_EnumDevicesBySemantics( ) { IDirectInputImpl *This = impl_from_IDirectInput8A( iface );
- DIDEVICEINSTANCEA devinst;
- LPDIRECTINPUTDEVICE8A lpdidev;
- unsigned int i;
- int j, r;
- int hasFormat = 0;
- FIXME("(this=%p,%s,%p,%p,%p,%04x): stub\n", This, ptszUserName, lpdiActionFormat,
- TRACE("(this=%p,%s,%p,%p,%p,%04x): stub\n", This, ptszUserName, lpdiActionFormat, lpCallback, pvRef, dwFlags);
#define X(x) if (dwFlags & x) FIXME("\tdwFlags |= "#x"\n"); X(DIEDBSFL_ATTACHEDONLY) @@ -695,6 +703,29 @@ static HRESULT WINAPI IDirectInput8AImpl_EnumDevicesBySemantics(
_dump_diactionformatA(lpdiActionFormat);
- devinst.dwSize = sizeof(devinst);
- /* mimicking what EnumDevices does and calling the callback function */
- for (i = 0; i < NB_DINPUT_DEVICES; i++) {
if (!dinput_devices[i]->enum_deviceA) continue;
for (j = 0, r = -1; r != 0; j++) {
TRACE(" - checking device %u ('%s')\n", i, dinput_devices[i]->name);
if ((r = dinput_devices[i]->enum_deviceA(DI8DEVCLASS_ALL, dwFlags, &devinst, This->dwVersion, j))) {
/* note that we have to create the device and set it's data format */
if ( GET_DIDEVICE_TYPE(devinst.dwDevType) == DI8DEVTYPE_KEYBOARD ) {
IDirectInput_CreateDevice(iface,&devinst.guidInstance, &lpdidev, NULL);
IDirectInputDevice_SetDataFormat(lpdidev,&c_dfDIKeyboard);
hasFormat = 1;
}
/* only enumerate keyboard */
if (!hasFormat) continue;
if (lpCallback(&devinst, lpdidev, 0 , 0, pvRef) == DIENUM_STOP)
return DI_OK;
}
}
- }
- return DI_OK;
}
@@ -841,7 +872,7 @@ static HRESULT WINAPI DICF_CreateInstance( return DirectInputCreateEx(0,0,riid,ppobj,pOuter); }
- FIXME("(%p,%p,%s,%p) Interface not found!\n",This,pOuter,debugstr_guid(riid),ppobj);
- FIXME("(%p,%p,%s,%p) Interface not found!\n",This,pOuter,debugstr_guid(riid),ppobj); return E_NOINTERFACE;
}
@@ -1121,3 +1152,4 @@ void check_dinput_hooks(LPDIRECTINPUTDEVICE8W iface)
LeaveCriticalSection(&dinput_hook_crit);
}
-- 1.7.0.4
From 97459e68a1247854301f7ef05584c6e860ad1b59 Mon Sep 17 00:00:00 2001 From: Lucas Fialho Zawacki lfzawacki@gmail.com Date: Sun, 29 May 2011 16:50:22 -0300 Subject: dinput8/tests: Testing if EnumDevicesBySemantics sets the device buffer size according to the DIACTIONFORMAT.
dlls/dinput8/tests/device.c | 18 ++++++++++++++++-- 1 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/dlls/dinput8/tests/device.c b/dlls/dinput8/tests/device.c index eca22a9..dab298c 100644 --- a/dlls/dinput8/tests/device.c +++ b/dlls/dinput8/tests/device.c @@ -51,10 +51,23 @@ static BOOL CALLBACK enum_by_semantics( DWORD dwRemaining, LPVOID pvRef) {
HRESULT hr;
DIPROPDWORD dipdw; int *ndevices = pvRef;
if (ndevices != NULL) *ndevices += 1;
/* test the buffer size */
dipdw.diph.dwSize = sizeof(DIPROPDWORD);
hr = IDirectInputDevice_GetProperty(lpdid, DIPROP_BUFFERSIZE, &dipdw.diph);
ok (SUCCEEDED(hr), "IDirectInputDevice_GetProperty failed hr=%08x\n",hr);
if ( SUCCEEDED(hr) ) {
todo_wine ok ( dipdw.dwData == 32,
"EnumDevicesBySemantics must set the buffer size, buffersize=%d\n",
dipdw.dwData);
}
return DIENUM_CONTINUE;
}
@@ -94,13 +107,14 @@ static void test_action_mapping(void) af.dwNumActions = sizeof(actionMapping) / sizeof(actionMapping[0]); af.rgoAction = actionMapping; af.guidActionMap = ACTION_MAPPING_GUID;
af.dwBufferSize = 32; af.dwGenre = 0x01000000; /* DIVIRTUAL_DRIVING_RACE */
hr = IDirectInput8_EnumDevicesBySemantics(pDI,0, &af, enum_by_semantics, &ndevices, 0);
ok(SUCCEEDED(hr), "EnumDevicesBySemantics failed: hr=%08x\n",hr);
- todo_wine ok (ndevices > 0, "EnumDevicesBySemantics did not call the callback. hr=%08x ndevices=%d\n", hr, ndevices);
ok(ndevices > 0, "EnumDevicesBySemantics did not call the callback. hr=%08x ndevices=%d\n", hr, ndevices);
/* The call fails with a zeroed GUID */ memset(&af.guidActionMap, 0, sizeof(GUID));
-- 1.7.0.4
From 33b8103cd04a028cd191c39fa58f56f307601b21 Mon Sep 17 00:00:00 2001 From: Lucas Fialho Zawacki lfzawacki@gmail.com Date: Sun, 29 May 2011 16:55:46 -0300 Subject: dinput: EnumDevicesBySemantics now sets the device buffer according to the DIACTIONFORMAT structure
dlls/dinput/dinput_main.c | 9 +++++++++ dlls/dinput8/tests/device.c | 2 +- 2 files changed, 10 insertions(+), 1 deletions(-)
diff --git a/dlls/dinput/dinput_main.c b/dlls/dinput/dinput_main.c index 2d572bf..debf060 100644 --- a/dlls/dinput/dinput_main.c +++ b/dlls/dinput/dinput_main.c @@ -686,6 +686,7 @@ static HRESULT WINAPI IDirectInput8AImpl_EnumDevicesBySemantics( IDirectInputImpl *This = impl_from_IDirectInput8A( iface ); DIDEVICEINSTANCEA devinst; LPDIRECTINPUTDEVICE8A lpdidev;
- DIPROPDWORD dipdw; /* to set the buffer */ unsigned int i; int j, r; int hasFormat = 0;
@@ -720,6 +721,14 @@ static HRESULT WINAPI IDirectInput8AImpl_EnumDevicesBySemantics( /* only enumerate keyboard */ if (!hasFormat) continue;
/* set the buffer */
if (lpdiActionFormat->dwBufferSize > 0) {
IDirectInputDevice_Unacquire(lpdidev);
dipdw.diph.dwSize = sizeof(DIPROPDWORD);
dipdw.dwData = lpdiActionFormat->dwBufferSize;
IDirectInputDevice_SetProperty(lpdidev,DIPROP_BUFFERSIZE,&dipdw.diph);
}
if (lpCallback(&devinst, lpdidev, 0 , 0, pvRef) == DIENUM_STOP) return DI_OK; }
diff --git a/dlls/dinput8/tests/device.c b/dlls/dinput8/tests/device.c index dab298c..70e5498 100644 --- a/dlls/dinput8/tests/device.c +++ b/dlls/dinput8/tests/device.c @@ -63,7 +63,7 @@ static BOOL CALLBACK enum_by_semantics( ok (SUCCEEDED(hr), "IDirectInputDevice_GetProperty failed hr=%08x\n",hr);
if ( SUCCEEDED(hr) ) {
todo_wine ok ( dipdw.dwData == 32,
}ok ( dipdw.dwData == 32, "EnumDevicesBySemantics must set the buffer size, buffersize=%d\n", dipdw.dwData);
-- 1.7.0.4
From 67b5ac926ec3107df70a8b018191a9b209eb22b8 Mon Sep 17 00:00:00 2001 From: Lucas Fialho Zawacki lfzawacki@gmail.com Date: Sun, 29 May 2011 18:48:29 -0300 Subject: dinput: Implemented SetActionMapA. Added an array of action mappings to the wine's dinput device
dlls/dinput/device.c | 64 +++++++++++++++++++++++++---------------- dlls/dinput/device_private.h | 9 +++++- 2 files changed, 47 insertions(+), 26 deletions(-)
diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c index 397e70e..90ede33 100644 --- a/dlls/dinput/device.c +++ b/dlls/dinput/device.c @@ -100,7 +100,7 @@ static void _dump_EnumObjects_flags(DWORD dwFlags) { FE(DIDFT_TGLBUTTON), FE(DIDFT_POV), FE(DIDFT_COLLECTION),
FE(DIDFT_NODATA),
FE(DIDFT_NODATA), FE(DIDFT_FFACTUATOR), FE(DIDFT_FFEFFECTTRIGGER), FE(DIDFT_OUTPUT),
@@ -221,7 +221,7 @@ void _dump_DIDATAFORMAT(const DIDATAFORMAT *df) { TRACE(")\n"); TRACE(" - dwDataSize: %d\n", df->dwDataSize); TRACE(" - dwNumObjs: %d\n", df->dwNumObjs);
- for (i = 0; i < df->dwNumObjs; i++) { TRACE(" - Object %d:\n", i); TRACE(" * GUID: %s ('%s')\n", debugstr_guid(df->rgodf[i].pguid), _dump_dinput_GUID(df->rgodf[i].pguid));
@@ -326,19 +326,19 @@ void fill_DataFormat(void *out, DWORD size, const void *in, const DataFormat *df df->dt[i].offset_out, df->dt[i].value); *(out_c + df->dt[i].offset_out) = (char) df->dt[i].value; break;
case 2: TRACE("Copying (s) to %d default value %d\n", df->dt[i].offset_out, df->dt[i].value); *((short *) (out_c + df->dt[i].offset_out)) = (short) df->dt[i].value; break;
case 4: TRACE("Copying (i) to %d default value %d\n", df->dt[i].offset_out, df->dt[i].value); *((int *) (out_c + df->dt[i].offset_out)) = df->dt[i].value; break;
default: memset((out_c + df->dt[i].offset_out), 0, df->dt[i].size); break;
@@ -388,7 +388,7 @@ static HRESULT create_DataFormat(LPCDIDATAFORMAT asked_format, DataFormat *forma memcpy(format->user_df, asked_format, asked_format->dwSize);
TRACE("Creating DataTransform :\n");
- for (i = 0; i < format->wine_df->dwNumObjs; i++) { format->offsets[i] = -1;
@@ -396,7 +396,7 @@ static HRESULT create_DataFormat(LPCDIDATAFORMAT asked_format, DataFormat *forma for (j = 0; j < asked_format->dwNumObjs; j++) { if (done[j] == 1) continue;
if (/* Check if the application either requests any GUID and if not, it if matches
*/
- the GUID of the Wine object.
@@ -415,7 +415,7 @@ static HRESULT create_DataFormat(LPCDIDATAFORMAT asked_format, DataFormat *forma DIDFT_GETTYPE(asked_format->rgodf[j].dwType) & format->wine_df->rgodf[i].dwType)) { done[j] = 1;
- TRACE("Matching :\n"); TRACE(" - Asked (%d) :\n", j); TRACE(" * GUID: %s ('%s')\n",
@@ -424,7 +424,7 @@ static HRESULT create_DataFormat(LPCDIDATAFORMAT asked_format, DataFormat *forma TRACE(" * Offset: %3d\n", asked_format->rgodf[j].dwOfs); TRACE(" * dwType: %08x\n", asked_format->rgodf[j].dwType); TRACE(" "); _dump_EnumObjects_flags(asked_format->rgodf[j].dwType); TRACE("\n");
- TRACE(" - Wine (%d) :\n", i); TRACE(" * GUID: %s ('%s')\n", debugstr_guid(format->wine_df->rgodf[i].pguid),
@@ -432,7 +432,7 @@ static HRESULT create_DataFormat(LPCDIDATAFORMAT asked_format, DataFormat *forma TRACE(" * Offset: %3d\n", format->wine_df->rgodf[i].dwOfs); TRACE(" * dwType: %08x\n", format->wine_df->rgodf[i].dwType); TRACE(" "); _dump_EnumObjects_flags(format->wine_df->rgodf[i].dwType); TRACE("\n");
elseif (format->wine_df->rgodf[i].dwType & DIDFT_BUTTON) dt[index].size = sizeof(BYTE);
@@ -442,10 +442,10 @@ static HRESULT create_DataFormat(LPCDIDATAFORMAT asked_format, DataFormat *forma format->offsets[i] = asked_format->rgodf[j].dwOfs; dt[index].value = 0; next = next + dt[index].size;
if (format->wine_df->rgodf[i].dwOfs != dt[index].offset_out) same = 0;
- index++; break; }
@@ -462,7 +462,7 @@ static HRESULT create_DataFormat(LPCDIDATAFORMAT asked_format, DataFormat *forma TRACE(" * Offset: %3d\n", asked_format->rgodf[j].dwOfs); TRACE(" * dwType: %08x\n", asked_format->rgodf[j].dwType); TRACE(" "); _dump_EnumObjects_flags(asked_format->rgodf[j].dwType); TRACE("\n");
dt[index].size = sizeof(BYTE); elseif (asked_format->rgodf[j].dwType & DIDFT_BUTTON)
@@ -478,7 +478,7 @@ static HRESULT create_DataFormat(LPCDIDATAFORMAT asked_format, DataFormat *forma same = 0; } }
- format->internal_format_size = format->wine_df->dwDataSize; format->size = index; if (same) {
@@ -1191,7 +1191,7 @@ HRESULT WINAPI IDirectInputDevice2AImpl_EnumEffects( { FIXME("(this=%p,%p,%p,0x%08x): stub!\n", iface, lpCallback, lpvRef, dwFlags);
- return DI_OK;
}
@@ -1203,7 +1203,7 @@ HRESULT WINAPI IDirectInputDevice2WImpl_EnumEffects( { FIXME("(this=%p,%p,%p,0x%08x): stub!\n", iface, lpCallback, lpvRef, dwFlags);
- return DI_OK;
}
@@ -1317,7 +1317,7 @@ HRESULT WINAPI IDirectInputDevice7AImpl_EnumEffectsInFile(LPDIRECTINPUTDEVICE8A DWORD dwFlags) { FIXME("(%p)->(%s,%p,%p,%08x): stub !\n", iface, lpszFileName, pec, pvRef, dwFlags);
- return DI_OK;
}
@@ -1328,7 +1328,7 @@ HRESULT WINAPI IDirectInputDevice7WImpl_EnumEffectsInFile(LPDIRECTINPUTDEVICE8W DWORD dwFlags) { FIXME("(%p)->(%s,%p,%p,%08x): stub !\n", iface, debugstr_w(lpszFileName), pec, pvRef, dwFlags);
- return DI_OK;
}
@@ -1339,7 +1339,7 @@ HRESULT WINAPI IDirectInputDevice7AImpl_WriteEffectToFile(LPDIRECTINPUTDEVICE8A DWORD dwFlags) { FIXME("(%p)->(%s,%08x,%p,%08x): stub !\n", iface, lpszFileName, dwEntries, rgDiFileEft, dwFlags);
- return DI_OK;
}
@@ -1350,7 +1350,7 @@ HRESULT WINAPI IDirectInputDevice7WImpl_WriteEffectToFile(LPDIRECTINPUTDEVICE8W DWORD dwFlags) { FIXME("(%p)->(%s,%08x,%p,%08x): stub !\n", iface, debugstr_w(lpszFileName), dwEntries, rgDiFileEft, dwFlags);
- return DI_OK;
}
@@ -1382,7 +1382,7 @@ HRESULT WINAPI IDirectInputDevice8WImpl_BuildActionMap(LPDIRECTINPUTDEVICE8W ifa X(DIDBAM_INITIALIZE) X(DIDBAM_HWDEFAULTS) #undef X
- return DI_OK;
}
@@ -1391,8 +1391,21 @@ HRESULT WINAPI IDirectInputDevice8AImpl_SetActionMap(LPDIRECTINPUTDEVICE8A iface LPCSTR lpszUserName, DWORD dwFlags) {
- IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8A(iface);
- int i;
- This->use_actionmap = 1;
- /* search for actions for this device and apply them */
- for (i=0; i < lpdiaf->dwNumActions; i++) {
if (IsEqualGUID( &lpdiaf->rgoAction[i].guidInstance, &This->guid ) ) {
int actionIndex = DIDFT_GETINSTANCE(lpdiaf->rgoAction[i].dwObjID);
This->actionmap[actionIndex] = lpdiaf->rgoAction[i].uAppData;
}
- }
- FIXME("(%p)->(%p,%s,%08x): stub !\n", iface, lpdiaf, lpszUserName, dwFlags);
- return DI_OK;
}
@@ -1402,7 +1415,7 @@ HRESULT WINAPI IDirectInputDevice8WImpl_SetActionMap(LPDIRECTINPUTDEVICE8W iface DWORD dwFlags) { FIXME("(%p)->(%p,%s,%08x): stub !\n", iface, lpdiaf, debugstr_w(lpszUserName), dwFlags);
- return DI_OK;
}
@@ -1410,7 +1423,7 @@ HRESULT WINAPI IDirectInputDevice8AImpl_GetImageInfo(LPDIRECTINPUTDEVICE8A iface LPDIDEVICEIMAGEINFOHEADERA lpdiDevImageInfoHeader) { FIXME("(%p)->(%p): stub !\n", iface, lpdiDevImageInfoHeader);
- return DI_OK;
}
@@ -1418,6 +1431,7 @@ HRESULT WINAPI IDirectInputDevice8WImpl_GetImageInfo(LPDIRECTINPUTDEVICE8W iface LPDIDEVICEIMAGEINFOHEADERW lpdiDevImageInfoHeader) { FIXME("(%p)->(%p): stub !\n", iface, lpdiDevImageInfoHeader);
- return DI_OK;
}
diff --git a/dlls/dinput/device_private.h b/dlls/dinput/device_private.h index f254d7f..b399d59 100644 --- a/dlls/dinput/device_private.h +++ b/dlls/dinput/device_private.h @@ -28,6 +28,8 @@ #include "wine/list.h" #include "dinput_private.h"
+#define MAX_DEVICE_OBJECTS 256
typedef struct { int size; @@ -71,6 +73,10 @@ struct IDirectInputDeviceImpl BOOL overflow; /* return DI_BUFFEROVERFLOW in 'GetDeviceData' */
DataFormat data_format; /* user data format and wine to user format converter */
- int use_actionmap;
- /* each app data is indexed by the device ObjID */
- DWORD actionmap[MAX_DEVICE_OBJECTS];
};
extern BOOL get_app_key(HKEY*, HKEY*) DECLSPEC_HIDDEN; @@ -150,7 +156,7 @@ extern HRESULT WINAPI IDirectInputDevice2AImpl_GetObjectInfo( LPDIDEVICEOBJECTINSTANCEA pdidoi, DWORD dwObj, DWORD dwHow) DECLSPEC_HIDDEN; -extern HRESULT WINAPI IDirectInputDevice2WImpl_GetObjectInfo(LPDIRECTINPUTDEVICE8W iface, +extern HRESULT WINAPI IDirectInputDevice2WImpl_GetObjectInfo(LPDIRECTINPUTDEVICE8W iface, LPDIDEVICEOBJECTINSTANCEW pdidoi, DWORD dwObj, DWORD dwHow) DECLSPEC_HIDDEN; @@ -246,3 +252,4 @@ extern HRESULT WINAPI IDirectInputDevice8WImpl_GetImageInfo(LPDIRECTINPUTDEVICE8 LPDIDEVICEIMAGEINFOHEADERW lpdiDevImageInfoHeader) DECLSPEC_HIDDEN;
#endif /* __WINE_DLLS_DINPUT_DINPUTDEVICE_PRIVATE_H */
-- 1.7.0.4
From 5b668ce7a929c34491fd478eefd50730e9a1c4ca Mon Sep 17 00:00:00 2001 From: Lucas Fialho Zawacki lfzawacki@gmail.com Date: Sun, 29 May 2011 18:55:56 -0300 Subject: dinput: queue_event function now sets the uAppData member if the device is using action mapping
dlls/dinput/device.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c index 90ede33..a979fff 100644 --- a/dlls/dinput/device.c +++ b/dlls/dinput/device.c @@ -576,6 +576,10 @@ 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;
- if (This->use_actionmap) {
This->data_queue[This->queue_head].uAppData = This->actionmap[ofs];
- }
- This->queue_head = next_pos; /* Send event if asked */
}
1.7.0.4
From 943df09d16501c88a6a0a9bdf675b8514f268b68 Mon Sep 17 00:00:00 2001 From: Lucas Fialho Zawacki lfzawacki@gmail.com Date: Sun, 29 May 2011 19:01:29 -0300 Subject: dinput: Implemented BuildActionMapA for all the DIACTION that map actions to DIKEYBOARD_* constants.
dlls/dinput/device.c | 23 +++++++++++++++++++++++ 1 files changed, 23 insertions(+), 0 deletions(-)
diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c index a979fff..19a64f7 100644 --- a/dlls/dinput/device.c +++ b/dlls/dinput/device.c @@ -1358,11 +1358,34 @@ HRESULT WINAPI IDirectInputDevice7WImpl_WriteEffectToFile(LPDIRECTINPUTDEVICE8W return DI_OK; }
+/******************************************************************************
- BuildActionMap
- This sets an objID and a GUID for each DIACTION in the DIACTIONFORMAT that
- should be mapped to this device.
- */
HRESULT WINAPI IDirectInputDevice8AImpl_BuildActionMap(LPDIRECTINPUTDEVICE8A iface, LPDIACTIONFORMATA lpdiaf, LPCSTR lpszUserName, DWORD dwFlags) {
- IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8A(iface);
- int i;
+/* dwSemantic=810004df is dwObjID=0xdf04 */ +#define SEMANTIC_TO_OBJID(s) (0x0000ffff & ( ((s) << 8) | ((s) >> 8) ))
- if ( IsEqualGUID(&This->guid, &GUID_SysKeyboard) ) {
for (i=0; i < lpdiaf->dwNumActions; i++) {
if ( HIWORD(lpdiaf->rgoAction[i].dwSemantic) == 0x8100) { /* DIKEYBOARD_* constant */
lpdiaf->rgoAction[i].dwObjID = SEMANTIC_TO_OBJID(lpdiaf->rgoAction[i].dwSemantic);
lpdiaf->rgoAction[i].guidInstance = This->guid;
lpdiaf->rgoAction[i].dwHow |= DIAH_USERCONFIG; /* set it as configured by the user */
}
}
- }
+#undef SEMANTIC_TO_OBJID
- FIXME("(%p)->(%p,%s,%08x): stub !\n", iface, lpdiaf, lpszUserName, dwFlags);
#define X(x) if (dwFlags & x) FIXME("\tdwFlags =|"#x"\n"); X(DIDBAM_DEFAULT) -- 1.7.0.4
On 05/29/2011 04:18 PM, Lucas Zawacki wrote:
I'm sending a series of patches so everyone can take a look before I try commiting them. Please note that these contain a partial implementation of EnumDevicesBySemantics, BuildActionMap and SetActionMap, and also they're only the A versions.
In general you heading the right direction. In practice these patches can't go in as is for number of reasons: - Too many white space changes. Yes, I know dinput looks terrible, thanks to whomever wrote it 10+ years ago. But current Wine policies do not allow white space only changes. You can fix few lines around area you modifying but not throughout the entire file - If you modifying line please change tabs to spaces - I've been working for years to get codding style of dinput to one standard - curly braces on their own line. No curlies when you don't need them. Please don't break it. - You have to implement both A & W versions of your functions, or things will break.
- FIXME("(this=%p,%s,%p,%p,%p,%04x): stub\n", This, ptszUserName, lpdiActionFormat,
- TRACE("(this=%p,%s,%p,%p,%p,%04x): stub\n", This, ptszUserName, lpdiActionFormat,
Don't change fixme to trace without actually implementing stuff. If it's partially implemented - change the message to say "semi-stub".
if ((r = dinput_devices[i]->enum_deviceA(DI8DEVCLASS_ALL, dwFlags, &devinst, This->dwVersion, j))) {
/* note that we have to create the device and set it's data format */
if ( GET_DIDEVICE_TYPE(devinst.dwDevType) == DI8DEVTYPE_KEYBOARD ) {
If you looking for keyboard then you should ask for keyboard devices only instead of DI8DEVCLASS_ALL. Also note that according to MSDN ans some of my tests, keyboard and mouse was always enumerated, regardless of action format.
IDirectInputDevice_SetDataFormat(lpdidev,&c_dfDIKeyboard);
This should be done in IDirectInputDevice8AImpl_SetActionMap not EnumDevicesBySemantics.
ok(SUCCEEDED(hr), "EnumDevicesBySemantics failed: hr=%08x\n",hr);
- todo_wine ok (ndevices > 0, "EnumDevicesBySemantics did not call the callback. hr=%08x ndevices=%d\n", hr, ndevices);
- ok(ndevices > 0, "EnumDevicesBySemantics did not call the callback. hr=%08x ndevices=%d\n", hr, ndevices);
I'm not seeing any changes in the dinput code. How did this test got fixed? You sure it wasn't broken because of incorrect function call? Then it would have failed on Windows.
/* set the buffer */
if (lpdiActionFormat->dwBufferSize > 0) {
IDirectInputDevice_Unacquire(lpdidev);
dipdw.diph.dwSize = sizeof(DIPROPDWORD);
dipdw.dwData = lpdiActionFormat->dwBufferSize;
IDirectInputDevice_SetProperty(lpdidev,DIPROP_BUFFERSIZE,&dipdw.diph);
}
This is wrong. You do not need to un-acquire device - it was just created. You must specify diph.dwHow = DIPH_DEVICE and diph.dwHeaderSize = sizeof(DIPROPHEADER) or this call fail. And this again needs to go into SetActionMap.
- /* each app data is indexed by the device ObjID */
- DWORD actionmap[MAX_DEVICE_OBJECTS];
Wrong data type. Should be UINT_PTR not DWORD.
I'm not too sure of how to code the tests that require user input...
You can inject input events with SendInput or keybd_event/mouse_event. This of course only applies to keyboard and mouse. Joysticks will have to be tested manually.
Please combine patches that implement something with tests for it. Also don't forget to run your tests on Windows. Or at least on Wine with native dinput.dll & dinput8.dll.
Vitaliy
Just a simple doubt. Should I correct the tabs and align the parameters in the function prototype when I implement them? For instance SetActionMap and BuildActionMap have a lot of them.
Thanks