From 8ba666f3a74da4ceaf3c9cfc3b1b7488ade23938 Mon Sep 17 00:00:00 2001
From: Alexandre Julliard <julliard@winehq.org>
Date: Wed, 8 Jan 2003 19:56:31 +0000
Subject: [PATCH] Store the keyboard state in the thread input structure on the
 server side.

---
 dlls/user/message.c            |  66 +++++++++++++
 dlls/user/msg16.c              |  27 ++++++
 dlls/user/user.exe.spec        |   4 +-
 include/wine/server_protocol.h |  34 ++++++-
 server/protocol.def            |  15 +++
 server/queue.c                 | 116 ++++++++++++++++++++++-
 server/request.h               |   4 +
 server/trace.c                 |  26 ++++++
 windows/message.c              | 165 ++-------------------------------
 9 files changed, 291 insertions(+), 166 deletions(-)

diff --git a/dlls/user/message.c b/dlls/user/message.c
index 01a48fb1587..2c2b96ad622 100644
--- a/dlls/user/message.c
+++ b/dlls/user/message.c
@@ -2298,3 +2298,69 @@ BOOL WINAPI GetGUIThreadInfo( DWORD id, GUITHREADINFO *info )
     SERVER_END_REQ;
     return ret;
 }
+
+
+/**********************************************************************
+ *		GetKeyState (USER32.@)
+ *
+ * An application calls the GetKeyState function in response to a
+ * keyboard-input message.  This function retrieves the state of the key
+ * at the time the input message was generated.
+ */
+SHORT WINAPI GetKeyState(INT vkey)
+{
+    SHORT retval = 0;
+
+    SERVER_START_REQ( get_key_state )
+    {
+        req->tid = GetCurrentThreadId();
+        req->key = vkey;
+        if (!wine_server_call( req )) retval = (signed char)reply->state;
+    }
+    SERVER_END_REQ;
+    TRACE("key (0x%x) -> %x\n", vkey, retval);
+    return retval;
+}
+
+
+/**********************************************************************
+ *		GetKeyboardState (USER32.@)
+ */
+BOOL WINAPI GetKeyboardState( LPBYTE state )
+{
+    BOOL ret;
+
+    TRACE("(%p)\n", state);
+
+    memset( state, 0, 256 );
+    SERVER_START_REQ( get_key_state )
+    {
+        req->tid = GetCurrentThreadId();
+        req->key = -1;
+        wine_server_set_reply( req, state, 256 );
+        ret = !wine_server_call_err( req );
+    }
+    SERVER_END_REQ;
+    return ret;
+}
+
+
+/**********************************************************************
+ *		SetKeyboardState (USER32.@)
+ */
+BOOL WINAPI SetKeyboardState( LPBYTE state )
+{
+    BOOL ret;
+
+    TRACE("(%p)\n", state);
+
+    memset( state, 0, 256 );
+    SERVER_START_REQ( set_key_state )
+    {
+        req->tid = GetCurrentThreadId();
+        wine_server_add_data( req, state, 256 );
+        ret = !wine_server_call_err( req );
+    }
+    SERVER_END_REQ;
+    return ret;
+}
diff --git a/dlls/user/msg16.c b/dlls/user/msg16.c
index c30fb9c585d..0ce268769c0 100644
--- a/dlls/user/msg16.c
+++ b/dlls/user/msg16.c
@@ -403,6 +403,33 @@ void WINAPI PostQuitMessage16( INT16 exitCode )
 }
 
 
+/**********************************************************************
+ *		GetKeyState (USER.106)
+ */
+INT16 WINAPI GetKeyState16(INT16 vkey)
+{
+    return GetKeyState(vkey);
+}
+
+
+/**********************************************************************
+ *		GetKeyboardState (USER.222)
+ */
+BOOL WINAPI GetKeyboardState16( LPBYTE state )
+{
+    return GetKeyboardState( state );
+}
+
+
+/**********************************************************************
+ *		SetKeyboardState (USER.223)
+ */
+BOOL WINAPI SetKeyboardState16( LPBYTE state )
+{
+    return SetKeyboardState( state );
+}
+
+
 /***********************************************************************
  *		SetMessageQueue (USER.266)
  */
