Merged mouse buttons states into the key state array.
Fixed confusion between queue state and async state.

diff --git a/dlls/user/message.c b/dlls/user/message.c
index 1c5afa6..ac8bf41 100644
--- a/dlls/user/message.c
+++ b/dlls/user/message.c
@@ -1860,20 +1860,6 @@
         queue->GetMessagePosVal  = MAKELONG( msg.pt.x, msg.pt.y );
     }
 
-      /* We got a message */
-    if (flags & PM_REMOVE)
-    {
-        if (msg.message == WM_KEYDOWN || msg.message == WM_SYSKEYDOWN)
-        {
-            BYTE *p = &QueueKeyStateTable[msg.wParam & 0xff];
-
-            if (!(*p & 0x80)) *p ^= 0x01;
-            *p |= 0x80;
-        }
-        else if (msg.message == WM_KEYUP || msg.message == WM_SYSKEYUP)
-            QueueKeyStateTable[msg.wParam & 0xff] &= ~0x80;
-    }
-
     HOOK_CallHooksW( WH_GETMESSAGE, HC_ACTION, flags & PM_REMOVE, (LPARAM)&msg );
 
     /* copy back our internal safe copy of message data to msg_out.
diff --git a/include/input.h b/include/input.h
index dcaa44e..6b02ef1 100644
--- a/include/input.h
+++ b/include/input.h
@@ -9,10 +9,7 @@
 
 #include "windef.h"
 
-extern BOOL MouseButtonsStates[3];
-extern BOOL AsyncMouseButtonsStates[3];
 extern BYTE InputKeyStateTable[256];
-extern BYTE QueueKeyStateTable[256];
 extern BYTE AsyncKeyStateTable[256];
 
 #endif  /* __WINE_INPUT_H */
diff --git a/windows/input.c b/windows/input.c
index 408d214..f4909c3 100644
--- a/windows/input.c
+++ b/windows/input.c
@@ -41,21 +41,18 @@
 static BOOL InputEnabled = TRUE;
 static BOOL SwappedButtons;
 
-BOOL MouseButtonsStates[3];
-BOOL AsyncMouseButtonsStates[3];
 BYTE InputKeyStateTable[256];
-BYTE QueueKeyStateTable[256];
 BYTE AsyncKeyStateTable[256];
 
 /* Storage for the USER-maintained mouse positions */
 static DWORD PosX, PosY;
 
 #define GET_KEYSTATE() \
