Commit 76a138c9 authored by Rémi Bernon's avatar Rémi Bernon Committed by Alexandre Julliard

dinput: Use SendMessageW to notify and stop input thread.

parent f3952a3e
...@@ -565,7 +565,6 @@ static HRESULT WINAPI dinput_device_Acquire( IDirectInputDevice8W *iface ) ...@@ -565,7 +565,6 @@ static HRESULT WINAPI dinput_device_Acquire( IDirectInputDevice8W *iface )
if (hr != DI_OK) return hr; if (hr != DI_OK) return hr;
dinput_hooks_acquire_device( iface ); dinput_hooks_acquire_device( iface );
check_dinput_hooks( iface, TRUE );
return hr; return hr;
} }
...@@ -585,7 +584,6 @@ static HRESULT WINAPI dinput_device_Unacquire( IDirectInputDevice8W *iface ) ...@@ -585,7 +584,6 @@ static HRESULT WINAPI dinput_device_Unacquire( IDirectInputDevice8W *iface )
if (hr != DI_OK) return hr; if (hr != DI_OK) return hr;
dinput_hooks_unacquire_device( iface ); dinput_hooks_unacquire_device( iface );
check_dinput_hooks( iface, FALSE );
return hr; return hr;
} }
......
...@@ -51,6 +51,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(dinput); ...@@ -51,6 +51,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(dinput);
struct input_thread_state struct input_thread_state
{ {
BOOL running;
UINT events_count; UINT events_count;
UINT devices_count; UINT devices_count;
HHOOK mouse_ll_hook; HHOOK mouse_ll_hook;
...@@ -69,10 +70,9 @@ static inline struct dinput_device *impl_from_IDirectInputDevice8W( IDirectInput ...@@ -69,10 +70,9 @@ static inline struct dinput_device *impl_from_IDirectInputDevice8W( IDirectInput
HINSTANCE DINPUT_instance; HINSTANCE DINPUT_instance;
static HWND di_em_win; static HWND di_em_win;
static HANDLE dinput_thread; static HANDLE dinput_thread;
static DWORD dinput_thread_id;
static UINT input_thread_user_count; static UINT input_thread_user_count;
static struct input_thread_state *input_thread_state;
static CRITICAL_SECTION dinput_hook_crit; static CRITICAL_SECTION dinput_hook_crit;
static CRITICAL_SECTION_DEBUG dinput_critsect_debug = static CRITICAL_SECTION_DEBUG dinput_critsect_debug =
...@@ -100,6 +100,8 @@ void dinput_hooks_acquire_device( IDirectInputDevice8W *iface ) ...@@ -100,6 +100,8 @@ void dinput_hooks_acquire_device( IDirectInputDevice8W *iface )
else else
list_add_tail( &acquired_device_list, &impl->entry ); list_add_tail( &acquired_device_list, &impl->entry );
LeaveCriticalSection( &dinput_hook_crit ); LeaveCriticalSection( &dinput_hook_crit );
SendMessageW( di_em_win, WM_USER + 0x10, 1, 0 );
} }
void dinput_hooks_unacquire_device( IDirectInputDevice8W *iface ) void dinput_hooks_unacquire_device( IDirectInputDevice8W *iface )
...@@ -109,6 +111,8 @@ void dinput_hooks_unacquire_device( IDirectInputDevice8W *iface ) ...@@ -109,6 +111,8 @@ void dinput_hooks_unacquire_device( IDirectInputDevice8W *iface )
EnterCriticalSection( &dinput_hook_crit ); EnterCriticalSection( &dinput_hook_crit );
list_remove( &impl->entry ); list_remove( &impl->entry );
LeaveCriticalSection( &dinput_hook_crit ); LeaveCriticalSection( &dinput_hook_crit );
SendMessageW( di_em_win, WM_USER + 0x10, 1, 0 );
} }
static void dinput_device_internal_unacquire( IDirectInputDevice8W *iface, DWORD status ) static void dinput_device_internal_unacquire( IDirectInputDevice8W *iface, DWORD status )
...@@ -298,6 +302,22 @@ static LRESULT WINAPI di_em_win_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPAR ...@@ -298,6 +302,22 @@ static LRESULT WINAPI di_em_win_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPAR
} }
} }
if (msg == WM_USER + 0x10)
{
struct input_thread_state *state = input_thread_state;
TRACE( "Processing hook change notification wparam %#Ix, lparam %#Ix.\n", wparam, lparam );
if (!wparam) state->running = FALSE;
else
{
while (state->devices_count--) dinput_device_internal_release( state->devices[state->devices_count] );
input_thread_update_device_list( state );
}
return 0;
}
return DefWindowProcW( hwnd, msg, wparam, lparam ); return DefWindowProcW( hwnd, msg, wparam, lparam );
} }
...@@ -323,19 +343,18 @@ static void unregister_di_em_win_class(void) ...@@ -323,19 +343,18 @@ static void unregister_di_em_win_class(void)
static DWORD WINAPI dinput_thread_proc( void *params ) static DWORD WINAPI dinput_thread_proc( void *params )
{ {
struct input_thread_state state = {0}; struct input_thread_state state = {.running = TRUE};
struct dinput_device *device; struct dinput_device *device;
HANDLE start_event = params; HANDLE start_event = params;
DWORD ret; DWORD ret;
MSG msg; MSG msg;
input_thread_state = &state;
di_em_win = CreateWindowW( L"DIEmWin", L"DIEmWin", 0, 0, 0, 0, 0, HWND_MESSAGE, 0, DINPUT_instance, NULL ); di_em_win = CreateWindowW( L"DIEmWin", L"DIEmWin", 0, 0, 0, 0, 0, HWND_MESSAGE, 0, DINPUT_instance, NULL );
/* Force creation of the message queue */
PeekMessageW( &msg, 0, 0, 0, PM_NOREMOVE ); PeekMessageW( &msg, 0, 0, 0, PM_NOREMOVE );
SetEvent( start_event ); SetEvent( start_event );
while ((ret = MsgWaitForMultipleObjectsEx( state.events_count, state.events, INFINITE, QS_ALLINPUT, 0 )) <= state.events_count) while (state.running && (ret = MsgWaitForMultipleObjectsEx( state.events_count, state.events, INFINITE, QS_ALLINPUT, 0 )) <= state.events_count)
{ {
if (ret < state.events_count) if (ret < state.events_count)
{ {
...@@ -354,27 +373,17 @@ static DWORD WINAPI dinput_thread_proc( void *params ) ...@@ -354,27 +373,17 @@ static DWORD WINAPI dinput_thread_proc( void *params )
while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE ))
{ {
if (msg.message != WM_USER+0x10) TranslateMessage(&msg);
{ DispatchMessageW(&msg);
TranslateMessage(&msg);
DispatchMessageW(&msg);
continue;
}
TRACE( "Processing hook change notification wparam %#Ix, lparam %#Ix.\n", msg.wParam, msg.lParam );
if (!msg.wParam) goto done;
while (state.devices_count--) dinput_device_internal_release( state.devices[state.devices_count] );
input_thread_update_device_list( &state );
SetEvent( (HANDLE)msg.lParam );
} }
} }
ERR( "Unexpected termination, ret %#lx\n", ret ); if (state.running)
dinput_unacquire_window_devices( 0 ); {
ERR( "Unexpected termination, ret %#lx\n", ret );
dinput_unacquire_window_devices( 0 );
}
done:
while (state.devices_count--) dinput_device_internal_release( state.devices[state.devices_count] ); while (state.devices_count--) dinput_device_internal_release( state.devices[state.devices_count] );
if (state.callwndproc_hook) UnhookWindowsHookEx( state.callwndproc_hook ); if (state.callwndproc_hook) UnhookWindowsHookEx( state.callwndproc_hook );
if (state.keyboard_ll_hook) UnhookWindowsHookEx( state.keyboard_ll_hook ); if (state.keyboard_ll_hook) UnhookWindowsHookEx( state.keyboard_ll_hook );
...@@ -395,7 +404,7 @@ void input_thread_add_user(void) ...@@ -395,7 +404,7 @@ void input_thread_add_user(void)
if (!(start_event = CreateEventW( NULL, FALSE, FALSE, NULL ))) if (!(start_event = CreateEventW( NULL, FALSE, FALSE, NULL )))
ERR( "Failed to create start event, error %lu\n", GetLastError() ); ERR( "Failed to create start event, error %lu\n", GetLastError() );
else if (!(dinput_thread = CreateThread( NULL, 0, dinput_thread_proc, start_event, 0, &dinput_thread_id ))) else if (!(dinput_thread = CreateThread( NULL, 0, dinput_thread_proc, start_event, 0, NULL )))
ERR( "Failed to create internal thread, error %lu\n", GetLastError() ); ERR( "Failed to create internal thread, error %lu\n", GetLastError() );
else else
WaitForSingleObject( start_event, INFINITE ); WaitForSingleObject( start_event, INFINITE );
...@@ -412,28 +421,13 @@ void input_thread_remove_user(void) ...@@ -412,28 +421,13 @@ void input_thread_remove_user(void)
{ {
TRACE( "Stopping input thread.\n" ); TRACE( "Stopping input thread.\n" );
PostThreadMessageW( dinput_thread_id, WM_USER + 0x10, 0, 0 ); SendMessageW( di_em_win, WM_USER + 0x10, 0, 0 );
WaitForSingleObject( dinput_thread, INFINITE ); WaitForSingleObject( dinput_thread, INFINITE );
CloseHandle( dinput_thread ); CloseHandle( dinput_thread );
} }
LeaveCriticalSection( &dinput_hook_crit ); LeaveCriticalSection( &dinput_hook_crit );
} }
void check_dinput_hooks( IDirectInputDevice8W *iface, BOOL acquired )
{
HANDLE hook_change_finished_event = NULL;
EnterCriticalSection(&dinput_hook_crit);
hook_change_finished_event = CreateEventW( NULL, FALSE, FALSE, NULL );
PostThreadMessageW( dinput_thread_id, WM_USER + 0x10, 1, (LPARAM)hook_change_finished_event );
LeaveCriticalSection(&dinput_hook_crit);
WaitForSingleObject(hook_change_finished_event, INFINITE);
CloseHandle(hook_change_finished_event);
}
void check_dinput_events(void) void check_dinput_events(void)
{ {
/* Windows does not do that, but our current implementation of winex11 /* Windows does not do that, but our current implementation of winex11
......
...@@ -73,7 +73,6 @@ extern int dinput_keyboard_hook( IDirectInputDevice8W *iface, WPARAM wparam, LPA ...@@ -73,7 +73,6 @@ extern int dinput_keyboard_hook( IDirectInputDevice8W *iface, WPARAM wparam, LPA
extern void dinput_mouse_rawinput_hook( IDirectInputDevice8W *iface, WPARAM wparam, LPARAM lparam, extern void dinput_mouse_rawinput_hook( IDirectInputDevice8W *iface, WPARAM wparam, LPARAM lparam,
RAWINPUT *raw ); RAWINPUT *raw );
extern void check_dinput_hooks( IDirectInputDevice8W *iface, BOOL acquired ) DECLSPEC_HIDDEN;
extern void check_dinput_events(void) DECLSPEC_HIDDEN; extern void check_dinput_events(void) DECLSPEC_HIDDEN;
extern HRESULT _configure_devices(IDirectInput8W *iface, LPDICONFIGUREDEVICESCALLBACK lpdiCallback, LPDICONFIGUREDEVICESPARAMSW lpdiCDParams, DWORD dwFlags, LPVOID pvRefData) DECLSPEC_HIDDEN; extern HRESULT _configure_devices(IDirectInput8W *iface, LPDICONFIGUREDEVICESCALLBACK lpdiCallback, LPDICONFIGUREDEVICESPARAMSW lpdiCDParams, DWORD dwFlags, LPVOID pvRefData) DECLSPEC_HIDDEN;
......
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