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 :)
From 551a2f3bea643add493d50a5580f7c2a3c2f7566 Mon Sep 17 00:00:00 2001 From: Lucas Fialho Zawacki <lfzawa...@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 <lfzawa...@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 <lfzawa...@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 <lfzawa...@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 <lfzawa...@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"); - + if (format->wine_df->rgodf[i].dwType & DIDFT_BUTTON) dt[index].size = sizeof(BYTE); else @@ -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"); - + if (asked_format->rgodf[j].dwType & DIDFT_BUTTON) dt[index].size = sizeof(BYTE); else @@ -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 <lfzawa...@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 <lfzawa...@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