-     ((MouseButtonsStates[SwappedButtons ? 2 : 0]  ? MK_LBUTTON : 0) | \
-      (MouseButtonsStates[1]                       ? MK_RBUTTON : 0) | \
-      (MouseButtonsStates[SwappedButtons ? 0 : 2]  ? MK_MBUTTON : 0) | \
-      (InputKeyStateTable[VK_SHIFT]   & 0x80       ? MK_SHIFT   : 0) | \
-      (InputKeyStateTable[VK_CONTROL] & 0x80       ? MK_CONTROL : 0))
+     ((InputKeyStateTable[SwappedButtons ? VK_RBUTTON : VK_LBUTTON] & 0x80 ? MK_LBUTTON : 0) | \
+      (InputKeyStateTable[SwappedButtons ? VK_LBUTTON : VK_LBUTTON] & 0x80 ? MK_RBUTTON : 0) | \
+      (InputKeyStateTable[VK_MBUTTON] & 0x80 ? MK_MBUTTON : 0) | \
+      (InputKeyStateTable[VK_SHIFT]   & 0x80 ? MK_SHIFT   : 0) | \
+      (InputKeyStateTable[VK_CONTROL] & 0x80 ? MK_CONTROL : 0))
 
 typedef union
 {
@@ -190,37 +187,40 @@
     }
     if (mi->dwFlags & (!SwappedButtons? MOUSEEVENTF_LEFTDOWN : MOUSEEVENTF_RIGHTDOWN))
     {
-        MouseButtonsStates[0] = AsyncMouseButtonsStates[0] = TRUE;
+        InputKeyStateTable[VK_LBUTTON] |= 0x80;
+        AsyncKeyStateTable[VK_LBUTTON] |= 0x80;
         queue_raw_hardware_message( WM_LBUTTONDOWN, keystate, 0, PosX, PosY,
                                     mi->time, mi->dwExtraInfo );
     }
     if (mi->dwFlags & (!SwappedButtons? MOUSEEVENTF_LEFTUP : MOUSEEVENTF_RIGHTUP))
     {
-        MouseButtonsStates[0] = FALSE;
+        AsyncKeyStateTable[VK_LBUTTON] &= ~0x80;
         queue_raw_hardware_message( WM_LBUTTONUP, keystate, 0, PosX, PosY,
                                     mi->time, mi->dwExtraInfo );
     }
     if (mi->dwFlags & (!SwappedButtons? MOUSEEVENTF_RIGHTDOWN : MOUSEEVENTF_LEFTDOWN))
     {
-        MouseButtonsStates[2] = AsyncMouseButtonsStates[2] = TRUE;
+        InputKeyStateTable[VK_RBUTTON] |= 0x80;
+        AsyncKeyStateTable[VK_RBUTTON] |= 0x80;
         queue_raw_hardware_message( WM_RBUTTONDOWN, keystate, 0, PosX, PosY,
                                     mi->time, mi->dwExtraInfo );
     }
     if (mi->dwFlags & (!SwappedButtons? MOUSEEVENTF_RIGHTUP : MOUSEEVENTF_LEFTUP))
     {
-        MouseButtonsStates[2] = FALSE;
+        AsyncKeyStateTable[VK_RBUTTON] &= ~0x80;
         queue_raw_hardware_message( WM_RBUTTONUP, keystate, 0, PosX, PosY,
                                     mi->time, mi->dwExtraInfo );
     }
     if (mi->dwFlags & MOUSEEVENTF_MIDDLEDOWN)
     {
-        MouseButtonsStates[1] = AsyncMouseButtonsStates[1] = TRUE;
+        InputKeyStateTable[VK_MBUTTON] |= 0x80;
+        AsyncKeyStateTable[VK_MBUTTON] |= 0x80;
         queue_raw_hardware_message( WM_MBUTTONDOWN, keystate, 0, PosX, PosY,
                                     mi->time, mi->dwExtraInfo );
     }
     if (mi->dwFlags & MOUSEEVENTF_MIDDLEUP)
     {
-        MouseButtonsStates[1] = FALSE;
+        AsyncKeyStateTable[VK_MBUTTON] &= ~0x80;
         queue_raw_hardware_message( WM_MBUTTONUP, keystate, 0, PosX, PosY,
                                     mi->time, mi->dwExtraInfo );
     }
@@ -340,9 +340,9 @@
         if (keyState != GET_KEYSTATE())
         {
             /* We need to update the keystate with what X provides us */
-            MouseButtonsStates[SwappedButtons ? 2 : 0] = (keyState & MK_LBUTTON ? TRUE : FALSE);
-            MouseButtonsStates[SwappedButtons ? 0 : 2] = (keyState & MK_RBUTTON ? TRUE : FALSE);
-            MouseButtonsStates[1]                      = (keyState & MK_MBUTTON ? TRUE : FALSE);
+            InputKeyStateTable[SwappedButtons ? VK_RBUTTON : VK_LBUTTON] = (keyState & MK_LBUTTON ? 0x80 : 0);
+            InputKeyStateTable[SwappedButtons ? VK_LBUTTON : VK_RBUTTON] = (keyState & MK_RBUTTON ? 0x80 : 0);
+            InputKeyStateTable[VK_MBUTTON]             = (keyState & MK_MBUTTON ? 0x80 : 0);
             InputKeyStateTable[VK_SHIFT]               = (keyState & MK_SHIFT   ? 0x80 : 0);
             InputKeyStateTable[VK_CONTROL]             = (keyState & MK_CONTROL ? 0x80 : 0);
         }
