From 724857c412533e99901443e26717a9ba1981837f Mon Sep 17 00:00:00 2001
From: Rafal Milecki <zajec5@gmail.com>
Date: Wed, 7 May 2008 20:33:24 +0200
Subject: [PATCH] This adds BYTE global_key_state_table[256] variable to wineserver and makes use of it in keyboard.c. Also adding two new entries to wineserver protocol were needed.

---
 dlls/winex11.drv/keyboard.c    |   49 ++++++++++++++++++++++++++++++++++++++-
 include/wine/server_protocol.h |   32 +++++++++++++++++++++++++-
 server/protocol.def            |   13 ++++++++++
 server/queue.c                 |   17 ++++++++++++++
 server/trace.c                 |   22 ++++++++++++++++++
 tools/make_requests            |    1 +
 6 files changed, 131 insertions(+), 3 deletions(-)

diff --git a/dlls/winex11.drv/keyboard.c b/dlls/winex11.drv/keyboard.c
index 981e4df..6ff4fcf 100644
--- a/dlls/winex11.drv/keyboard.c
+++ b/dlls/winex11.drv/keyboard.c
@@ -1207,12 +1207,40 @@ void X11DRV_send_keyboard_input( WORD wVk, WORD wScan, DWORD event_flags, DWORD
     {
         key_state_table[wVk] &= ~0x80;
         key_state_table[wVkStripped] = key_state_table[wVkL] | key_state_table[wVkR];
+        SERVER_START_REQ( set_global_key_state )
+        {
+            req->key      = wVk;
+            req->value    = key_state_table[wVk];
+            wine_server_call( req );
+        }
+        SERVER_END_REQ;
+        SERVER_START_REQ( set_global_key_state )
+        {
+            req->key      = wVkStripped;
+            req->value    = key_state_table[wVkStripped];
+            wine_server_call( req );
+        }
+        SERVER_END_REQ;
     }
     else
     {
         if (!(key_state_table[wVk] & 0x80)) key_state_table[wVk] ^= 0x01;
         key_state_table[wVk] |= 0xc0;
         key_state_table[wVkStripped] = key_state_table[wVkL] | key_state_table[wVkR];
+        SERVER_START_REQ( set_global_key_state )
+        {
+            req->key      = wVk;
+            req->value    = key_state_table[wVk];
+            wine_server_call( req );
+        }
+        SERVER_END_REQ;
+        SERVER_START_REQ( set_global_key_state )
+        {
+            req->key      = wVkStripped;
+            req->value    = key_state_table[wVkStripped];
+            wine_server_call( req );
+        }
+        SERVER_END_REQ;
     }
 
     if (key_state_table[VK_MENU] & 0x80) flags |= KF_ALTDOWN;
@@ -1788,9 +1816,26 @@ SHORT X11DRV_GetAsyncKeyState(INT key)
     /* Photoshop livelocks unless mouse events are included here */
     X11DRV_MsgWaitForMultipleObjectsEx( 0, NULL, 0, QS_KEY | QS_MOUSE, 0 );
 
-    retval = ((key_state_table[key] & 0x40) ? 0x0001 : 0) |
-             ((key_state_table[key] & 0x80) ? 0x8000 : 0);
+    BOOL ret;
+    BYTE state;
+    SERVER_START_REQ( get_global_key_state )
+    {
+        req->key = key;
+        ret = !wine_server_call_err( req );
+        state = reply->value;
+    }
+    SERVER_END_REQ;
+
+    retval = ((state & 0x40) ? 0x0001 : 0) |
+             ((state & 0x80) ? 0x8000 : 0);
     key_state_table[key] &= ~0x40;
+    SERVER_START_REQ( set_global_key_state )
+    {
+        req->key      = key;
+        req->value    = key_state_table[key];
+        wine_server_call( req );
+    }
+    SERVER_END_REQ;
     TRACE_(key)("(%x) -> %x\n", key, retval);
     return retval;
 }
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index 810464c..fc5f85e 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -3455,6 +3455,30 @@ struct set_key_state_reply
 };
 
 