diff --git a/dlls/user/user.exe.spec b/dlls/user/user.exe.spec
index 4c57d2cee13..70072c9fbb2 100644
--- a/dlls/user/user.exe.spec
+++ b/dlls/user/user.exe.spec
@@ -219,8 +219,8 @@
 219 pascal16 CreateDialogIndirect(word ptr word segptr) CreateDialogIndirect16
 220 pascal16 LoadMenuIndirect(ptr) LoadMenuIndirect16
 221 pascal16 ScrollDC(word s_word s_word ptr ptr word ptr) ScrollDC16
-222 pascal16 GetKeyboardState(ptr) GetKeyboardState
-223 pascal16 SetKeyboardState(ptr) SetKeyboardState
+222 pascal16 GetKeyboardState(ptr) GetKeyboardState16
+223 pascal16 SetKeyboardState(ptr) SetKeyboardState16
 224 pascal16 GetWindowTask(word) GetWindowTask16
 225 pascal16 EnumTaskWindows(word segptr long) EnumTaskWindows16
 226 stub LockInput # not in W2.0
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index 7d79c38a6b4..12713be3ffa 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -2778,6 +2778,32 @@ struct get_thread_input_reply
 };
 
 
+struct get_key_state_request
+{
+    struct request_header __header;
+    thread_id_t    tid;
+    int            key;
+};
+struct get_key_state_reply
+{
+    struct reply_header __header;
+    unsigned char  state;
+    /* VARARG(keystate,bytes); */
+};
+
+
+struct set_key_state_request
+{
+    struct request_header __header;
+    thread_id_t    tid;
+    /* VARARG(keystate,bytes); */
+};
+struct set_key_state_reply
+{
+    struct reply_header __header;
+};
+
+
 struct set_foreground_window_request
 {
     struct request_header __header;
@@ -3112,6 +3138,8 @@ enum request
     REQ_get_window_properties,
     REQ_attach_thread_input,
     REQ_get_thread_input,
+    REQ_get_key_state,
+    REQ_set_key_state,
     REQ_set_foreground_window,
     REQ_set_focus_window,
     REQ_set_active_window,
@@ -3289,6 +3317,8 @@ union generic_request
     struct get_window_properties_request get_window_properties_request;
     struct attach_thread_input_request attach_thread_input_request;
     struct get_thread_input_request get_thread_input_request;
+    struct get_key_state_request get_key_state_request;
+    struct set_key_state_request set_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;
@@ -3464,6 +3494,8 @@ union generic_reply
     struct get_window_properties_reply get_window_properties_reply;
     struct attach_thread_input_reply attach_thread_input_reply;
     struct get_thread_input_reply get_thread_input_reply;
+    struct get_key_state_reply get_key_state_reply;
+    struct set_key_state_reply set_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;
@@ -3477,6 +3509,6 @@ union generic_reply
     struct get_next_hook_reply get_next_hook_reply;
 };
 
-#define SERVER_PROTOCOL_VERSION 93
+#define SERVER_PROTOCOL_VERSION 94
 
 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/server/protocol.def b/server/protocol.def
index 19eca9e8684..9bbfde049c7 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -1941,6 +1941,21 @@ enum message_type
     rectangle_t    rect;          /* caret rectangle */
 @END
 
+/* Retrieve queue keyboard state for a given thread */
+@REQ(get_key_state)
+    thread_id_t    tid;           /* id of thread */
+    int            key;           /* optional key code or -1 */
+@REPLY
+    unsigned char  state;         /* state of specified key */
+    VARARG(keystate,bytes);       /* state array for all the keys */
+@END
+
+/* Set queue keyboard state for a given thread */
+@REQ(set_key_state)
+    thread_id_t    tid;           /* id of thread */
+    VARARG(keystate,bytes);       /* state array for all the keys */
+@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 b913116364c..8eaba4d2a34 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -868,6 +868,68 @@ static struct timer *set_timer( struct msg_queue *queue, unsigned int rate )
     return timer;
 }
 
