Adapted to event synchronization changes.

diff --git a/loader/task.c b/loader/task.c
index 520bf48..a877ace 100644
--- a/loader/task.c
+++ b/loader/task.c
@@ -682,7 +682,6 @@
     TDB *pOldTask = NULL, *pNewTask;
     HTASK16 hTask = 0;
     STACK16FRAME *newframe16;
-    BOOL pending = FALSE;
 
     /* Get the initial task up and running */
     if (!hCurrentTask && GetCurrentTask())
@@ -743,10 +742,6 @@
         pOldTask->hYieldTo = 0;
     }
 
-    /* extract hardware events only! */
-
-    if (!hTask) pending = EVENT_WaitNetEvent( FALSE, TRUE );
-
     while (!hTask)
     {
         /* Find a task that has an event pending */
@@ -764,10 +759,6 @@
         if (hLockedTask && (hTask != hLockedTask)) hTask = 0;
         if (hTask) break;
 
-        /* If a non-hardware event is pending, return to TASK_YieldToSystem
-           temporarily to process it safely */
-        if (pending) return TRUE;
-
         /* No task found, wait for some events to come in */
 
         /* NOTE: We release the Win16Lock while waiting for events. This is to enable
@@ -776,7 +767,7 @@
                  TASK_Reschedule anyway, there should be no re-entrancy problem ... */
 
         SYSLEVEL_ReleaseWin16Lock();
-        pending = EVENT_WaitNetEvent( TRUE, TRUE );
+        EVENT_WaitNetEvent( );
         SYSLEVEL_RestoreWin16Lock();
     }
 
@@ -850,24 +841,9 @@
         return;
     }
 
-    if ( Callbacks->CallTaskRescheduleProc() )
-    {
-        /* NOTE: We get here only when no task has an event. This means also
-                 the current task, so we shouldn't actually return to the
-                 caller here. But, we need to do so, as the EVENT_WaitNetEvent
-                 call could lead to a complex series of inter-task SendMessage
-                 calls which might leave this task in a state where it again
-                 has no event, but where its queue's wakeMask is also reset
-                 to zero. Reentering TASK_Reschedule in this state would be 
-                 suicide.  Hence, we do return to the caller after processing
-                 non-hardware events. Actually, this should not hurt anyone,
-                 as the caller must be WaitEvent, and thus the QUEUE_WaitBits
-                 loop in USER. Should there actually be no message pending 
-                 for this task after processing non-hardware events, that loop
-                 will simply return to WaitEvent.  */
-                 
-        EVENT_WaitNetEvent( FALSE, FALSE );
-    }
+    EVENT_Synchronize( FALSE );
+
+    Callbacks->CallTaskRescheduleProc();
 }
 
 
diff --git a/scheduler/synchro.c b/scheduler/synchro.c
index ec73de7..a03aaa6 100644
--- a/scheduler/synchro.c
+++ b/scheduler/synchro.c
@@ -13,6 +13,8 @@
 #include "thread.h"
 #include "winerror.h"
 #include "syslevel.h"
+#include "message.h"
+#include "x11drv.h"
 #include "server.h"
 #include "debug.h"
 
@@ -84,6 +86,20 @@
         return WAIT_FAILED;
     }
 
+    /* FIXME: This is extremely ugly, but needed to avoid endless
+     *        recursion due to EVENT_Synchronize itself using 
+     *        EnterCriticalSection( &X11DRV_CritSection ) ...
+     */ 
+    if ( count == 0 || handles[0] != X11DRV_CritSection.LockSemaphore )
+    {
+        /* Before we might possibly block, we need to push outstanding
+         * graphics output to the X server ...  This needs to be done
+         * here so that it also works with native USER.
+         */
+        if ( timeout != 0 )
+            EVENT_Synchronize( FALSE );
+    }
+
     for (i = 0; i < count; i++) server_handle[i] = handles[i];
 
     req.count   = count;