Sebastian Lackner : user32: Globally invalidate key state on changes in other threads.

Alexandre Julliard julliard at winehq.org
Sun Mar 18 09:02:32 CDT 2018


Module: wine
Branch: oldstable
Commit: cacd11edc1e20011f3641681f28044a82d693669
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=cacd11edc1e20011f3641681f28044a82d693669

Author: Sebastian Lackner <sebastian at fds-team.de>
Date:   Mon Dec 18 16:20:58 2017 +0100

user32: Globally invalidate key state on changes in other threads.

Signed-off-by: Alexandre Julliard <julliard at winehq.org>
(cherry picked from commit 059d5ece23265e003ab413aa711e963da9c0564e)
Signed-off-by: Michael Stefaniuc <mstefani at winehq.org>

---

 dlls/user32/input.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/dlls/user32/input.c b/dlls/user32/input.c
index 44b7e70..bc62f87 100644
--- a/dlls/user32/input.c
+++ b/dlls/user32/input.c
@@ -371,6 +371,7 @@ 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;
+    BYTE prev_key_state;
     SHORT ret;
 
     if (key < 0 || key >= 256) return 0;
@@ -398,14 +399,23 @@ SHORT WINAPI DECLSPEC_HOTPATCH GetAsyncKeyState( INT key )
         {
             req->tid = 0;
             req->key = key;
-            if (key_state_info) wine_server_set_reply( req, key_state_info->state,
-                                                       sizeof(key_state_info->state) );
+            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 = interlocked_xchg_add( &global_key_state_counter, 1 ) + 1;
+
                     key_state_info->time    = GetTickCount();
                     key_state_info->counter = counter;
                 }




More information about the wine-cvs mailing list