GSoC: dinput8 Action Mapping

Marcus Meissner meissner at suse.de
Mon May 30 09:16:28 CDT 2011


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 at 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 at 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 at 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 at 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 at 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 <lfzawacki at 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 at 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
> 

> 


-- 
Working, but not speaking, for the following german company:
SUSE LINUX Products GmbH, HRB 16746 (AG Nuernberg)
Geschaeftsfuehrer: Jeff Hawn, Jennifer Guild, Felix Imendoerffer



More information about the wine-devel mailing list