@@ -563,84 +563,6 @@
 }
 
 /**********************************************************************
- *		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;
-
-    switch (vkey)
-	{
-	case VK_LBUTTON : /* VK_LBUTTON is 1 */
-	    retval = MouseButtonsStates[0] ? 0x8000 : 0;
-	    break;
-	case VK_MBUTTON : /* VK_MBUTTON is 4 */
-	    retval = MouseButtonsStates[1] ? 0x8000 : 0;
-	    break;
-	case VK_RBUTTON : /* VK_RBUTTON is 2 */
-	    retval = MouseButtonsStates[2] ? 0x8000 : 0;
-	    break;
-	default :
-	    if (vkey >= 'a' && vkey <= 'z')
-		vkey += 'A' - 'a';
-	    retval = ( (WORD)(QueueKeyStateTable[vkey] & 0x80) << 8 ) |
-		       (WORD)(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 != NULL) {
-	QueueKeyStateTable[VK_LBUTTON] = MouseButtonsStates[0] ? 0x80 : 0;
-	QueueKeyStateTable[VK_MBUTTON] = MouseButtonsStates[1] ? 0x80 : 0;
-	QueueKeyStateTable[VK_RBUTTON] = MouseButtonsStates[2] ? 0x80 : 0;
-	memcpy(lpKeyState, QueueKeyStateTable, 256);
-    }
-
-    return TRUE;
-}
-
-/**********************************************************************
- *		SetKeyboardState (USER.223)
- *		SetKeyboardState (USER32.@)
- */
-BOOL WINAPI SetKeyboardState(LPBYTE lpKeyState)
-{
-    TRACE_(key)("(%p)\n", lpKeyState);
-    if (lpKeyState != NULL) {
-	memcpy(QueueKeyStateTable, lpKeyState, 256);
-	MouseButtonsStates[0] = (QueueKeyStateTable[VK_LBUTTON] != 0);
-	MouseButtonsStates[1] = (QueueKeyStateTable[VK_MBUTTON] != 0);
-	MouseButtonsStates[2] = (QueueKeyStateTable[VK_RBUTTON] != 0);
-    }
-
-    return TRUE;
-}
-
-/**********************************************************************
  *		GetAsyncKeyState (USER32.@)
  *
  *	Determine if a key is or was pressed.  retval has high-order 
@@ -655,31 +577,9 @@
  */
 WORD WINAPI GetAsyncKeyState(INT nKey)
 {
-    WORD retval;
-
-    switch (nKey) {
-     case VK_LBUTTON:
-         retval = (AsyncMouseButtonsStates[0] ? 0x0001 : 0) |
-                 (MouseButtonsStates[0] ? 0x8000 : 0);
-        AsyncMouseButtonsStates[0] = 0;
-        break;
-     case VK_MBUTTON:
-         retval = (AsyncMouseButtonsStates[1] ? 0x0001 : 0) |
-                 (MouseButtonsStates[1] ? 0x8000 : 0);
-        AsyncMouseButtonsStates[1] = 0;
-        break;
-     case VK_RBUTTON:
-         retval = (AsyncMouseButtonsStates[2] ? 0x0001 : 0) |
-                 (MouseButtonsStates[2] ? 0x8000 : 0);
-        AsyncMouseButtonsStates[2] = 0;
-        break;
-     default:
-         retval = ((AsyncKeyStateTable[nKey] & 0x80) ? 0x0001 : 0) |
+    WORD retval = ((AsyncKeyStateTable[nKey] & 0x80) ? 0x0001 : 0) |
                   ((InputKeyStateTable[nKey] & 0x80) ? 0x8000 : 0);
-        AsyncKeyStateTable[nKey] = 0;
-        break;
-    }
-
+    AsyncKeyStateTable[nKey] = 0;
     TRACE_(key)("(%x) -> %x\n", nKey, retval);
     return retval;
 }
diff --git a/windows/message.c b/windows/message.c
index 638e474..8d6644e 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -37,6 +37,7 @@
 #define WM_NCMOUSEFIRST         WM_NCMOUSEMOVE
 #define WM_NCMOUSELAST          WM_NCMBUTTONDBLCLK
 
+static BYTE QueueKeyStateTable[256];
 static UINT doubleClickSpeed = 452;
 
 
@@ -115,6 +116,52 @@
 
 
 /***********************************************************************
+ *           update_queue_key_state
+ */
+static void update_queue_key_state( UINT msg, WPARAM wp )
+{
+    BOOL down = FALSE;
+
+    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;
+        break;
+    }
+    if (down)
+    {
+        BYTE *p = &QueueKeyStateTable[wp];
+        if (!(*p & 0x80)) *p ^= 0x01;
+        *p |= 0x80;
+    }
+    else QueueKeyStateTable[wp] &= ~0x80;
+}
+
+
+/***********************************************************************
  *           MSG_SendParentNotify
  *
  * Send a WM_PARENTNOTIFY to all ancestors of the given window, unless
@@ -172,12 +219,13 @@
                         keyDown++;
                 if (!keyDown)
                     msg.lParam |= 0x40000000;
-                AsyncKeyStateTable[msg.wParam]=InputKeyStateTable[msg.wParam] |= 0x80;
+                InputKeyStateTable[msg.wParam] |= 0x80;
+                AsyncKeyStateTable[msg.wParam] |= 0x80;
             }
             else                                       /* WM_KEYUP, WM_SYSKEYUP */
             {
                 msg.lParam |= 0xC0000000;
-                AsyncKeyStateTable[msg.wParam]=InputKeyStateTable[msg.wParam] &= ~0x80;
+                InputKeyStateTable[msg.wParam] &= ~0x80;
             }
             if (InputKeyStateTable[VK_MENU] & 0x80)
                 msg.lParam |= 0x20000000;
