From: Rémi Bernon rbernon@codeweavers.com
Based on a patch by Huw Davies huw@codeweavers.com. --- dlls/win32u/hook.c | 2 -- dlls/win32u/input.c | 44 +++++++++--------------------------- dlls/win32u/message.c | 16 +++---------- dlls/win32u/ntuser_private.h | 8 ------- dlls/win32u/sysparams.c | 2 -- dlls/win32u/win32u_private.h | 1 - dlls/win32u/winstation.c | 2 -- 7 files changed, 14 insertions(+), 61 deletions(-)
diff --git a/dlls/win32u/hook.c b/dlls/win32u/hook.c index fab2b960fa5..eca9e7d6ce9 100644 --- a/dlls/win32u/hook.c +++ b/dlls/win32u/hook.c @@ -345,8 +345,6 @@ static LRESULT call_hook( struct win_hook_params *info, const WCHAR *module, siz if (params != info) free( params ); }
- if (info->id == WH_KEYBOARD_LL || info->id == WH_MOUSE_LL) - InterlockedIncrement( &global_key_state_counter ); /* force refreshing the key state cache */ return ret; }
diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c index 4d0c2589c1b..a582826d18e 100644 --- a/dlls/win32u/input.c +++ b/dlls/win32u/input.c @@ -406,7 +406,6 @@ static const KBDTABLES kbdus_tables =
static LONG clipping_cursor; /* clipping thread counter */
-LONG global_key_state_counter = 0; BOOL grab_pointer = TRUE; BOOL grab_fullscreen = FALSE;
@@ -810,52 +809,31 @@ static void check_for_events( UINT flags ) */ SHORT WINAPI NtUserGetAsyncKeyState( INT key ) { - struct user_key_state_info *key_state_info = get_user_thread_info()->key_state; - INT counter = global_key_state_counter; - BYTE prev_key_state; - SHORT ret; + const desktop_shm_t *desktop_shm; + struct object_lock lock = OBJECT_LOCK_INIT; + NTSTATUS status; + BYTE state = 0; + SHORT ret = 0;
if (key < 0 || key >= 256) return 0;
check_for_events( QS_INPUT );
- if (key_state_info && !(key_state_info->state[key] & 0xc0) && - key_state_info->counter == counter && NtGetTickCount() - key_state_info->time < 50) - { - /* use cached value */ - return 0; - } - else if (!key_state_info) - { - key_state_info = calloc( 1, sizeof(*key_state_info) ); - get_user_thread_info()->key_state = key_state_info; - } + while ((status = get_shared_desktop( &lock, &desktop_shm )) == STATUS_PENDING) + state = desktop_shm->keystate[key];
- ret = 0; + if (status) return 0; + if (!(state & 0x40)) return (state & 0x80) << 8; + + /* Need to make a server call to reset the last pressed bit */ SERVER_START_REQ( get_key_state ) { req->async = 1; req->key = key; - if (key_state_info) - { - prev_key_state = key_state_info->state[key]; - wine_server_set_reply( req, key_state_info->state, sizeof(key_state_info->state) ); - } if (!wine_server_call( req )) { if (reply->state & 0x40) ret |= 0x0001; if (reply->state & 0x80) ret |= 0x8000; - if (key_state_info) - { - /* force refreshing the key state cache - some multithreaded programs - * (like Adobe Photoshop CS5) expect that changes to the async key state - * are also immediately available in other threads. */ - if (prev_key_state != key_state_info->state[key]) - counter = InterlockedIncrement( &global_key_state_counter ); - - key_state_info->time = NtGetTickCount(); - key_state_info->counter = counter; - } } } SERVER_END_REQ; diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index d1f49ca3ed9..b7062414658 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -3469,7 +3469,7 @@ NTSTATUS send_hardware_message( HWND hwnd, UINT flags, const INPUT *input, LPARA struct send_message_info info; int prev_x, prev_y, new_x, new_y; NTSTATUS ret; - BOOL wait, affects_key_state = FALSE; + BOOL wait;
info.type = MSG_HARDWARE; info.dest_tid = 0; @@ -3495,10 +3495,6 @@ NTSTATUS send_hardware_message( HWND hwnd, UINT flags, const INPUT *input, LPARA req->input.mouse.flags = input->mi.dwFlags; req->input.mouse.time = input->mi.time; req->input.mouse.info = input->mi.dwExtraInfo; - affects_key_state = !!(input->mi.dwFlags & (MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP | - MOUSEEVENTF_RIGHTDOWN | MOUSEEVENTF_RIGHTUP | - MOUSEEVENTF_MIDDLEDOWN | MOUSEEVENTF_MIDDLEUP | - MOUSEEVENTF_XDOWN | MOUSEEVENTF_XUP)); break; case INPUT_KEYBOARD: if (input->ki.dwFlags & KEYEVENTF_SCANCODE) @@ -3523,7 +3519,6 @@ NTSTATUS send_hardware_message( HWND hwnd, UINT flags, const INPUT *input, LPARA req->input.kbd.flags = input->ki.dwFlags & ~KEYEVENTF_SCANCODE; req->input.kbd.time = input->ki.time; req->input.kbd.info = input->ki.dwExtraInfo; - affects_key_state = TRUE; break; case INPUT_HARDWARE: req->input.hw.msg = input->hi.uMsg; @@ -3553,13 +3548,8 @@ NTSTATUS send_hardware_message( HWND hwnd, UINT flags, const INPUT *input, LPARA } SERVER_END_REQ;
- if (!ret) - { - if (affects_key_state) - InterlockedIncrement( &global_key_state_counter ); /* force refreshing the key state cache */ - if ((flags & SEND_HWMSG_INJECTED) && (prev_x != new_x || prev_y != new_y)) - user_driver->pSetCursorPos( new_x, new_y ); - } + if (!ret && (flags & SEND_HWMSG_INJECTED) && (prev_x != new_x || prev_y != new_y)) + user_driver->pSetCursorPos( new_x, new_y );
if (wait) { diff --git a/dlls/win32u/ntuser_private.h b/dlls/win32u/ntuser_private.h index 39943e2261b..d95ea03d45f 100644 --- a/dlls/win32u/ntuser_private.h +++ b/dlls/win32u/ntuser_private.h @@ -116,7 +116,6 @@ struct user_thread_info HHOOK hook; /* Current hook */ UINT active_hooks; /* Bitmap of active hooks */ struct received_message_info *receive_info; /* Message being currently received */ - struct user_key_state_info *key_state; /* Cache of global key state */ struct imm_thread_data *imm_thread_data; /* IMM thread data */ HKL kbd_layout; /* Current keyboard layout */ UINT kbd_layout_id; /* Current keyboard layout ID */ @@ -134,13 +133,6 @@ static inline struct user_thread_info *get_user_thread_info(void) return CONTAINING_RECORD( NtUserGetThreadInfo(), struct user_thread_info, client_info ); }
-struct user_key_state_info -{ - UINT time; /* Time of last key state refresh */ - INT counter; /* Counter to invalidate the key state */ - BYTE state[256]; /* State for each key */ -}; - struct hook_extra_info { HHOOK handle; diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 34de10168e2..9a06db2c7f6 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -6334,8 +6334,6 @@ static void thread_detach(void) destroy_thread_windows(); user_driver->pThreadDetach();
- free( thread_info->key_state ); - thread_info->key_state = 0; free( thread_info->rawinput );
cleanup_imm_thread(); diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index f7ba2c1a423..e2e35d6c40d 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -90,7 +90,6 @@ extern void unregister_imm_window( HWND hwnd ); extern BOOL grab_pointer; extern BOOL grab_fullscreen; extern BOOL destroy_caret(void); -extern LONG global_key_state_counter; extern HWND get_active_window(void); extern HWND get_capture(void); extern BOOL get_cursor_pos( POINT *pt ); diff --git a/dlls/win32u/winstation.c b/dlls/win32u/winstation.c index 7168a614735..1676539c69c 100644 --- a/dlls/win32u/winstation.c +++ b/dlls/win32u/winstation.c @@ -441,11 +441,9 @@ BOOL WINAPI NtUserSetThreadDesktop( HDESK handle ) if (ret) /* reset the desktop windows */ { struct user_thread_info *thread_info = get_user_thread_info(); - struct user_key_state_info *key_state_info = thread_info->key_state; get_session_thread_data()->shared_desktop = find_shared_session_object( locator ); thread_info->client_info.top_window = 0; thread_info->client_info.msg_window = 0; - if (key_state_info) key_state_info->time = 0; if (was_virtual_desktop != is_virtual_desktop()) update_display_cache( FALSE ); } return ret;