+/* change the input key state for a given key */
+static void set_input_key_state( struct thread_input *input, unsigned char key, int down )
+{
+    if (down)
+    {
+        if (!(input->keystate[key] & 0x80)) input->keystate[key] ^= 0x01;
+        input->keystate[key] |= 0x80;
+    }
+    else input->keystate[key] &= ~0x80;
+}
+
+/* update the input key state for a keyboard message */
+static void update_input_key_state( struct thread_input *input, const struct message *msg )
+{
+    unsigned char key;
+    int down = 0, extended;
+
+    switch (msg->msg)
+    {
+    case WM_LBUTTONDOWN:
+        down = 1;
+        /* fall through */
+    case WM_LBUTTONUP:
+        set_input_key_state( input, VK_LBUTTON, down );
+        break;
+    case WM_MBUTTONDOWN:
+        down = 1;
+        /* fall through */
+    case WM_MBUTTONUP:
+        set_input_key_state( input, VK_MBUTTON, down );
+        break;
+    case WM_RBUTTONDOWN:
+        down = 1;
+        /* fall through */
+    case WM_RBUTTONUP:
+        set_input_key_state( input, VK_RBUTTON, down );
+        break;
+    case WM_KEYDOWN:
+    case WM_SYSKEYDOWN:
+        down = 1;
+        /* fall through */
+    case WM_KEYUP:
+    case WM_SYSKEYUP:
+        key = (unsigned char)msg->wparam;
+        extended = ((msg->lparam >> 16) & KF_EXTENDED) != 0;
+        set_input_key_state( input, key, down );
+        switch(key)
+        {
+        case VK_SHIFT:
+            set_input_key_state( input, extended ? VK_RSHIFT : VK_LSHIFT, down );
+            break;
+        case VK_CONTROL:
+            set_input_key_state( input, extended ? VK_RCONTROL : VK_LCONTROL, down );
+            break;
+        case VK_MENU:
+            set_input_key_state( input, extended ? VK_RMENU : VK_LMENU, down );
+            break;
+        }
+        break;
+    }
+}
+
 /* release the hardware message currently being processed by the given thread */
 static void release_hardware_message( struct thread *thread, int remove )
 {
@@ -879,6 +941,7 @@ static void release_hardware_message( struct thread *thread, int remove )
         struct message *other;
         int clr_bit;
 
+        update_input_key_state( input, input->msg );
         unlink_message( &input->msg_list, input->msg );
         clr_bit = get_hardware_msg_bit( input->msg );
         for (other = input->msg_list.first; other; other = other->next)
@@ -892,13 +955,19 @@ static void release_hardware_message( struct thread *thread, int remove )
 }
 
 /* find the window that should receive a given hardware message */
