Sebastian Lackner : user32: Invalidate key state cache globally after running LL hooks.

Alexandre Julliard julliard at wine.codeweavers.com
Tue Apr 7 10:11:28 CDT 2015


Module: wine
Branch: master
Commit: d3be42ab96cf8925bb2abd5c26b8ffa67c8b910c
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=d3be42ab96cf8925bb2abd5c26b8ffa67c8b910c

Author: Sebastian Lackner <sebastian at fds-team.de>
Date:   Tue Apr  7 02:53:06 2015 +0200

user32: Invalidate key state cache globally after running LL hooks.

---

 dlls/user32/hook.c         | 5 +----
 dlls/user32/input.c        | 9 ++++++++-
 dlls/user32/message.c      | 7 ++++++-
 dlls/user32/user_private.h | 3 +++
 4 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/dlls/user32/hook.c b/dlls/user32/hook.c
index f19949c..281b88e 100644
--- a/dlls/user32/hook.c
+++ b/dlls/user32/hook.c
@@ -437,10 +437,7 @@ static LRESULT call_hook( struct hook_info *info, INT code, WPARAM wparam, LPARA
     }
 
     if (info->id == WH_KEYBOARD_LL || info->id == WH_MOUSE_LL)
-    {
-        struct user_key_state_info *key_state_info = get_user_thread_info()->key_state;
-        if (key_state_info) key_state_info->time = 0;  /* force refreshing the key state cache */
-    }
+        interlocked_xchg_add( &global_key_state_counter, 1 );  /* force refreshing the key state cache */
 
     return ret;
 }
diff --git a/dlls/user32/input.c b/dlls/user32/input.c
index 6ea2c2f..57594a7 100644
--- a/dlls/user32/input.c
+++ b/dlls/user32/input.c
@@ -52,6 +52,7 @@
 WINE_DEFAULT_DEBUG_CHANNEL(win);
 WINE_DECLARE_DEBUG_CHANNEL(keyboard);
 
+INT global_key_state_counter = 0;
 
 /***********************************************************************
  *           get_key_state
@@ -369,6 +370,7 @@ static void check_for_events( UINT flags )
 SHORT WINAPI DECLSPEC_HOTPATCH GetAsyncKeyState( INT key )
 {
     struct user_key_state_info *key_state_info = get_user_thread_info()->key_state;
+    INT counter = global_key_state_counter;
     SHORT ret;
 
     if (key < 0 || key >= 256) return 0;
@@ -379,6 +381,7 @@ SHORT WINAPI DECLSPEC_HOTPATCH GetAsyncKeyState( INT key )
     {
         if (key_state_info &&
             !(key_state_info->state[key] & 0xc0) &&
+            key_state_info->counter == counter &&
             GetTickCount() - key_state_info->time < 50)
         {
             /* use cached value */
@@ -401,7 +404,11 @@ SHORT WINAPI DECLSPEC_HOTPATCH GetAsyncKeyState( INT key )
             {
                 if (reply->state & 0x40) ret |= 0x0001;
                 if (reply->state & 0x80) ret |= 0x8000;
-                if (key_state_info) key_state_info->time = GetTickCount();
+                if (key_state_info)
+                {
+                    key_state_info->time    = GetTickCount();
+                    key_state_info->counter = counter;
+                }
             }
         }
         SERVER_END_REQ;
diff --git a/dlls/user32/message.c b/dlls/user32/message.c
index fbc11da..2b544de 100644
--- a/dlls/user32/message.c
+++ b/dlls/user32/message.c
@@ -3293,6 +3293,7 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, UINT flags )
     struct user_key_state_info *key_state_info = get_user_thread_info()->key_state;
     struct send_message_info info;
     int prev_x, prev_y, new_x, new_y;
+    INT counter = global_key_state_counter;
     NTSTATUS ret;
     BOOL wait;
 
@@ -3342,7 +3343,11 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, UINT flags )
 
     if (!ret)
     {
-        if (key_state_info) key_state_info->time = GetTickCount();
+        if (key_state_info)
+        {
+            key_state_info->time    = GetTickCount();
+            key_state_info->counter = counter;
+        }
         if ((flags & SEND_HWMSG_INJECTED) && (prev_x != new_x || prev_y != new_y))
             USER_Driver->pSetCursorPos( new_x, new_y );
     }
diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h
index 9e3a373..445fd40 100644
--- a/dlls/user32/user_private.h
+++ b/dlls/user32/user_private.h
@@ -192,9 +192,12 @@ struct user_thread_info
 
 C_ASSERT( sizeof(struct user_thread_info) <= sizeof(((TEB *)0)->Win32ClientInfo) );
 
+extern INT global_key_state_counter DECLSPEC_HIDDEN;
+
 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 */
 };
 




More information about the wine-cvs mailing list