mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-14 11:12:47 +00:00
dinput: Hook window threads instead of the entire prefix.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=54431
This commit is contained in:
parent
7a2d59fb24
commit
e5c540c59b
|
@ -95,6 +95,7 @@ struct dinput_device
|
|||
HWND win;
|
||||
enum device_status status;
|
||||
BOOL use_raw_input; /* use raw input instead of low-level messages */
|
||||
HHOOK cbt_hook; /* CBT hook to track foreground changes */
|
||||
|
||||
LPDIDEVICEOBJECTDATA data_queue; /* buffer for 'GetDeviceData'. */
|
||||
int queue_len; /* valid size of the queue */
|
||||
|
|
|
@ -61,7 +61,6 @@ struct input_thread_state
|
|||
UINT devices_count;
|
||||
HHOOK mouse_ll_hook;
|
||||
HHOOK keyboard_ll_hook;
|
||||
HHOOK callwndproc_hook;
|
||||
RAWINPUTDEVICE rawinput_devices[2];
|
||||
struct dinput_device *devices[INPUT_THREAD_MAX_DEVICES];
|
||||
HANDLE events[INPUT_THREAD_MAX_DEVICES];
|
||||
|
@ -112,12 +111,21 @@ void dinput_hooks_unacquire_device( IDirectInputDevice8W *iface )
|
|||
SendMessageW( di_em_win, INPUT_THREAD_NOTIFY, NOTIFY_REFRESH_DEVICES, 0 );
|
||||
}
|
||||
|
||||
static void unhook_device_window_foreground_changes( struct dinput_device *device )
|
||||
{
|
||||
if (!device->cbt_hook) return;
|
||||
UnhookWindowsHookEx( device->cbt_hook );
|
||||
device->cbt_hook = NULL;
|
||||
}
|
||||
|
||||
static void dinput_device_internal_unacquire( IDirectInputDevice8W *iface, DWORD status )
|
||||
{
|
||||
struct dinput_device *impl = impl_from_IDirectInputDevice8W( iface );
|
||||
|
||||
TRACE( "iface %p.\n", iface );
|
||||
|
||||
unhook_device_window_foreground_changes( impl );
|
||||
|
||||
EnterCriticalSection( &impl->crit );
|
||||
if (impl->status == STATUS_ACQUIRED)
|
||||
{
|
||||
|
@ -198,17 +206,26 @@ static LRESULT CALLBACK cbt_hook_proc( int code, WPARAM wparam, LPARAM lparam )
|
|||
return CallNextHookEx( 0, code, wparam, lparam );
|
||||
}
|
||||
|
||||
static void hook_device_window_foreground_changes( struct dinput_device *device )
|
||||
{
|
||||
DWORD tid, pid;
|
||||
if (!(tid = GetWindowThreadProcessId( device->win, &pid ))) return;
|
||||
device->cbt_hook = SetWindowsHookExW( WH_CBT, cbt_hook_proc, DINPUT_instance, tid );
|
||||
}
|
||||
|
||||
static void input_thread_update_device_list( struct input_thread_state *state )
|
||||
{
|
||||
RAWINPUTDEVICE rawinput_keyboard = {.usUsagePage = HID_USAGE_PAGE_GENERIC, .usUsage = HID_USAGE_GENERIC_KEYBOARD, .dwFlags = RIDEV_REMOVE};
|
||||
RAWINPUTDEVICE rawinput_mouse = {.usUsagePage = HID_USAGE_PAGE_GENERIC, .usUsage = HID_USAGE_GENERIC_MOUSE, .dwFlags = RIDEV_REMOVE};
|
||||
UINT count = 0, keyboard_ll_count = 0, mouse_ll_count = 0, foreground_count = 0;
|
||||
UINT count = 0, keyboard_ll_count = 0, mouse_ll_count = 0;
|
||||
struct dinput_device *device;
|
||||
|
||||
EnterCriticalSection( &dinput_hook_crit );
|
||||
LIST_FOR_EACH_ENTRY( device, &acquired_device_list, struct dinput_device, entry )
|
||||
{
|
||||
if (device->dwCoopLevel & DISCL_FOREGROUND) foreground_count++;
|
||||
unhook_device_window_foreground_changes( device );
|
||||
if (device->dwCoopLevel & DISCL_FOREGROUND) hook_device_window_foreground_changes( device );
|
||||
|
||||
if (!device->read_event || !device->vtbl->read) continue;
|
||||
state->events[count] = device->read_event;
|
||||
dinput_device_internal_addref( (state->devices[count] = device) );
|
||||
|
@ -250,14 +267,6 @@ static void input_thread_update_device_list( struct input_thread_state *state )
|
|||
state->devices_count = count;
|
||||
LeaveCriticalSection( &dinput_hook_crit );
|
||||
|
||||
if (foreground_count && !state->callwndproc_hook)
|
||||
state->callwndproc_hook = SetWindowsHookExW( WH_CBT, cbt_hook_proc, DINPUT_instance, 0 );
|
||||
else if (!foreground_count && state->callwndproc_hook)
|
||||
{
|
||||
UnhookWindowsHookEx( state->callwndproc_hook );
|
||||
state->callwndproc_hook = NULL;
|
||||
}
|
||||
|
||||
if (keyboard_ll_count && !state->keyboard_ll_hook)
|
||||
state->keyboard_ll_hook = SetWindowsHookExW( WH_KEYBOARD_LL, input_thread_ll_hook_proc, DINPUT_instance, 0 );
|
||||
else if (!keyboard_ll_count && state->keyboard_ll_hook)
|
||||
|
@ -413,7 +422,6 @@ static DWORD WINAPI dinput_thread_proc( void *params )
|
|||
}
|
||||
|
||||
while (state.devices_count--) dinput_device_internal_release( state.devices[state.devices_count] );
|
||||
if (state.callwndproc_hook) UnhookWindowsHookEx( state.callwndproc_hook );
|
||||
if (state.keyboard_ll_hook) UnhookWindowsHookEx( state.keyboard_ll_hook );
|
||||
if (state.mouse_ll_hook) UnhookWindowsHookEx( state.mouse_ll_hook );
|
||||
DestroyWindow( di_em_win );
|
||||
|
|
Loading…
Reference in a new issue