-static user_handle_t find_hardware_message_window( struct thread_input *input, struct message *msg )
+static user_handle_t find_hardware_message_window( struct thread_input *input, struct message *msg,
+                                                   unsigned int *msg_code )
 {
     user_handle_t win = 0;
 
+    *msg_code = msg->msg;
     if (is_keyboard_msg( msg ))
     {
-        if (input && !(win = input->focus)) win = input->active;
+        if (input && !(win = input->focus))
+        {
+            win = input->active;
+            if (*msg_code < WM_SYSKEYDOWN) *msg_code += WM_SYSKEYDOWN - WM_KEYDOWN;
+        }
     }
     else  /* mouse message */
     {
@@ -916,8 +985,9 @@ static void queue_hardware_message( struct msg_queue *queue, struct message *msg
     user_handle_t win;
     struct thread *thread;
     struct thread_input *input;
+    unsigned int msg_code;
 
-    win = find_hardware_message_window( queue ? queue->input : foreground_input, msg );
+    win = find_hardware_message_window( queue ? queue->input : foreground_input, msg, &msg_code );
     if (!win || !(thread = get_window_thread(win)))
     {
         free( msg );
@@ -943,6 +1013,7 @@ static int get_hardware_message( struct thread *thread, struct message *first,
     struct message *msg;
     user_handle_t win;
     int clear_bits, got_one = 0;
+    unsigned int msg_code;
 
     if (input->msg_thread && input->msg_thread != thread)
         return 0;  /* locked by another thread */
@@ -960,11 +1031,12 @@ static int get_hardware_message( struct thread *thread, struct message *first,
 
     while (msg)
     {
-        win = find_hardware_message_window( input, msg );
+        win = find_hardware_message_window( input, msg, &msg_code );
         if (!win || !(win_thread = get_window_thread( win )))
         {
             /* no window at all, remove it */
             struct message *next = msg->next;
+            update_input_key_state( input, msg );
             unlink_message( &input->msg_list, msg );
             free_message( msg );
             msg = next;
@@ -998,7 +1070,7 @@ static int get_hardware_message( struct thread *thread, struct message *first,
 
         reply->type   = MSG_HARDWARE;
         reply->win    = win;
-        reply->msg    = msg->msg;
+        reply->msg    = msg_code;
         reply->wparam = msg->wparam;
         reply->lparam = msg->lparam;
         reply->x      = msg->x;
@@ -1458,6 +1530,40 @@ DECL_HANDLER(get_thread_input)
 }
 
 
+/* retrieve queue keyboard state for a given thread */
+DECL_HANDLER(get_key_state)
+{
+    struct thread *thread;
+    struct thread_input *input;
+
+    if (!(thread = get_thread_from_id( req->tid ))) return;
+    input = thread->queue ? thread->queue->input : NULL;
+    if (input)
+    {
+        if (req->key >= 0) reply->state = input->keystate[req->key & 0xff];
+        set_reply_data( input->keystate, min( get_reply_max_size(), sizeof(input->keystate) ));
+    }
+    release_object( thread );
+}
+
+
+/* set queue keyboard state for a given thread */
+DECL_HANDLER(set_key_state)
+{
+    struct thread *thread = NULL;
+    struct thread_input *input;
+
+    if (!(thread = get_thread_from_id( req->tid ))) return;
+    input = thread->queue ? thread->queue->input : NULL;
+    if (input)
+    {
+        size_t size = min( sizeof(input->keystate), get_req_data_size() );
+        if (size) memcpy( input->keystate, get_req_data(), size );
+    }
+    release_object( thread );
+}
+
+
 /* set the system foreground window */
 DECL_HANDLER(set_foreground_window)
 {
diff --git a/server/request.h b/server/request.h
index 213da9883dc..240238b4709 100644
--- a/server/request.h
+++ b/server/request.h
@@ -262,6 +262,8 @@ DECL_HANDLER(get_window_property);
 DECL_HANDLER(get_window_properties);
 DECL_HANDLER(attach_thread_input);
 DECL_HANDLER(get_thread_input);
+DECL_HANDLER(get_key_state);
+DECL_HANDLER(set_key_state);
 DECL_HANDLER(set_foreground_window);
 DECL_HANDLER(set_focus_window);
 DECL_HANDLER(set_active_window);
@@ -438,6 +440,8 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
     (req_handler)req_get_window_properties,
     (req_handler)req_attach_thread_input,
     (req_handler)req_get_thread_input,
+    (req_handler)req_get_key_state,
+    (req_handler)req_set_key_state,
     (req_handler)req_set_foreground_window,
     (req_handler)req_set_focus_window,
     (req_handler)req_set_active_window,
diff --git a/server/trace.c b/server/trace.c
index 322aeb4d505..fa2be02fc59 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -2211,6 +2211,26 @@ static void dump_get_thread_input_reply( const struct get_thread_input_reply *re
     dump_rectangle( &req->rect );
 }
 
+static void dump_get_key_state_request( const struct get_key_state_request *req )
+{
+    fprintf( stderr, " tid=%08x,", req->tid );
+    fprintf( stderr, " key=%d", req->key );
+}
+
+static void dump_get_key_state_reply( const struct get_key_state_reply *req )
+{
+    fprintf( stderr, " state=%02x,", req->state );
+    fprintf( stderr, " keystate=" );
+    dump_varargs_bytes( cur_size );
+}
+
+static void dump_set_key_state_request( const struct set_key_state_request *req )
+{
+    fprintf( stderr, " tid=%08x,", req->tid );
+    fprintf( stderr, " keystate=" );
+    dump_varargs_bytes( cur_size );
+}
+
 static void dump_set_foreground_window_request( const struct set_foreground_window_request *req )
 {
     fprintf( stderr, " handle=%p", req->handle );
@@ -2509,6 +2529,8 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
     (dump_func)dump_get_window_properties_request,
     (dump_func)dump_attach_thread_input_request,
     (dump_func)dump_get_thread_input_request,
+    (dump_func)dump_get_key_state_request,
+    (dump_func)dump_set_key_state_request,
     (dump_func)dump_set_foreground_window_request,
     (dump_func)dump_set_focus_window_request,
     (dump_func)dump_set_active_window_request,
@@ -2682,6 +2704,8 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
     (dump_func)dump_get_window_properties_reply,
     (dump_func)0,
     (dump_func)dump_get_thread_input_reply,
+    (dump_func)dump_get_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,
@@ -2855,6 +2879,8 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
     "get_window_properties",
     "attach_thread_input",
     "get_thread_input",
+    "get_key_state",
+    "set_key_state",
     "set_foreground_window",
     "set_focus_window",
     "set_active_window",
diff --git a/windows/message.c b/windows/message.c
index a59724b57af..8527cf95f48 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -51,8 +51,6 @@ WINE_DECLARE_DEBUG_CHANNEL(key);
 #define WM_NCMOUSEFIRST         WM_NCMOUSEMOVE
 #define WM_NCMOUSELAST          WM_NCMBUTTONDBLCLK
 
-static BYTE QueueKeyStateTable[256];
-
 
 /***********************************************************************
  *           is_keyboard_message
@@ -130,80 +128,6 @@ static void queue_hardware_message( MSG *msg, ULONG_PTR extra_info )
 #endif
 
 
-/***********************************************************************
- *           update_queue_key_state
- */
-static void update_queue_key_state( UINT msg, WPARAM wp, LPARAM lp )
-{
-    BOOL down = FALSE, iskey = FALSE;
-    WPARAM dualkey = 0;
-
-    switch (msg)
-    {
-    case WM_LBUTTONDOWN:
-        down = TRUE;
-        /* fall through */
-    case WM_LBUTTONUP:
-        wp = VK_LBUTTON;
-        break;
-    case WM_MBUTTONDOWN:
-        down = TRUE;
-        /* fall through */
-    case WM_MBUTTONUP:
-        wp = VK_MBUTTON;
-        break;
-    case WM_RBUTTONDOWN:
-        down = TRUE;
-        /* fall through */
-    case WM_RBUTTONUP:
-        wp = VK_RBUTTON;
-        break;
-    case WM_KEYDOWN:
-    case WM_SYSKEYDOWN:
-        down = TRUE;
-        /* fall through */
-    case WM_KEYUP:
-    case WM_SYSKEYUP:
-        wp = wp & 0xff;
-	iskey = TRUE;
-        break;
-    }
-    if (iskey)
-    {
-        switch(wp)
-        {
-            case VK_SHIFT:
-		dualkey = (HIWORD(lp) & KF_EXTENDED) ? VK_RSHIFT : VK_LSHIFT;
-                break;
-            case VK_CONTROL:
-		dualkey = (HIWORD(lp) & KF_EXTENDED) ? VK_RCONTROL : VK_LCONTROL;
-                break;
-            case VK_MENU:
-		dualkey = (HIWORD(lp) & KF_EXTENDED) ? VK_RMENU : VK_LMENU;
-                break;
-            
-        }
-    }
-    if (down)
-    {
-        BYTE *p = &QueueKeyStateTable[wp];
-        if (!(*p & 0x80)) *p ^= 0x01;
-        *p |= 0x80;
-    }
-    else QueueKeyStateTable[wp] &= ~0x80;
-    if (dualkey)
-    { /* also update the "dual" keys properly */
-        if (down)
-        {
-            BYTE *p = &QueueKeyStateTable[dualkey];
-            if (!(*p & 0x80)) *p ^= 0x01;
-            *p |= 0x80;
-        }
-        else QueueKeyStateTable[dualkey] &= ~0x80;
-    }
-}
-
-
 /***********************************************************************
  *           MSG_SendParentNotify
  *
@@ -330,18 +254,10 @@ void MSG_JournalPlayBackMsg(void)
  *
  * returns TRUE if the contents of 'msg' should be passed to the application
  */
-static BOOL process_raw_keyboard_message( MSG *msg, ULONG_PTR extra_info )
+static void process_raw_keyboard_message( MSG *msg )
 {
     EVENTMSG event;
 
-    if (!(msg->hwnd = GetFocus()))
-    {
-        /* Send the message to the active window instead,  */
-        /* translating messages to their WM_SYS equivalent */
-        msg->hwnd = GetActiveWindow();
-        if (msg->message < WM_SYSKEYDOWN) msg->message += WM_SYSKEYDOWN - WM_KEYDOWN;
-    }
-
     event.message = msg->message;
     event.hwnd    = msg->hwnd;
     event.time    = msg->time;
@@ -349,11 +265,6 @@ static BOOL process_raw_keyboard_message( MSG *msg, ULONG_PTR extra_info )
     event.paramH  = msg->lParam & 0x7FFF;
     if (HIWORD(msg->lParam) & 0x0100) event.paramH |= 0x8000; /* special_key - bit */
     HOOK_CallHooks( WH_JOURNALRECORD, HC_ACTION, 0, (LPARAM)&event, TRUE );
-
-    /* if we are going to throw away the message, update the queue state now */
-    if (!msg->hwnd) update_queue_key_state( msg->message, msg->wParam, msg->lParam );
-
-    return (msg->hwnd != 0);
 }
 
 
@@ -366,8 +277,6 @@ static BOOL process_cooked_keyboard_message( MSG *msg, BOOL remove )
 {
     if (remove)
     {
-        update_queue_key_state( msg->message, msg->wParam, msg->lParam );
-
         /* Handle F1 key by sending out WM_HELP message */
         if ((msg->message == WM_KEYUP) &&
             (msg->wParam == VK_F1) &&
@@ -398,10 +307,8 @@ static BOOL process_cooked_keyboard_message( MSG *msg, BOOL remove )
 
 /***********************************************************************
  *          process_raw_mouse_message
- *
- * returns TRUE if the contents of 'msg' should be passed to the application
  */
-static BOOL process_raw_mouse_message( MSG *msg, ULONG_PTR extra_info, BOOL remove )
+static void process_raw_mouse_message( MSG *msg, BOOL remove )
 {
     static MSG clk_msg;
 
@@ -478,7 +385,6 @@ static BOOL process_raw_mouse_message( MSG *msg, ULONG_PTR extra_info, BOOL remo
         if (!(info.flags & GUI_INMENUMODE)) ScreenToClient( msg->hwnd, &pt );
     }
     msg->lParam = MAKELONG( pt.x, pt.y );
-    return TRUE;
 }
 
 
@@ -506,8 +412,6 @@ static BOOL process_cooked_mouse_message( MSG *msg, ULONG_PTR extra_info, BOOL r
         raw_message += WM_LBUTTONDOWN - WM_LBUTTONDBLCLK;
     }
 
-    if (remove) update_queue_key_state( raw_message, 0, 0 );
-
     hook.pt           = msg->pt;
     hook.hwnd         = msg->hwnd;
     hook.wHitTestCode = hittest;
@@ -602,11 +506,11 @@ BOOL MSG_process_raw_hardware_message( MSG *msg, ULONG_PTR extra_info, HWND hwnd
 {
     if (is_keyboard_message( msg->message ))
     {
-        if (!process_raw_keyboard_message( msg, extra_info )) return FALSE;
+        process_raw_keyboard_message( msg );
     }
     else if (is_mouse_message( msg->message ))
     {
-        if (!process_raw_mouse_message( msg, extra_info, remove )) return FALSE;
+        process_raw_mouse_message( msg, remove );
     }
     else
     {
@@ -635,63 +539,6 @@ BOOL MSG_process_cooked_hardware_message( MSG *msg, ULONG_PTR extra_info, BOOL r
 }
 
 
-/**********************************************************************
- *		GetKeyState (USER.106)
- */
-INT16 WINAPI GetKeyState16(INT16 vkey)
-{
-    return GetKeyState(vkey);
-}
-
-
-/**********************************************************************
- *		GetKeyState (USER32.@)
- *
- * An application calls the GetKeyState function in response to a
- * keyboard-input message.  This function retrieves the state of the key
- * at the time the input message was generated.  (SDK 3.1 Vol 2. p 390)
- */
-SHORT WINAPI GetKeyState(INT vkey)
-{
-    INT retval;
-
-    if (vkey >= 'a' && vkey <= 'z') vkey += 'A' - 'a';
-    retval = ((WORD)(QueueKeyStateTable[vkey] & 0x80) << 8 ) |
-              (QueueKeyStateTable[vkey] & 0x80) |
-              (QueueKeyStateTable[vkey] & 0x01);
-    TRACE("key (0x%x) -> %x\n", vkey, retval);
-    return retval;
-}
-
-
-/**********************************************************************
- *		GetKeyboardState (USER.222)
- *		GetKeyboardState (USER32.@)
- *
- * An application calls the GetKeyboardState function in response to a
- * keyboard input message.  This function retrieves the state of the keyboard
- * at the time the input message was generated.  (SDK 3.1 Vol 2. p 387)
- */
-BOOL WINAPI GetKeyboardState(LPBYTE lpKeyState)
-{
-    TRACE_(key)("(%p)\n", lpKeyState);
-    if (lpKeyState) memcpy(lpKeyState, QueueKeyStateTable, 256);
-    return TRUE;
-}
-
-
-/**********************************************************************
- *		SetKeyboardState (USER.223)
- *		SetKeyboardState (USER32.@)
- */
-BOOL WINAPI SetKeyboardState(LPBYTE lpKeyState)
-{
-    TRACE_(key)("(%p)\n", lpKeyState);
-    if (lpKeyState) memcpy(QueueKeyStateTable, lpKeyState, 256);
-    return TRUE;
-}
-
-
 /***********************************************************************
  *		WaitMessage (USER.112) Suspend thread pending messages
  *		WaitMessage (USER32.@) Suspend thread pending messages
@@ -974,6 +821,7 @@ BOOL WINAPI TranslateMessage( const MSG *msg )
     UINT message;
     WCHAR wp[2];
     BOOL rc = FALSE;
+    BYTE state[256];
 
     if (msg->message >= WM_KEYFIRST && msg->message <= WM_KEYLAST)
     {
@@ -989,8 +837,9 @@ BOOL WINAPI TranslateMessage( const MSG *msg )
     TRACE_(key)("Translating key %s (%04x), scancode %02x\n",
                  SPY_GetVKeyName(msg->wParam), msg->wParam, LOBYTE(HIWORD(msg->lParam)));
 
+    GetKeyboardState( state );
     /* FIXME : should handle ToUnicode yielding 2 */
-    switch (ToUnicode(msg->wParam, HIWORD(msg->lParam), QueueKeyStateTable, wp, 2, 0))
+    switch (ToUnicode(msg->wParam, HIWORD(msg->lParam), state, wp, 2, 0))
     {
     case 1:
         message = (msg->message == WM_KEYDOWN) ? WM_CHAR : WM_SYSCHAR;
-- 
GitLab