[PATCH 6/9] dinput: Factor all (Un)Acquire implementations together.

Rémi Bernon rbernon at codeweavers.com
Wed Oct 13 02:21:17 CDT 2021


And introduce new internal acquire / unacquire callbacks.

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/dinput/device.c         | 65 ++++++++++++++-----------
 dlls/dinput/device_private.h | 17 +++++--
 dlls/dinput/dinput_main.c    |  4 +-
 dlls/dinput/joystick_hid.c   | 93 ++++++++++++------------------------
 dlls/dinput/keyboard.c       | 34 +++++++------
 dlls/dinput/mouse.c          | 30 ++++++------
 6 files changed, 114 insertions(+), 129 deletions(-)

diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c
index 0f649ec59e8..8f57d32dee2 100644
--- a/dlls/dinput/device.c
+++ b/dlls/dinput/device.c
@@ -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;
diff --git a/dlls/dinput/device_private.h b/dlls/dinput/device_private.h
index d61a0a3e6e8..7ae040744cb 100644
--- a/dlls/dinput/device_private.h
+++ b/dlls/dinput/device_private.h
@@ -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;
diff --git a/dlls/dinput/dinput_main.c b/dlls/dinput/dinput_main.c
index bc35d6d77b3..329cb738469 100644
--- a/dlls/dinput/dinput_main.c
+++ b/dlls/dinput/dinput_main.c
@@ -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;
             }
diff --git a/dlls/dinput/joystick_hid.c b/dlls/dinput/joystick_hid.c
index 13083a6ac77..6454a4b7fd1 100644
--- a/dlls/dinput/joystick_hid.c
+++ b/dlls/dinput/joystick_hid.c
@@ -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 );
diff --git a/dlls/dinput/keyboard.c b/dlls/dinput/keyboard.c
index c367162164a..138b8439374 100644
--- a/dlls/dinput/keyboard.c
+++ b/dlls/dinput/keyboard.c
@@ -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,
diff --git a/dlls/dinput/mouse.c b/dlls/dinput/mouse.c
index c1992a8557f..20a4ab9af40 100644
--- a/dlls/dinput/mouse.c
+++ b/dlls/dinput/mouse.c
@@ -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,
-- 
2.33.0




More information about the wine-devel mailing list