[DINPUT] Sync with Wine Staging 4.18. CORE-16441

This commit is contained in:
Amine Khaldi 2019-10-26 13:03:34 +01:00
parent 1477b2deb7
commit 41c8c312e1
16 changed files with 1001 additions and 376 deletions

View file

@ -30,7 +30,6 @@
* - Fallout : works great in X and DGA mode
*/
#include "config.h"
#include <assert.h>
#include <stdarg.h>
#include <string.h>
@ -39,7 +38,9 @@
#define NONAMELESSUNION
#include "wine/debug.h"
#include "wine/heap.h"
#include "wine/unicode.h"
#include "wine/asm.h"
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
@ -47,6 +48,7 @@
#include "objbase.h"
#include "rpcproxy.h"
#include "initguid.h"
#include "devguid.h"
#include "dinput_private.h"
#include "device_private.h"
#include "dinputd.h"
@ -289,6 +291,20 @@ static void _dump_EnumDevices_dwFlags(DWORD dwFlags)
TRACE("\n");
}
static const char *dump_semantic(DWORD semantic)
{
if((semantic & 0xff000000) == 0xff000000)
return "Any AXIS";
else if((semantic & 0x82000000) == 0x82000000)
return "Mouse";
else if((semantic & 0x81000000) == 0x81000000)
return "Keybaord";
else if((semantic & DIVIRTUAL_FLYING_HELICOPTER) == DIVIRTUAL_FLYING_HELICOPTER)
return "Helicopter";
return "Unknown";
}
static void _dump_diactionformatA(LPDIACTIONFORMATA lpdiActionFormat)
{
unsigned int i;
@ -311,7 +327,7 @@ static void _dump_diactionformatA(LPDIACTIONFORMATA lpdiActionFormat)
{
TRACE("diaf.rgoAction[%u]:\n", i);
TRACE("\tuAppData=0x%lx\n", lpdiActionFormat->rgoAction[i].uAppData);
TRACE("\tdwSemantic=0x%08x\n", lpdiActionFormat->rgoAction[i].dwSemantic);
TRACE("\tdwSemantic=0x%08x (%s)\n", lpdiActionFormat->rgoAction[i].dwSemantic, dump_semantic(lpdiActionFormat->rgoAction[i].dwSemantic));
TRACE("\tdwFlags=0x%x\n", lpdiActionFormat->rgoAction[i].dwFlags);
TRACE("\tszActionName=%s\n", debugstr_a(lpdiActionFormat->rgoAction[i].u.lptszActionName));
TRACE("\tguidInstance=%s\n", debugstr_guid(&lpdiActionFormat->rgoAction[i].guidInstance));
@ -467,9 +483,10 @@ static HRESULT WINAPI IDirectInputAImpl_EnumDevices(
for (i = 0; i < ARRAY_SIZE(dinput_devices); i++) {
if (!dinput_devices[i]->enum_deviceA) continue;
TRACE(" Checking device %u ('%s')\n", i, dinput_devices[i]->name);
for (j = 0, r = S_OK; SUCCEEDED(r); j++) {
devInstance.dwSize = sizeof(devInstance);
TRACE(" - checking device %u ('%s')\n", i, dinput_devices[i]->name);
r = dinput_devices[i]->enum_deviceA(dwDevType, dwFlags, &devInstance, This->dwVersion, j);
if (r == S_OK)
if (enum_callback_wrapper(lpCallback, &devInstance, pvRef) == DIENUM_STOP)
@ -525,7 +542,7 @@ static ULONG WINAPI IDirectInputAImpl_AddRef(LPDIRECTINPUT7A iface)
IDirectInputImpl *This = impl_from_IDirectInput7A( iface );
ULONG ref = InterlockedIncrement(&This->ref);
TRACE( "(%p) incrementing from %d\n", This, ref - 1);
TRACE( "(%p) ref %d\n", This, ref );
return ref;
}
@ -540,7 +557,7 @@ static ULONG WINAPI IDirectInputAImpl_Release(LPDIRECTINPUT7A iface)
IDirectInputImpl *This = impl_from_IDirectInput7A( iface );
ULONG ref = InterlockedDecrement( &This->ref );
TRACE( "(%p) releasing from %d\n", This, ref + 1 );
TRACE( "(%p) ref %d\n", This, ref );
if (ref == 0)
{
@ -566,53 +583,39 @@ static HRESULT WINAPI IDirectInputAImpl_QueryInterface(LPDIRECTINPUT7A iface, RE
if (!riid || !ppobj)
return E_POINTER;
*ppobj = NULL;
#if DIRECTINPUT_VERSION == 0x0700
if (IsEqualGUID( &IID_IUnknown, riid ) ||
IsEqualGUID( &IID_IDirectInputA, riid ) ||
IsEqualGUID( &IID_IDirectInput2A, riid ) ||
IsEqualGUID( &IID_IDirectInput7A, riid ))
{
IsEqualGUID( &IID_IDirectInputA, riid ) ||
IsEqualGUID( &IID_IDirectInput2A, riid ) ||
IsEqualGUID( &IID_IDirectInput7A, riid ))
*ppobj = &This->IDirectInput7A_iface;
IUnknown_AddRef( (IUnknown*)*ppobj );
return DI_OK;
}
if (IsEqualGUID( &IID_IDirectInputW, riid ) ||
IsEqualGUID( &IID_IDirectInput2W, riid ) ||
IsEqualGUID( &IID_IDirectInput7W, riid ))
{
else if (IsEqualGUID( &IID_IDirectInputW, riid ) ||
IsEqualGUID( &IID_IDirectInput2W, riid ) ||
IsEqualGUID( &IID_IDirectInput7W, riid ))
*ppobj = &This->IDirectInput7W_iface;
IUnknown_AddRef( (IUnknown*)*ppobj );
return DI_OK;
}
if (IsEqualGUID( &IID_IDirectInput8A, riid ))
{
#else
if (IsEqualGUID( &IID_IUnknown, riid ) ||
IsEqualGUID( &IID_IDirectInput8A, riid ))
*ppobj = &This->IDirectInput8A_iface;
IUnknown_AddRef( (IUnknown*)*ppobj );
return DI_OK;
}
if (IsEqualGUID( &IID_IDirectInput8W, riid ))
{
else if (IsEqualGUID( &IID_IDirectInput8W, riid ))
*ppobj = &This->IDirectInput8W_iface;
IUnknown_AddRef( (IUnknown*)*ppobj );
return DI_OK;
}
#endif
if (IsEqualGUID( &IID_IDirectInputJoyConfig8, riid ))
{
*ppobj = &This->IDirectInputJoyConfig8_iface;
IUnknown_AddRef( (IUnknown*)*ppobj );
if(*ppobj)
{
IUnknown_AddRef( (IUnknown*)*ppobj );
return DI_OK;
}
FIXME( "Unsupported interface: %s\n", debugstr_guid(riid));
*ppobj = NULL;
WARN( "Unsupported interface: %s\n", debugstr_guid(riid));
return E_NOINTERFACE;
}
@ -690,7 +693,7 @@ static HRESULT WINAPI IDirectInputAImpl_Initialize(LPDIRECTINPUT7A iface, HINSTA
{
IDirectInputImpl *This = impl_from_IDirectInput7A( iface );
TRACE("(%p)->(%p, 0x%04x)\n", iface, hinst, version);
TRACE("(%p)->(%p, 0x%04x)\n", This, hinst, version);
if (!hinst)
return DIERR_INVALIDPARAM;
@ -947,7 +950,7 @@ static HRESULT WINAPI IDirectInput8AImpl_Initialize(LPDIRECTINPUT8A iface, HINST
{
IDirectInputImpl *This = impl_from_IDirectInput8A( iface );
TRACE("(%p)->(%p, 0x%04x)\n", iface, hinst, version);
TRACE("(%p)->(%p, 0x%04x)\n", This, hinst, version);
if (!hinst)
return DIERR_INVALIDPARAM;
@ -1104,10 +1107,12 @@ static HRESULT WINAPI IDirectInput8AImpl_EnumDevicesBySemantics(
if (lpCallback(&didevis[i], lpdid, callbackFlags, --remain, pvRef) == DIENUM_STOP)
{
IDirectInputDevice_Release(lpdid);
HeapFree(GetProcessHeap(), 0, didevis);
HeapFree(GetProcessHeap(), 0, username_w);
return DI_OK;
}
IDirectInputDevice_Release(lpdid);
}
HeapFree(GetProcessHeap(), 0, didevis);
@ -1130,9 +1135,11 @@ static HRESULT WINAPI IDirectInput8AImpl_EnumDevicesBySemantics(
if (lpCallback(&didevi, lpdid, callbackFlags, --remain, pvRef) == DIENUM_STOP)
{
IDirectInputDevice_Release(lpdid);
HeapFree(GetProcessHeap(), 0, username_w);
return DI_OK;
}
IDirectInputDevice_Release(lpdid);
}
}
@ -1260,9 +1267,34 @@ static HRESULT WINAPI IDirectInput8AImpl_ConfigureDevices(
/* Copy parameters */
diCDParamsW.dwSize = sizeof(DICONFIGUREDEVICESPARAMSW);
diCDParamsW.dwcUsers = lpdiCDParams->dwcUsers;
diCDParamsW.dwcFormats = lpdiCDParams->dwcFormats;
diCDParamsW.lprgFormats = &diafW;
diCDParamsW.hwnd = lpdiCDParams->hwnd;
diCDParamsW.lptszUserNames = NULL;
if (lpdiCDParams->lptszUserNames) {
char *start = lpdiCDParams->lptszUserNames;
WCHAR *to = NULL;
int total_len = 0;
for (i = 0; i < lpdiCDParams->dwcUsers; i++)
{
char *end = start + 1;
int len;
while (*(end++));
len = MultiByteToWideChar(CP_ACP, 0, start, end - start, NULL, 0);
total_len += len + 2; /* length of string and two null char */
if (to)
to = HeapReAlloc(GetProcessHeap(), 0, to, sizeof(WCHAR) * total_len);
else
to = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * total_len);
MultiByteToWideChar(CP_ACP, 0, start, end - start, to + (total_len - len - 2), len);
to[total_len] = 0;
to[total_len - 1] = 0;
}
diCDParamsW.lptszUserNames = to;
}
diafW.rgoAction = HeapAlloc(GetProcessHeap(), 0, sizeof(DIACTIONW)*lpdiCDParams->lprgFormats->dwNumActions);
_copy_diactionformatAtoW(&diafW, lpdiCDParams->lprgFormats);
@ -1290,6 +1322,8 @@ static HRESULT WINAPI IDirectInput8AImpl_ConfigureDevices(
HeapFree(GetProcessHeap(), 0, diafW.rgoAction);
heap_free((void*) diCDParamsW.lptszUserNames);
return hr;
}
@ -1777,7 +1811,7 @@ static DWORD WINAPI hook_thread_proc(void *param)
DispatchMessageW(&msg);
}
return 0;
FreeLibraryAndExitThread(DINPUT_instance, 0);
}
static DWORD hook_thread_id;
@ -1794,15 +1828,16 @@ static CRITICAL_SECTION dinput_hook_crit = { &dinput_critsect_debug, -1, 0, 0, 0
static BOOL check_hook_thread(void)
{
static HANDLE hook_thread;
HMODULE module;
EnterCriticalSection(&dinput_hook_crit);
TRACE("IDirectInputs left: %d\n", list_count(&direct_input_list));
if (!list_empty(&direct_input_list) && !hook_thread)
{
GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (const WCHAR*)DINPUT_instance, &module);
hook_thread_event = CreateEventW(NULL, FALSE, FALSE, NULL);
hook_thread = CreateThread(NULL, 0, hook_thread_proc, hook_thread_event, 0, &hook_thread_id);
LeaveCriticalSection(&dinput_hook_crit);
}
else if (list_empty(&direct_input_list) && hook_thread)
{
@ -1817,16 +1852,11 @@ static BOOL check_hook_thread(void)
hook_thread_id = 0;
PostThreadMessageW(tid, WM_USER+0x10, 0, 0);
LeaveCriticalSection(&dinput_hook_crit);
/* wait for hook thread to exit */
WaitForSingleObject(hook_thread, INFINITE);
CloseHandle(hook_thread);
hook_thread = NULL;
}
else
LeaveCriticalSection(&dinput_hook_crit);
LeaveCriticalSection(&dinput_hook_crit);
return hook_thread_id != 0;
}