+struct get_global_key_state_request
+{
+    struct request_header __header;
+    int            key;
+};
+struct get_global_key_state_reply
+{
+    struct reply_header __header;
+    BYTE           value;
+};
+
+
+struct set_global_key_state_request
+{
+    struct request_header __header;
+    int            key;
+    BYTE           value;
+};
+struct set_global_key_state_reply
+{
+    struct reply_header __header;
+};
+
+
 struct set_foreground_window_request
 {
     struct request_header __header;
@@ -4466,6 +4490,8 @@ enum request
     REQ_get_last_input_time,
     REQ_get_key_state,
     REQ_set_key_state,
+    REQ_get_global_key_state,
+    REQ_set_global_key_state,
     REQ_set_foreground_window,
     REQ_set_focus_window,
     REQ_set_active_window,
@@ -4706,6 +4732,8 @@ union generic_request
     struct get_last_input_time_request get_last_input_time_request;
     struct get_key_state_request get_key_state_request;
     struct set_key_state_request set_key_state_request;
+    struct get_global_key_state_request get_global_key_state_request;
+    struct set_global_key_state_request set_global_key_state_request;
     struct set_foreground_window_request set_foreground_window_request;
     struct set_focus_window_request set_focus_window_request;
     struct set_active_window_request set_active_window_request;
@@ -4944,6 +4972,8 @@ union generic_reply
     struct get_last_input_time_reply get_last_input_time_reply;
     struct get_key_state_reply get_key_state_reply;
     struct set_key_state_reply set_key_state_reply;
+    struct get_global_key_state_reply get_global_key_state_reply;
+    struct set_global_key_state_reply set_global_key_state_reply;
     struct set_foreground_window_reply set_foreground_window_reply;
     struct set_focus_window_reply set_focus_window_reply;
     struct set_active_window_reply set_active_window_reply;
@@ -4996,6 +5026,6 @@ union generic_reply
     struct add_fd_completion_reply add_fd_completion_reply;
 };
 
-#define SERVER_PROTOCOL_VERSION 339
+#define SERVER_PROTOCOL_VERSION 4
 
 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/server/protocol.def b/server/protocol.def
index 01d94d2..d1329d4 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -2497,6 +2497,19 @@ enum message_type
     VARARG(keystate,bytes);       /* state array for all the keys */
 @END
 
+/* Get global key state */
+@REQ(get_global_key_state)
+    int            key;           /* key */
+@REPLY
+    BYTE           value;         /* status of key */
+@END
+
+/* Set global key state */
+@REQ(set_global_key_state)
+    int            key;           /* key */
+    BYTE           value;         /* status for key */
+@END
+
 /* Set the system foreground window */
 @REQ(set_foreground_window)
     user_handle_t  handle;        /* handle to the foreground window */
diff --git a/server/queue.c b/server/queue.c
index d90c36b..9807981 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -2250,3 +2250,20 @@ DECL_HANDLER(get_last_input_time)
 {
     reply->time = last_input_time;
 }
+
+
+BYTE global_key_state_table[256];
+
+
+/* get global key state */
+DECL_HANDLER(get_global_key_state)
+{
+    reply->value = global_key_state_table[req->key];
+}
+
+
+/* set global key state */
+DECL_HANDLER(set_global_key_state)
+{
+    global_key_state_table[req->key] = req->value;
+}
diff --git a/server/trace.c b/server/trace.c
index bbae524..ca17b77 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -3087,6 +3087,22 @@ static void dump_set_key_state_request( const struct set_key_state_request *req
     dump_varargs_bytes( cur_size );
 }
 
+static void dump_get_global_key_state_request( const struct get_global_key_state_request *req )
+{
+    fprintf( stderr, " key=%d", req->key );
+}
+
+static void dump_get_global_key_state_reply( const struct get_global_key_state_reply *req )
+{
+    fprintf( stderr, " value=%#.2x", req->value );
+}
+
+static void dump_set_global_key_state_request( const struct set_global_key_state_request *req )
+{
+    fprintf( stderr, " key=%d,", req->key );
+    fprintf( stderr, " value=%#.2x", req->value );
+}
+
 static void dump_set_foreground_window_request( const struct set_foreground_window_request *req )
 {
     fprintf( stderr, " handle=%p", req->handle );
@@ -3966,6 +3982,8 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
     (dump_func)dump_get_last_input_time_request,
     (dump_func)dump_get_key_state_request,
     (dump_func)dump_set_key_state_request,
+    (dump_func)dump_get_global_key_state_request,
+    (dump_func)dump_set_global_key_state_request,
     (dump_func)dump_set_foreground_window_request,
     (dump_func)dump_set_focus_window_request,
     (dump_func)dump_set_active_window_request,
@@ -4202,6 +4220,8 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
     (dump_func)dump_get_last_input_time_reply,
     (dump_func)dump_get_key_state_reply,
     (dump_func)0,
+    (dump_func)dump_get_global_key_state_reply,
+    (dump_func)0,
     (dump_func)dump_set_foreground_window_reply,
     (dump_func)dump_set_focus_window_reply,
     (dump_func)dump_set_active_window_reply,
@@ -4438,6 +4458,8 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
     "get_last_input_time",
     "get_key_state",
     "set_key_state",
+    "get_global_key_state",
+    "set_global_key_state",
     "set_foreground_window",
     "set_focus_window",
     "set_active_window",
diff --git a/tools/make_requests b/tools/make_requests
index 2dcac16..5c5704c 100755
--- a/tools/make_requests
+++ b/tools/make_requests
@@ -48,6 +48,7 @@ my %formats =
     "luid_t"        => "&dump_luid",
     "ioctl_code_t"  => "&dump_ioctl_code",
     "file_pos_t"    => "&dump_file_pos",
+    "BYTE"          => "%#.2x",
 );
 
 my @requests = ();
-- 
1.5.4.5