@@ -192,27 +240,33 @@
             switch (tmpMsg.message)
             {
             case WM_LBUTTONDOWN:
-                MouseButtonsStates[0]=AsyncMouseButtonsStates[0]=TRUE;break;
+                InputKeyStateTable[VK_LBUTTON] |= 0x80;
+                AsyncKeyStateTable[VK_LBUTTON] |= 0x80;
+                break;
             case WM_LBUTTONUP:
-                MouseButtonsStates[0]=AsyncMouseButtonsStates[0]=FALSE;break;
+                InputKeyStateTable[VK_LBUTTON] &= ~0x80;
+                break;
             case WM_MBUTTONDOWN:
-                MouseButtonsStates[1]=AsyncMouseButtonsStates[1]=TRUE;break;
+                InputKeyStateTable[VK_MBUTTON] |= 0x80;
+                AsyncKeyStateTable[VK_MBUTTON] |= 0x80;
+                break;
             case WM_MBUTTONUP:
-                MouseButtonsStates[1]=AsyncMouseButtonsStates[1]=FALSE;break;
+                InputKeyStateTable[VK_MBUTTON] &= ~0x80;
+                break;
             case WM_RBUTTONDOWN:
-                MouseButtonsStates[2]=AsyncMouseButtonsStates[2]=TRUE;break;
+                InputKeyStateTable[VK_RBUTTON] |= 0x80;
+                AsyncKeyStateTable[VK_RBUTTON] |= 0x80;
+                break;
             case WM_RBUTTONUP:
-                MouseButtonsStates[2]=AsyncMouseButtonsStates[2]=FALSE;break;
+                InputKeyStateTable[VK_RBUTTON] &= ~0x80;
+                break;
             }
-            AsyncKeyStateTable[VK_LBUTTON]= InputKeyStateTable[VK_LBUTTON] = MouseButtonsStates[0] ? 0x80 : 0;
-            AsyncKeyStateTable[VK_MBUTTON]= InputKeyStateTable[VK_MBUTTON] = MouseButtonsStates[1] ? 0x80 : 0;
-            AsyncKeyStateTable[VK_RBUTTON]= InputKeyStateTable[VK_RBUTTON] = MouseButtonsStates[2] ? 0x80 : 0;
             SetCursorPos(tmpMsg.paramL,tmpMsg.paramH);
             msg.lParam=MAKELONG(tmpMsg.paramL,tmpMsg.paramH);
             msg.wParam=0;
-            if (MouseButtonsStates[0]) msg.wParam |= MK_LBUTTON;
-            if (MouseButtonsStates[1]) msg.wParam |= MK_MBUTTON;
-            if (MouseButtonsStates[2]) msg.wParam |= MK_RBUTTON;
+            if (InputKeyStateTable[VK_LBUTTON] & 0x80) msg.wParam |= MK_LBUTTON;
+            if (InputKeyStateTable[VK_MBUTTON] & 0x80) msg.wParam |= MK_MBUTTON;
+            if (InputKeyStateTable[VK_RBUTTON] & 0x80) msg.wParam |= MK_RBUTTON;
 
             msg.pt.x = tmpMsg.paramL;
             msg.pt.y = tmpMsg.paramH;
@@ -270,6 +324,8 @@
 {
     if (remove)
     {
+        update_queue_key_state( msg->message, msg->wParam );
+
         /* Handle F1 key by sending out WM_HELP message */
         if ((msg->message == WM_KEYUP) &&
             (msg->wParam == VK_F1) &&
@@ -400,6 +456,8 @@
         raw_message += WM_LBUTTONDOWN - WM_LBUTTONDBLCLK;
     }
 
+    if (remove) update_queue_key_state( raw_message, 0 );
+
     if (HOOK_IsHooked( WH_MOUSE ))
     {
         MOUSEHOOKSTRUCT hook;
@@ -538,6 +596,61 @@
 
 
 /**********************************************************************
+ *		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] & 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;
+}
+
+
+/**********************************************************************
  *		SetDoubleClickTime (USER32.@)
  */
 BOOL WINAPI SetDoubleClickTime( UINT interval )