Commit 77f5edda authored by Rémi Bernon's avatar Rémi Bernon Committed by Alexandre Julliard

dinput: Factor all (Un)Acquire implementations together.

And introduce new internal acquire / unacquire callbacks. Signed-off-by: 's avatarRémi Bernon <rbernon@codeweavers.com> Signed-off-by: 's avatarAlexandre Julliard <julliard@winehq.org>
parent 7908d25f
......@@ -886,50 +886,56 @@ void queue_event( IDirectInputDevice8W *iface, int inst_id, DWORD data, DWORD ti
* Acquire
*/
HRESULT WINAPI IDirectInputDevice2WImpl_Acquire(LPDIRECTINPUTDEVICE8W iface)
HRESULT WINAPI IDirectInputDevice2WImpl_Acquire( IDirectInputDevice8W *iface )
{
IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface);
HRESULT res;
TRACE("(%p)\n", This);
IDirectInputDeviceImpl *impl = impl_from_IDirectInputDevice8W( iface );
HRESULT hr = DI_OK;
if (!This->data_format.user_df) return DIERR_INVALIDPARAM;
if (This->dwCoopLevel & DISCL_FOREGROUND && This->win != GetForegroundWindow())
return DIERR_OTHERAPPHASPRIO;
TRACE( "iface %p.\n", iface );
EnterCriticalSection(&This->crit);
res = This->acquired ? S_FALSE : DI_OK;
This->acquired = 1;
LeaveCriticalSection(&This->crit);
if (res != DI_OK) return res;
EnterCriticalSection( &impl->crit );
if (impl->acquired)
hr = DI_NOEFFECT;
else if (!impl->data_format.user_df)
hr = DIERR_INVALIDPARAM;
else if ((impl->dwCoopLevel & DISCL_FOREGROUND) && impl->win != GetForegroundWindow())
hr = DIERR_OTHERAPPHASPRIO;
else
{
impl->acquired = TRUE;
if (FAILED(hr = impl->vtbl->acquire( iface ))) impl->acquired = FALSE;
}
LeaveCriticalSection( &impl->crit );
if (hr != DI_OK) return hr;
dinput_hooks_acquire_device(iface);
check_dinput_hooks(iface, TRUE);
dinput_hooks_acquire_device( iface );
check_dinput_hooks( iface, TRUE );
return res;
return hr;
}
/******************************************************************************
* Unacquire
*/
HRESULT WINAPI IDirectInputDevice2WImpl_Unacquire(LPDIRECTINPUTDEVICE8W iface)
HRESULT WINAPI IDirectInputDevice2WImpl_Unacquire( IDirectInputDevice8W *iface )
{
IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface);
HRESULT res;
IDirectInputDeviceImpl *impl = impl_from_IDirectInputDevice8W( iface );
HRESULT hr = DI_OK;
TRACE("(%p)\n", This);
TRACE( "iface %p.\n", iface );
EnterCriticalSection(&This->crit);
res = !This->acquired ? DI_NOEFFECT : DI_OK;
This->acquired = 0;
LeaveCriticalSection(&This->crit);
if (res != DI_OK) return res;
EnterCriticalSection( &impl->crit );
if (!impl->acquired) hr = DI_NOEFFECT;
else hr = impl->vtbl->unacquire( iface );
impl->acquired = FALSE;
LeaveCriticalSection( &impl->crit );
if (hr != DI_OK) return hr;
dinput_hooks_unacquire_device(iface);
check_dinput_hooks(iface, FALSE);
dinput_hooks_unacquire_device( iface );
check_dinput_hooks( iface, FALSE );
return res;
return hr;
}
/******************************************************************************
......@@ -1787,7 +1793,7 @@ HRESULT WINAPI IDirectInputDevice8WImpl_GetImageInfo(LPDIRECTINPUTDEVICE8W iface
return DI_OK;
}
HRESULT direct_input_device_alloc( SIZE_T size, const IDirectInputDevice8WVtbl *vtbl,
HRESULT direct_input_device_alloc( SIZE_T size, const IDirectInputDevice8WVtbl *vtbl, const struct dinput_device_vtbl *internal_vtbl,
const GUID *guid, IDirectInputImpl *dinput, void **out )
{
IDirectInputDeviceImpl *This;
......@@ -1811,6 +1817,7 @@ HRESULT direct_input_device_alloc( SIZE_T size, const IDirectInputDevice8WVtbl *
InitializeCriticalSection( &This->crit );
This->dinput = dinput;
IDirectInput_AddRef( &dinput->IDirectInput7A_iface );
This->vtbl = internal_vtbl;
*out = This;
return DI_OK;
......
......@@ -55,6 +55,13 @@ typedef struct
typedef HRESULT dinput_device_read_state( IDirectInputDevice8W *iface );
struct dinput_device_vtbl
{
HRESULT (*read)(IDirectInputDevice8W *);
HRESULT (*acquire)(IDirectInputDevice8W *);
HRESULT (*unacquire)(IDirectInputDevice8W *);
};
/* Device implementation */
typedef struct IDirectInputDeviceImpl IDirectInputDeviceImpl;
struct IDirectInputDeviceImpl
......@@ -89,13 +96,13 @@ struct IDirectInputDeviceImpl
int num_actions; /* number of actions mapped */
ActionMap *action_map; /* array of mappings */
/* internal device file reading */
HANDLE read_event;
dinput_device_read_state *read_callback;
/* internal device callbacks */
HANDLE read_event;
const struct dinput_device_vtbl *vtbl;
};
extern HRESULT direct_input_device_alloc( SIZE_T size, const IDirectInputDevice8WVtbl *vtbl, const GUID *guid,
IDirectInputImpl *dinput, void **out ) DECLSPEC_HIDDEN;
extern HRESULT direct_input_device_alloc( SIZE_T size, const IDirectInputDevice8WVtbl *vtbl, const struct dinput_device_vtbl *internal_vtbl,
const GUID *guid, IDirectInputImpl *dinput, void **out ) DECLSPEC_HIDDEN;
extern const IDirectInputDevice8AVtbl dinput_device_a_vtbl DECLSPEC_HIDDEN;
extern BOOL get_app_key(HKEY*, HKEY*) DECLSPEC_HIDDEN;
......
......@@ -1308,7 +1308,7 @@ static DWORD WINAPI hook_thread_proc(void *param)
{
if (impl->read_event == events[ret])
{
hr = impl->read_callback( &impl->IDirectInputDevice8W_iface );
hr = impl->vtbl->read( &impl->IDirectInputDevice8W_iface );
if (FAILED(hr)) list_remove( &impl->entry );
break;
}
......@@ -1343,7 +1343,7 @@ static DWORD WINAPI hook_thread_proc(void *param)
mice_cnt = list_count( &acquired_mouse_list );
LIST_FOR_EACH_ENTRY( impl, &acquired_device_list, IDirectInputDeviceImpl, entry )
{
if (!impl->read_event || !impl->read_callback) continue;
if (!impl->read_event || !impl->vtbl->read) continue;
if (events_count >= ARRAY_SIZE(events)) break;
events[events_count++] = impl->read_event;
}
......
......@@ -916,83 +916,46 @@ static HRESULT WINAPI hid_joystick_SetProperty( IDirectInputDevice8W *iface, con
return DI_OK;
}
static HRESULT WINAPI hid_joystick_Acquire( IDirectInputDevice8W *iface )
static HRESULT hid_joystick_internal_acquire( IDirectInputDevice8W *iface )
{
struct hid_joystick *impl = impl_from_IDirectInputDevice8W( iface );
ULONG report_len = impl->caps.InputReportByteLength;
HRESULT hr = DI_OK;
BOOL ret;
TRACE( "iface %p.\n", iface );
EnterCriticalSection( &impl->base.crit );
if (impl->base.acquired)
hr = DI_NOEFFECT;
else if (!impl->base.data_format.user_df)
hr = DIERR_INVALIDPARAM;
else if ((impl->base.dwCoopLevel & DISCL_FOREGROUND) && impl->base.win != GetForegroundWindow())
hr = DIERR_OTHERAPPHASPRIO;
else if (impl->device == INVALID_HANDLE_VALUE)
if (impl->device == INVALID_HANDLE_VALUE)
{
impl->device = CreateFileW( impl->device_path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING, 0 );
if (impl->device == INVALID_HANDLE_VALUE) hr = DIERR_INPUTLOST;
if (impl->device == INVALID_HANDLE_VALUE) return DIERR_INPUTLOST;
}
if (hr == DI_OK)
memset( &impl->read_ovl, 0, sizeof(impl->read_ovl) );
impl->read_ovl.hEvent = impl->base.read_event;
ret = ReadFile( impl->device, impl->input_report_buf, report_len, NULL, &impl->read_ovl );
if (!ret && GetLastError() != ERROR_IO_PENDING)
{
memset( &impl->read_ovl, 0, sizeof(impl->read_ovl) );
impl->read_ovl.hEvent = impl->base.read_event;
ret = ReadFile( impl->device, impl->input_report_buf, report_len, NULL, &impl->read_ovl );
if (!ret && GetLastError() != ERROR_IO_PENDING)
{
CloseHandle( impl->device );
impl->device = INVALID_HANDLE_VALUE;
hr = DIERR_INPUTLOST;
}
else
{
impl->base.acquired = TRUE;
IDirectInputDevice8_SendForceFeedbackCommand( iface, DISFFC_RESET );
}
CloseHandle( impl->device );
impl->device = INVALID_HANDLE_VALUE;
return DIERR_INPUTLOST;
}
LeaveCriticalSection( &impl->base.crit );
if (hr != DI_OK) return hr;
dinput_hooks_acquire_device( iface );
check_dinput_hooks( iface, TRUE );
return hr;
IDirectInputDevice8_SendForceFeedbackCommand( iface, DISFFC_RESET );
return DI_OK;
}
static HRESULT WINAPI hid_joystick_Unacquire( IDirectInputDevice8W *iface )
static HRESULT hid_joystick_internal_unacquire( IDirectInputDevice8W *iface )
{
struct hid_joystick *impl = impl_from_IDirectInputDevice8W( iface );
HRESULT hr = DI_OK;
BOOL ret;
TRACE( "iface %p.\n", iface );
EnterCriticalSection( &impl->base.crit );
if (!impl->base.acquired) hr = DI_NOEFFECT;
else
{
if (impl->device != INVALID_HANDLE_VALUE)
{
ret = CancelIoEx( impl->device, &impl->read_ovl );
if (!ret) WARN( "CancelIoEx failed, last error %u\n", GetLastError() );
else WaitForSingleObject( impl->base.read_event, INFINITE );
}
IDirectInputDevice8_SendForceFeedbackCommand( iface, DISFFC_RESET );
impl->base.acquired = FALSE;
}
LeaveCriticalSection( &impl->base.crit );
if (hr != DI_OK) return hr;
if (impl->device == INVALID_HANDLE_VALUE) return DI_NOEFFECT;
dinput_hooks_unacquire_device( iface );
check_dinput_hooks( iface, FALSE );
ret = CancelIoEx( impl->device, &impl->read_ovl );
if (!ret) WARN( "CancelIoEx failed, last error %u\n", GetLastError() );
else WaitForSingleObject( impl->base.read_event, INFINITE );
return hr;
IDirectInputDevice8_SendForceFeedbackCommand( iface, DISFFC_RESET );
return DI_OK;
}
static HRESULT WINAPI hid_joystick_GetDeviceState( IDirectInputDevice8W *iface, DWORD len, void *ptr )
......@@ -1396,8 +1359,8 @@ static const IDirectInputDevice8WVtbl hid_joystick_vtbl =
hid_joystick_EnumObjects,
hid_joystick_GetProperty,
hid_joystick_SetProperty,
hid_joystick_Acquire,
hid_joystick_Unacquire,
IDirectInputDevice2WImpl_Acquire,
IDirectInputDevice2WImpl_Unacquire,
hid_joystick_GetDeviceState,
IDirectInputDevice2WImpl_GetDeviceData,
IDirectInputDevice2WImpl_SetDataFormat,
......@@ -1532,7 +1495,7 @@ static BOOL read_device_state_value( struct hid_joystick *impl, struct hid_value
return DIENUM_CONTINUE;
}
static HRESULT hid_joystick_read_state( IDirectInputDevice8W *iface )
static HRESULT hid_joystick_internal_read( IDirectInputDevice8W *iface )
{
static const DIPROPHEADER filter =
{
......@@ -1618,6 +1581,13 @@ static HRESULT hid_joystick_read_state( IDirectInputDevice8W *iface )
return hr;
}
static const struct dinput_device_vtbl hid_joystick_internal_vtbl =
{
hid_joystick_internal_read,
hid_joystick_internal_acquire,
hid_joystick_internal_unacquire,
};
static DWORD device_type_for_version( DWORD type, DWORD version )
{
if (version >= 0x0800) return type;
......@@ -2211,13 +2181,12 @@ static HRESULT hid_joystick_create_device( IDirectInputImpl *dinput, const GUID
else
return DIERR_DEVICENOTREG;
hr = direct_input_device_alloc( sizeof(struct hid_joystick), &hid_joystick_vtbl, guid,
dinput, (void **)&impl );
hr = direct_input_device_alloc( sizeof(struct hid_joystick), &hid_joystick_vtbl, &hid_joystick_internal_vtbl,
guid, dinput, (void **)&impl );
if (FAILED(hr)) return hr;
impl->base.crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": hid_joystick.base.crit");
impl->base.dwCoopLevel = DISCL_NONEXCLUSIVE | DISCL_BACKGROUND;
impl->base.read_event = CreateEventW( NULL, TRUE, FALSE, NULL );
impl->base.read_callback = hid_joystick_read_state;
hr = hid_joystick_device_open( -1, &instance, impl->device_path, &impl->device, &impl->preparsed,
&attrs, &impl->caps, dinput->dwVersion );
......
......@@ -37,6 +37,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(dinput);
#define WINE_DINPUT_KEYBOARD_MAX_KEYS 256
static const IDirectInputDevice8WVtbl SysKeyboardWvt;
static const struct dinput_device_vtbl keyboard_internal_vtbl;
typedef struct SysKeyboardImpl SysKeyboardImpl;
struct SysKeyboardImpl
......@@ -199,7 +200,8 @@ static HRESULT alloc_device( REFGUID rguid, IDirectInputImpl *dinput, SysKeyboar
int i, idx = 0;
HRESULT hr;
if (FAILED(hr = direct_input_device_alloc( sizeof(SysKeyboardImpl), &SysKeyboardWvt, rguid, dinput, (void **)&newDevice )))
if (FAILED(hr = direct_input_device_alloc( sizeof(SysKeyboardImpl), &SysKeyboardWvt, &keyboard_internal_vtbl,
rguid, dinput, (void **)&newDevice )))
return hr;
df = newDevice->base.data_format.wine_df;
newDevice->base.crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": SysKeyboardImpl*->base.crit");
......@@ -393,23 +395,25 @@ static HRESULT WINAPI SysKeyboardWImpl_GetProperty(LPDIRECTINPUTDEVICE8W iface,
return DI_OK;
}
static HRESULT WINAPI SysKeyboardWImpl_Acquire(LPDIRECTINPUTDEVICE8W iface)
static HRESULT keyboard_internal_acquire( IDirectInputDevice8W *iface )
{
SysKeyboardImpl *This = impl_from_IDirectInputDevice8W(iface);
HRESULT res;
TRACE("(%p)\n", This);
res = IDirectInputDevice2WImpl_Acquire(iface);
if (res == DI_OK)
{
TRACE("clearing keystate\n");
memset(This->DInputKeyState, 0, sizeof(This->DInputKeyState));
}
return DI_OK;
}
return res;
static HRESULT keyboard_internal_unacquire( IDirectInputDevice8W *iface )
{
SysKeyboardImpl *This = impl_from_IDirectInputDevice8W( iface );
memset( This->DInputKeyState, 0, sizeof(This->DInputKeyState) );
return DI_OK;
}
static const struct dinput_device_vtbl keyboard_internal_vtbl =
{
NULL,
keyboard_internal_acquire,
keyboard_internal_unacquire,
};
static const IDirectInputDevice8WVtbl SysKeyboardWvt =
{
IDirectInputDevice2WImpl_QueryInterface,
......@@ -419,7 +423,7 @@ static const IDirectInputDevice8WVtbl SysKeyboardWvt =
IDirectInputDevice2WImpl_EnumObjects,
SysKeyboardWImpl_GetProperty,
IDirectInputDevice2WImpl_SetProperty,
SysKeyboardWImpl_Acquire,
IDirectInputDevice2WImpl_Acquire,
IDirectInputDevice2WImpl_Unacquire,
SysKeyboardWImpl_GetDeviceState,
IDirectInputDevice2WImpl_GetDeviceData,
......
......@@ -44,6 +44,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(dinput);
#define WINE_MOUSE_BUTTONS_INSTANCE 3
static const IDirectInputDevice8WVtbl SysMouseWvt;
static const struct dinput_device_vtbl mouse_internal_vtbl;
typedef struct SysMouseImpl SysMouseImpl;
......@@ -143,7 +144,8 @@ static HRESULT alloc_device( REFGUID rguid, IDirectInputImpl *dinput, SysMouseIm
HKEY hkey, appkey;
HRESULT hr;
if (FAILED(hr = direct_input_device_alloc( sizeof(SysMouseImpl), &SysMouseWvt, rguid, dinput, (void **)&newDevice )))
if (FAILED(hr = direct_input_device_alloc( sizeof(SysMouseImpl), &SysMouseWvt, &mouse_internal_vtbl,
rguid, dinput, (void **)&newDevice )))
return hr;
df = newDevice->base.data_format.wine_df;
newDevice->base.crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": SysMouseImpl*->base.crit");
......@@ -462,7 +464,6 @@ static void warp_check( SysMouseImpl* This, BOOL force )
}
}
/******************************************************************************
* GetDeviceState : returns the "state" of the mouse.
*
......@@ -598,15 +599,10 @@ static HRESULT WINAPI SysMouseWImpl_GetObjectInfo(LPDIRECTINPUTDEVICE8W iface,
return res;
}
static HRESULT WINAPI SysMouseWImpl_Acquire( IDirectInputDevice8W *iface )
static HRESULT mouse_internal_acquire( IDirectInputDevice8W *iface )
{
SysMouseImpl *impl = impl_from_IDirectInputDevice8W( iface );
POINT point;
HRESULT res;
TRACE( "iface %p\n", iface );
if ((res = IDirectInputDevice2WImpl_Acquire( iface )) != DI_OK) return res;
/* Init the mouse state */
GetCursorPos( &point );
......@@ -646,14 +642,9 @@ static HRESULT WINAPI SysMouseWImpl_Acquire( IDirectInputDevice8W *iface )
return DI_OK;
}
static HRESULT WINAPI SysMouseWImpl_Unacquire( IDirectInputDevice8W *iface )
static HRESULT mouse_internal_unacquire( IDirectInputDevice8W *iface )
{
SysMouseImpl *impl = impl_from_IDirectInputDevice8W( iface );
HRESULT res;
TRACE( "iface %p\n", iface );
if ((res = IDirectInputDevice2WImpl_Unacquire( iface )) != DI_OK) return res;
if (impl->base.dwCoopLevel & DISCL_EXCLUSIVE)
{
......@@ -672,6 +663,13 @@ static HRESULT WINAPI SysMouseWImpl_Unacquire( IDirectInputDevice8W *iface )
return DI_OK;
}
static const struct dinput_device_vtbl mouse_internal_vtbl =
{
NULL,
mouse_internal_acquire,
mouse_internal_unacquire,
};
static const IDirectInputDevice8WVtbl SysMouseWvt =
{
IDirectInputDevice2WImpl_QueryInterface,
......@@ -681,8 +679,8 @@ static const IDirectInputDevice8WVtbl SysMouseWvt =
IDirectInputDevice2WImpl_EnumObjects,
SysMouseWImpl_GetProperty,
IDirectInputDevice2WImpl_SetProperty,
SysMouseWImpl_Acquire,
SysMouseWImpl_Unacquire,
IDirectInputDevice2WImpl_Acquire,
IDirectInputDevice2WImpl_Unacquire,
SysMouseWImpl_GetDeviceState,
SysMouseWImpl_GetDeviceData,
IDirectInputDevice2WImpl_SetDataFormat,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment