Call EVENT_Pending() to flush X11 output queue before blocking in
MsgWaitForMultipleObjects().
Don't call EVENT_WaitNetEvent in MSG_PeekHardwareMsg.
Protect system queue access in hardware_event().

diff --git a/windows/queue.c b/windows/queue.c
index 125b18b..5ead0ce 100644
--- a/windows/queue.c
+++ b/windows/queue.c
@@ -1146,12 +1146,15 @@
 		     int xPos, int yPos, DWORD time, DWORD extraInfo )
 {
     MSG *msg;
-    QMSG  *qmsg = sysMsgQueue->lastMsg;
+    QMSG  *qmsg;
     int  mergeMsg = 0;
 
     if (!sysMsgQueue) return;
 
-      /* Merge with previous event if possible */
+    EnterCriticalSection( &sysMsgQueue->cSection );
+
+    /* Merge with previous event if possible */
+    qmsg = sysMsgQueue->lastMsg;
 
     if ((message == WM_MOUSEMOVE) && sysMsgQueue->lastMsg)
     {
@@ -1173,7 +1176,10 @@
         /* Don't merge allocate a new msg in the global heap */
         
         if (!(qmsg = (QMSG *) HeapAlloc( SystemHeap, 0, sizeof(QMSG) ) ))
-        return;
+        {
+            LeaveCriticalSection( &sysMsgQueue->cSection );
+            return;
+        }
         
         /* put message at the end of the linked list */
         qmsg->nextMsg = 0;
@@ -1201,6 +1207,8 @@
     msg->pt.y    = yPos;
     qmsg->extraInfo = extraInfo;
 
+    LeaveCriticalSection( &sysMsgQueue->cSection );
+
     QUEUE_WakeSomeone( message );
 }