Moved idle event handling to the server.

diff --git a/include/process.h b/include/process.h
index f7bf458..4a74bea 100644
--- a/include/process.h
+++ b/include/process.h
@@ -91,8 +91,6 @@
     HANDLE          *dos_handles;      /*    Handles mapping DOS -> Win32 */
     WORD             winver;           /*    Windows version figured out by VERSION_GetVersion */
     struct _SERVICETABLE *service_table; /*  Service table for service thread */
-    HANDLE           idle_event;       /* event to signal, when the process is idle */
-    HANDLE16         main_queue;       /* main message queue of the process */ 
 } PDB;
 
 /* Process flags */
diff --git a/include/queue.h b/include/queue.h
index d3a6c24..4a1be22 100644
--- a/include/queue.h
+++ b/include/queue.h
@@ -90,7 +90,7 @@
   HQUEUE16  next;                   /* Next queue */
   HQUEUE16  self;                   /* Handle to self (was: reserved) */
   TEB*      teb;                    /* Thread owning queue */
-  HANDLE  hEvent;                 /* Event handle */
+  HANDLE    server_queue;           /* Handle to server-side queue */
   CRITICAL_SECTION cSection;        /* Queue access critical section */
 
   DWORD     magic;                  /* magic number should be QUEUE_MAGIC */
diff --git a/include/server.h b/include/server.h
index 774b8eb..ee1afd8 100644
--- a/include/server.h
+++ b/include/server.h
@@ -170,6 +170,7 @@
 {
     IN  void*        module;       /* main module base address */
     IN  void*        entry;        /* process entry point */
+    IN  int          gui;          /* is it a GUI process? */
     OUT int          debugged;     /* being debugged? */
 };
 
@@ -1147,6 +1148,29 @@
     OUT WCHAR        name[1];      /* atom name */
 };
 
+
+/* Get the message queue of the current thread */
+struct get_msg_queue_request
+{
+    OUT int          handle;       /* handle to the queue */
+};
+
+/* Wake up a message queue */
+struct wake_queue_request
+{
+    IN  int          handle;       /* handle to the queue */
+    IN  unsigned int bits;         /* wake bits */
+};
+
+/* Wait for a process to start waiting on input */
+struct wait_input_idle_request
+{
+    IN  int          handle;       /* process handle */
+    IN  int          timeout;      /* timeout */
+    OUT int          event;        /* handle to idle event */
+};
+
+
 /* Everything below this line is generated automatically by tools/make_requests */
 /* ### make_requests begin ### */
 
@@ -1255,10 +1279,13 @@
     REQ_DELETE_ATOM,
     REQ_FIND_ATOM,
     REQ_GET_ATOM_NAME,
+    REQ_GET_MSG_QUEUE,
+    REQ_WAKE_QUEUE,
+    REQ_WAIT_INPUT_IDLE,
     REQ_NB_REQUESTS
 };
 
-#define SERVER_PROTOCOL_VERSION 12
+#define SERVER_PROTOCOL_VERSION 13
 
 /* ### make_requests end ### */
 /* Everything above this line is generated automatically by tools/make_requests */
diff --git a/scheduler/process.c b/scheduler/process.c
index dd55f7d..0a9ce5d 100644
--- a/scheduler/process.c
+++ b/scheduler/process.c
@@ -187,7 +187,6 @@
     pdb->group                  = pdb;
     pdb->priority               = 8;  /* Normal */
     pdb->winver                 = 0xffff; /* to be determined */
-    pdb->main_queue             = INVALID_HANDLE_VALUE16;
     initial_envdb.startup_info  = &initial_startup;
 
     /* Setup the server connection */
@@ -218,14 +217,6 @@
     if (!HEAP_CreateSystemHeap()) return FALSE;
     pdb->heap = HeapCreate( HEAP_GROWABLE, 0, 0 );
 
-    /* Create the idle event for the initial process
-       FIXME 1: Shouldn't we call UserSignalProc for the initial process too?
-       FIXME 2: It seems to me that the initial pdb becomes never freed, so I don't now
-                where to release the idle event for the initial process.
-    */
-    pdb->idle_event = CreateEventA ( NULL, TRUE, FALSE, NULL );
-    pdb->idle_event = ConvertToGlobalHandle ( pdb->idle_event );
-
     /* Copy the parent environment */
     if (!ENV_BuildEnvironment()) return FALSE;
 
@@ -332,7 +323,7 @@
     __TRY
     {
         struct init_process_done_request *req = get_req_buffer();
-        int debugged;
+        int debugged, console_app;
         HMODULE16 hModule16;
         UINT cmdShow = SW_SHOWNORMAL;
         LPTHREAD_START_ROUTINE entry;
@@ -347,6 +338,7 @@
 
         /* Retrieve entry point address */
         entry = (LPTHREAD_START_ROUTINE)RVA_PTR( module, OptionalHeader.AddressOfEntryPoint );
+        console_app = (PE_HEADER(module)->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI);
 
         /* Create 16-bit dummy module */
         if ((hModule16 = MODULE_CreateDummyModule( pdb->exe_modref->filename, module )) < 32)
@@ -358,12 +350,12 @@
                           NtCurrentTeb(), NULL, 0 ))
             goto error;
 
-        if (PE_HEADER(module)->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI)
-            pdb->flags |= PDB32_CONSOLE_PROC;
+        if (console_app) pdb->flags |= PDB32_CONSOLE_PROC;
 
         /* Signal the parent process to continue */
         req->module = (void *)module;
         req->entry  = entry;
+        req->gui    = !console_app;
         server_call( REQ_INIT_PROCESS_DONE );
         debugged = req->debugged;
 
@@ -376,8 +368,7 @@
         LeaveCriticalSection( &pdb->crit_section );
 
         /* Call UserSignalProc ( USIG_PROCESS_RUNNING ... ) only for non-GUI win32 apps */
-        if (pdb->flags & PDB32_CONSOLE_PROC)
-            PROCESS_CallUserSignalProc( USIG_PROCESS_RUNNING, 0 );
+        if (console_app) PROCESS_CallUserSignalProc( USIG_PROCESS_RUNNING, 0 );
 
         TRACE_(relay)( "Starting Win32 process (entryproc=%p)\n", entry );
         if (debugged) DbgBreakPoint();
diff --git a/server/Makefile.in b/server/Makefile.in
index 0db09e5..2416736 100644
--- a/server/Makefile.in
+++ b/server/Makefile.in
@@ -22,6 +22,7 @@
 	pipe.c \
 	process.c \
 	ptrace.c \
+	queue.c \
 	registry.c \
 	request.c \
 	select.c \
diff --git a/server/object.h b/server/object.h
index 8869504..66ce781 100644
--- a/server/object.h
+++ b/server/object.h
@@ -72,6 +72,14 @@
 #endif
 };
 
+struct wait_queue_entry
+{
+    struct wait_queue_entry *next;
+    struct wait_queue_entry *prev;
+    struct object           *obj;
+    struct thread           *thread;
+};
+
 extern void *mem_alloc( size_t size );  /* malloc wrapper */
 extern void *memdup( const void *data, size_t len );
 extern void *alloc_object( const struct object_ops *ops, int fd );
diff --git a/server/process.c b/server/process.c
index 733b693..987bdd8 100644
--- a/server/process.c
+++ b/server/process.c
@@ -137,6 +137,8 @@
         req->hstderr = alloc_handle( process, process->console_out,
                                      GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, 1 );
     }
+    /* some handles above may have been invalid; this is not an error */
+    if (get_error() == STATUS_INVALID_HANDLE) clear_error();
     return 1;
 }
 
@@ -165,6 +167,8 @@
     process->console_in      = NULL;
     process->console_out     = NULL;
     process->init_event      = NULL;
+    process->idle_event      = NULL;
+    process->queue           = NULL;
     process->ldt_copy        = NULL;
     process->ldt_flags       = NULL;
     process->exe.next        = NULL;
@@ -282,6 +286,8 @@
     if (process->prev) process->prev->next = process->next;
     else first_process = process->next;
     if (process->init_event) release_object( process->init_event );
+    if (process->idle_event) release_object( process->idle_event );
+    if (process->queue) release_object( process->queue );
     if (process->exe.file) release_object( process->exe.file );
 }
 
@@ -813,6 +819,7 @@
     set_event( process->init_event );
     release_object( process->init_event );
     process->init_event = NULL;
+    if (req->gui) process->idle_event = create_event( NULL, 0, 1, 0 );
     if (current->suspend + current->process->suspend > 0) stop_thread( current );
     req->debugged = (current->process->debugger != 0);
 }
@@ -919,3 +926,19 @@
 {
     process_unload_dll( current->process, req->base );
 }
+
+/* wait for a process to start waiting on input */
+/* FIXME: only returns event for now, wait is done in the client */
+DECL_HANDLER(wait_input_idle)
+{
+    struct process *process;
+
+    req->event = -1;
+    if ((process = get_process_from_handle( req->handle, PROCESS_QUERY_INFORMATION )))
+    {
+        if (process->idle_event && process != current->process && process->queue != current->queue)
+            req->event = alloc_handle( current->process, process->idle_event,
+                                       EVENT_ALL_ACCESS, 0 );
+        release_object( process );
+    }
+}
diff --git a/server/process.h b/server/process.h
index ae606a5..2b7a699 100644
--- a/server/process.h
+++ b/server/process.h
@@ -13,6 +13,8 @@
 
 #include "object.h"
 
+struct msg_queue;
+
 /* process structures */
 
 struct process_dll
@@ -45,6 +47,8 @@
     struct object       *console_in;      /* console input */
     struct object       *console_out;     /* console output */
     struct event        *init_event;      /* event for init done */
+    struct event        *idle_event;      /* event for input idle */
+    struct msg_queue    *queue;           /* main message queue */
     struct process_dll   exe;             /* main exe file */
     void                *ldt_copy;        /* pointer to LDT copy in client addr space */
     void                *ldt_flags;       /* pointer to LDT flags in client addr space */
diff --git a/server/queue.c b/server/queue.c
new file mode 100644
index 0000000..80cfda6
--- /dev/null
+++ b/server/queue.c
@@ -0,0 +1,130 @@
+/*
+ * Server-side message queues
+ *
+ * Copyright (C) 2000 Alexandre Julliard
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "handle.h"
+#include "thread.h"
+#include "process.h"
+#include "request.h"
+
+struct msg_queue
+{
+    struct object  obj;             /* object header */
+    struct thread *thread;          /* thread owning this queue */
+    int            signaled;        /* queue has been signaled */
+};
+
+static void msg_queue_dump( struct object *obj, int verbose );
+static int msg_queue_add_queue( struct object *obj, struct wait_queue_entry *entry );
+static void msg_queue_remove_queue( struct object *obj, struct wait_queue_entry *entry );
+static int msg_queue_signaled( struct object *obj, struct thread *thread );
+static int msg_queue_satisfied( struct object *obj, struct thread *thread );
+
+static const struct object_ops msg_queue_ops =
+{
+    sizeof(struct msg_queue),  /* size */
+    msg_queue_dump,            /* dump */
+    msg_queue_add_queue,       /* add_queue */
+    msg_queue_remove_queue,    /* remove_queue */
+    msg_queue_signaled,        /* signaled */
+    msg_queue_satisfied,       /* satisfied */
+    NULL,                      /* get_poll_events */
+    NULL,                      /* poll_event */
+    no_read_fd,                /* get_read_fd */
+    no_write_fd,               /* get_write_fd */
+    no_flush,                  /* flush */
+    no_get_file_info,          /* get_file_info */
+    no_destroy                 /* destroy */
+};
+
+
+static struct msg_queue *create_msg_queue( struct thread *thread )
+{
+    struct msg_queue *queue;
+
+    if ((queue = alloc_object( &msg_queue_ops, -1 )))
+    {
+        queue->signaled = 0;
+        queue->thread = thread;
+        thread->queue = queue;
+        if (!thread->process->queue)
+            thread->process->queue = (struct msg_queue *)grab_object( queue );
+    }
+    return queue;
+}
+
+static int msg_queue_add_queue( struct object *obj, struct wait_queue_entry *entry )
+{
+    struct msg_queue *queue = (struct msg_queue *)obj;
+    struct process *process = entry->thread->process;
+
+    /* if waiting on the main process queue, set the idle event */
+    if (entry->thread == queue->thread && process->queue == queue)
+    {
+        if (process->idle_event) set_event( process->idle_event );
+    }
+    add_queue( obj, entry );
+    return 1;
+}
+
+static void msg_queue_remove_queue(struct object *obj, struct wait_queue_entry *entry )
+{
+    struct msg_queue *queue = (struct msg_queue *)obj;
+    struct process *process = entry->thread->process;
+
+    remove_queue( obj, entry );
+
+    /* if waiting on the main process queue, reset the idle event */
+    if (entry->thread == queue->thread && process->queue == queue)
+    {
+        if (process->idle_event) reset_event( process->idle_event );
+    }
+}
+
+static void msg_queue_dump( struct object *obj, int verbose )
+{
+    struct msg_queue *queue = (struct msg_queue *)obj;
+    fprintf( stderr, "Msg queue signaled=%d owner=%p\n", queue->signaled, queue->thread );
+}
+
+static int msg_queue_signaled( struct object *obj, struct thread *thread )
+{
+    struct msg_queue *queue = (struct msg_queue *)obj;
+    return queue->signaled;
+}
+
+static int msg_queue_satisfied( struct object *obj, struct thread *thread )
+{
+    struct msg_queue *queue = (struct msg_queue *)obj;
+    queue->signaled = 0;
+    return 0;  /* Not abandoned */
+}
+
+/* get the message queue of the current thread */
+DECL_HANDLER(get_msg_queue)
+{
+    struct msg_queue *queue = current->queue;
+
+    req->handle = -1;
+    if (!queue) queue = create_msg_queue( current );
+    if (queue) req->handle = alloc_handle( current->process, queue, SYNCHRONIZE, 0 );
+}
+
+/* wake up a message queue */
+DECL_HANDLER(wake_queue)
+{
+    struct msg_queue *queue = (struct msg_queue *)get_handle_obj( current->process, req->handle,
+                                                                  0, &msg_queue_ops );
+    if (queue)
+    {
+        queue->signaled = 1;
+        wake_up( &queue->obj, 0 );
+        release_object( queue );
+    }
+}
diff --git a/server/request.h b/server/request.h
index f87b4f5..6e3c943 100644
--- a/server/request.h
+++ b/server/request.h
@@ -173,6 +173,9 @@
 DECL_HANDLER(delete_atom);
 DECL_HANDLER(find_atom);
 DECL_HANDLER(get_atom_name);
+DECL_HANDLER(get_msg_queue);
+DECL_HANDLER(wake_queue);
+DECL_HANDLER(wait_input_idle);
 
 #ifdef WANT_REQUEST_HANDLERS
 
@@ -282,6 +285,9 @@
     (req_handler)req_delete_atom,
     (req_handler)req_find_atom,
     (req_handler)req_get_atom_name,
+    (req_handler)req_get_msg_queue,
+    (req_handler)req_wake_queue,
+    (req_handler)req_wait_input_idle,
 };
 #endif  /* WANT_REQUEST_HANDLERS */
 
diff --git a/server/thread.c b/server/thread.c
index f98982d..1899132 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -34,14 +34,6 @@
 
 /* thread queues */
 
-struct wait_queue_entry
-{
-    struct wait_queue_entry *next;
-    struct wait_queue_entry *prev;
-    struct object           *obj;
-    struct thread           *thread;
-};
-
 struct thread_wait
 {
     int                     count;      /* count of objects */
@@ -131,6 +123,7 @@
     thread->mutex       = NULL;
     thread->debug_ctx   = NULL;
     thread->debug_event = NULL;
+    thread->queue       = NULL;
     thread->info        = NULL;
     thread->wait        = NULL;
     thread->apc         = NULL;
@@ -196,6 +189,7 @@
     else first_thread = thread->next;
     if (thread->apc) free( thread->apc );
     if (thread->info) release_object( thread->info );
+    if (thread->queue) release_object( thread->queue );
     if (thread->buffer != (void *)-1) munmap( thread->buffer, MAX_REQUEST_LENGTH );
     if (thread->pass_fd != -1) close( thread->pass_fd );
 }
diff --git a/server/thread.h b/server/thread.h
index 3340d5e..910c330 100644
--- a/server/thread.h
+++ b/server/thread.h
@@ -22,6 +22,7 @@
 struct debug_ctx;
 struct debug_event;
 struct startup_info;
+struct msg_queue;
 
 enum run_state
 {
@@ -41,6 +42,7 @@
     struct mutex       *mutex;       /* list of currently owned mutexes */
     struct debug_ctx   *debug_ctx;   /* debugger context if this thread is a debugger */
     struct debug_event *debug_event; /* debug event being sent to debugger */
+    struct msg_queue   *queue;       /* message queue */
     struct startup_info*info;      /* startup info for child process */
     struct thread_wait *wait;      /* current wait condition if sleeping */
     struct thread_apc  *apc;       /* list of async procedure calls */
diff --git a/server/trace.c b/server/trace.c
index 4ea9319..369fed0 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -284,7 +284,8 @@
 static void dump_init_process_done_request( const struct init_process_done_request *req )
 {
     fprintf( stderr, " module=%p,", req->module );
-    fprintf( stderr, " entry=%p", req->entry );
+    fprintf( stderr, " entry=%p,", req->entry );
+    fprintf( stderr, " gui=%d", req->gui );
 }
 
 static void dump_init_process_done_reply( const struct init_process_done_request *req )
@@ -1333,6 +1334,32 @@
     dump_unicode_string( req, req->name );
 }
 
+static void dump_get_msg_queue_request( const struct get_msg_queue_request *req )
+{
+}
+
+static void dump_get_msg_queue_reply( const struct get_msg_queue_request *req )
+{
+    fprintf( stderr, " handle=%d", req->handle );
+}
+
+static void dump_wake_queue_request( const struct wake_queue_request *req )
+{
+    fprintf( stderr, " handle=%d,", req->handle );
+    fprintf( stderr, " bits=%08x", req->bits );
+}
+
+static void dump_wait_input_idle_request( const struct wait_input_idle_request *req )
+{
+    fprintf( stderr, " handle=%d,", req->handle );
+    fprintf( stderr, " timeout=%d", req->timeout );
+}
+
+static void dump_wait_input_idle_reply( const struct wait_input_idle_request *req )
+{
+    fprintf( stderr, " event=%d", req->event );
+}
+
 static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
     (dump_func)dump_new_process_request,
     (dump_func)dump_wait_process_request,
@@ -1437,6 +1464,9 @@
     (dump_func)dump_delete_atom_request,
     (dump_func)dump_find_atom_request,
     (dump_func)dump_get_atom_name_request,
+    (dump_func)dump_get_msg_queue_request,
+    (dump_func)dump_wake_queue_request,
+    (dump_func)dump_wait_input_idle_request,
 };
 
 static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
@@ -1543,6 +1573,9 @@
     (dump_func)0,
     (dump_func)dump_find_atom_reply,
     (dump_func)dump_get_atom_name_reply,
+    (dump_func)dump_get_msg_queue_reply,
+    (dump_func)0,
+    (dump_func)dump_wait_input_idle_reply,
 };
 
 static const char * const req_names[REQ_NB_REQUESTS] = {
@@ -1649,6 +1682,9 @@
     "delete_atom",
     "find_atom",
     "get_atom_name",
+    "get_msg_queue",
+    "wake_queue",
+    "wait_input_idle",
 };
 
 /* ### make_requests end ### */
diff --git a/windows/message.c b/windows/message.c
index d2c1a67..2c42ad6 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -23,7 +23,6 @@
 #include "queue.h"
 #include "winproc.h"
 #include "task.h"
-#include "process.h"
 #include "selectors.h"
 #include "thread.h"
 #include "options.h"
@@ -31,9 +30,9 @@
 #include "struct32.h"
 #include "debugtools.h"
 
-DEFAULT_DEBUG_CHANNEL(msg)
-DECLARE_DEBUG_CHANNEL(key)
-DECLARE_DEBUG_CHANNEL(sendmsg)
+DEFAULT_DEBUG_CHANNEL(msg);
+DECLARE_DEBUG_CHANNEL(key);
+DECLARE_DEBUG_CHANNEL(sendmsg);
 
 #define WM_NCMOUSEFIRST         WM_NCMOUSEMOVE
 #define WM_NCMOUSELAST          WM_NCMBUTTONDBLCLK
@@ -1952,7 +1951,6 @@
     DWORD i;
     HANDLE handles[MAXIMUM_WAIT_OBJECTS];
     DWORD ret;
-    PDB * pdb = PROCESS_Current();
 
     HQUEUE16 hQueue = GetFastQueue16();
     MESSAGEQUEUE *msgQueue = (MESSAGEQUEUE *)QUEUE_Lock( hQueue );
@@ -1988,7 +1986,6 @@
 	/*
 	 * Check the handles in the list.
 	 */
-	SetEvent ( pdb->idle_event );
 	ret = WaitForMultipleObjects(nCount, pHandles, fWaitAll, 5L);
 
 	/*
@@ -2020,18 +2017,11 @@
     {
     /* Add the thread event to the handle list */
       for (i = 0; i < nCount; i++)
-	handles[i] = pHandles[i];
-      handles[nCount] = msgQueue->hEvent;
-
-      if ( pdb->main_queue == INVALID_HANDLE_VALUE16 ) pdb->main_queue = hQueue;
-      if ( pdb->main_queue == hQueue ) SetEvent ( pdb->idle_event );
+ 	handles[i] = pHandles[i];
+      handles[nCount] = msgQueue->server_queue;
       ret = WaitForMultipleObjects( nCount+1, handles, fWaitAll, dwMilliseconds );
-      if ( pdb->main_queue == hQueue ) ResetEvent ( pdb->idle_event );
-
     } 
-
     QUEUE_Unlock( msgQueue );
-    
     return ret;
 }
 
diff --git a/windows/queue.c b/windows/queue.c
index 67fabc5..f4705b2 100644
--- a/windows/queue.c
+++ b/windows/queue.c
@@ -20,12 +20,12 @@
 #include "hook.h"
 #include "heap.h"
 #include "thread.h"
-#include "process.h"
 #include "debugtools.h"
+#include "server.h"
 #include "spy.h"
 
-DECLARE_DEBUG_CHANNEL(msg)
-DECLARE_DEBUG_CHANNEL(sendmsg)
+DECLARE_DEBUG_CHANNEL(msg);
+DECLARE_DEBUG_CHANNEL(sendmsg);
 
 #define MAX_QUEUE_SIZE   120  /* Max. size of a message queue */
 
@@ -342,8 +342,8 @@
         if ( --queue->lockCount == 0 )
         {
             DeleteCriticalSection ( &queue->cSection );
-            if (queue->hEvent)
-                CloseHandle( queue->hEvent );
+            if (queue->server_queue)
+                CloseHandle( queue->server_queue );
             GlobalFree16( queue->self );
         }
     
@@ -443,6 +443,7 @@
     HQUEUE16 hQueue;
     MESSAGEQUEUE * msgQueue;
     TDB *pTask = (TDB *)GlobalLock16( GetCurrentTask() );
+    struct get_msg_queue_request *req = get_req_buffer();
 
     TRACE_(msg)("(): Creating message queue...\n");
 
@@ -454,6 +455,15 @@
     if ( !msgQueue )
         return 0;
 
+    if (server_call( REQ_GET_MSG_QUEUE ))
+    {
+        ERR_(msg)("Cannot get thread queue");
+        GlobalFree16( hQueue );
+        return 0;
+    }
+    msgQueue->server_queue = req->handle;
+    msgQueue->server_queue = ConvertToGlobalHandle( msgQueue->server_queue );
+
     msgQueue->self        = hQueue;
     msgQueue->wakeBits    = msgQueue->changeBits = 0;
     msgQueue->wWinVersion = pTask ? pTask->version : 0;
@@ -461,22 +471,6 @@
     InitializeCriticalSection( &msgQueue->cSection );
     MakeCriticalSectionGlobal( &msgQueue->cSection );
 
-    /* Create an Event object for waiting on message, used by win32 thread
-       only */
-    if ( !THREAD_IsWin16( NtCurrentTeb() ) )
-    {
-        msgQueue->hEvent = CreateEventA( NULL, FALSE, FALSE, NULL);
-
-        if (msgQueue->hEvent == 0)
-        {
-            WARN_(msg)("CreateEventA is not able to create an event object");
-            return 0;
-        }
-        msgQueue->hEvent = ConvertToGlobalHandle( msgQueue->hEvent );
-    }
-    else
-        msgQueue->hEvent = 0;
-         
     msgQueue->lockCount = 1;
     msgQueue->magic = QUEUE_MAGIC;
     
@@ -645,7 +639,10 @@
         }
         else
         {
-            SetEvent( queue->hEvent );
+            struct wake_queue_request *req = get_req_buffer();
+            req->handle = queue->server_queue;
+            req->bits   = bit;
+            server_call( REQ_WAKE_QUEUE );
         }
     }
 }
@@ -675,7 +672,6 @@
     MESSAGEQUEUE *queue;
     DWORD curTime = 0;
     HQUEUE16 hQueue;
-    PDB * pdb;
 
     TRACE_(msg)("q %04x waiting for %04x\n", GetFastQueue16(), bits);
 
@@ -685,8 +681,6 @@
     hQueue = GetFastQueue16();
     if (!(queue = (MESSAGEQUEUE *)QUEUE_Lock( hQueue ))) return 0;
     
-    pdb = PROCESS_Current();
-
     for (;;)
     {
         if (queue->changeBits & bits)
@@ -724,22 +718,7 @@
 	        ReleaseThunkLock( &dwlc );
 	    }
 
-
-	    if ( pdb->main_queue == INVALID_HANDLE_VALUE16 ) 
-	    {
-	        pdb->main_queue = hQueue;
-	    }
-	    if ( pdb->main_queue == hQueue ) 
-	    {
-	        SetEvent ( pdb->idle_event );
-	    }
-
-	    WaitForSingleObject( queue->hEvent, timeout );
-
-	    if ( pdb->main_queue == hQueue ) 
-	    {
-	        ResetEvent ( pdb->idle_event );
-	    }
+	    WaitForSingleObject( queue->server_queue, timeout );
 
 	    if ( bHasWin16Lock ) 
 	    {
@@ -748,8 +727,6 @@
         }
         else
         {
-	    SetEvent ( pdb->idle_event );
-
             if ( timeout == INFINITE )
                 WaitEvent16( 0 );  /* win 16 thread, use WaitEvent */
             else
@@ -1522,34 +1499,21 @@
  */
 DWORD WINAPI WaitForInputIdle (HANDLE hProcess, DWORD dwTimeOut)
 {
-  PDB * pdb;
-  DWORD cur_time, ret, pid = MapProcessHandle ( hProcess );
+    DWORD cur_time, ret;
+    HANDLE idle_event;
+    struct wait_input_idle_request *req = get_req_buffer();
 
-  /* Check whether the calling process is a command line application */
-  if (!THREAD_IsWin16(NtCurrentTeb() ) &&
-      (PROCESS_Current()->flags & PDB32_CONSOLE_PROC))
-  {
-    TRACE_(msg)("not a win32 GUI application!\n" );
-    return 0; 
-  }
-  
-  if (!(pdb = PROCESS_IdToPDB( pid ))) return 0;
-
-  /* check whether we are waiting for a win32 process or the win16 subsystem */
-  if ( pdb->flags & PDB32_WIN16_PROC ) {
-    if ( THREAD_IsWin16(NtCurrentTeb()) ) return 0;
-  }
-    else { /* target is win32 */
-    if ( pdb->flags & PDB32_CONSOLE_PROC ) return 0;
-    if ( GetFastQueue16() == pdb->main_queue ) return 0;
-  }
+    req->handle = hProcess;
+    req->timeout = dwTimeOut;
+    if (server_call( REQ_WAIT_INPUT_IDLE )) return 0xffffffff;
+    if ((idle_event = req->event) == -1) return 0;  /* no event to wait on */
 
   cur_time = GetTickCount();
   
-  TRACE_(msg)("waiting for %x\n", pdb->idle_event );
+  TRACE_(msg)("waiting for %x\n", idle_event );
   while ( dwTimeOut > GetTickCount() - cur_time || dwTimeOut == INFINITE ) {
 
-    ret = MsgWaitForMultipleObjects ( 1, &pdb->idle_event, FALSE, dwTimeOut, QS_SENDMESSAGE );
+    ret = MsgWaitForMultipleObjects ( 1, &idle_event, FALSE, dwTimeOut, QS_SENDMESSAGE );
     if ( ret == ( WAIT_OBJECT_0 + 1 )) {
       MESSAGEQUEUE * queue;
       if (!(queue = (MESSAGEQUEUE *)QUEUE_Lock( GetFastQueue16() ))) return 0xFFFFFFFF;
diff --git a/windows/user.c b/windows/user.c
index c427c17..e77f20c 100644
--- a/windows/user.c
+++ b/windows/user.c
@@ -210,9 +210,7 @@
 WORD WINAPI UserSignalProc( UINT uCode, DWORD dwThreadOrProcessID,
                             DWORD dwFlags, HMODULE16 hModule )
 {
-    static HANDLE win16_idle_event;
     HINSTANCE16 hInst;
-    PDB * pdb;
 
     /* FIXME: Proper reaction to most signals still missing. */
 
@@ -239,32 +237,12 @@
         break;
 
     case USIG_PROCESS_CREATE:
-      pdb = PROCESS_Current();
-
-      /* Create the idle event for the process. We have just one idle_event for all
-	 win16 processes, while each win32 process has its own */
-
-      if ( pdb->flags & PDB32_WIN16_PROC )
-      {
-          if (!win16_idle_event)
-          {
-              win16_idle_event = CreateEventA ( NULL, TRUE, FALSE, NULL );
-              win16_idle_event = ConvertToGlobalHandle ( win16_idle_event );
-          }
-          pdb->idle_event = win16_idle_event;
-      }
-      else { /* win32 process */
-	pdb->idle_event = CreateEventA ( NULL, TRUE, FALSE, NULL );
-        pdb->idle_event = ConvertToGlobalHandle ( pdb->idle_event );
-	TRACE_(win)("created win32 idle event: %x\n", pdb->idle_event );
-      }
       break;
 
     case USIG_PROCESS_INIT:
     case USIG_PROCESS_LOADED:
       break;
     case USIG_PROCESS_RUNNING:
-	SetEvent ( PROCESS_Current()->idle_event );
         break;
 
     case USIG_PROCESS_EXIT:
@@ -273,12 +251,6 @@
     case USIG_PROCESS_DESTROY:      
       hInst = ((TDB *)GlobalLock16( GetCurrentTask() ))->hInstance;
       USER_AppExit( hInst );
-
-      pdb = PROCESS_Current();
-      if ( ! (pdb->flags & PDB32_WIN16_PROC) ) {
-	TRACE_(win)("destroying win32 idle event: %x\n", pdb->idle_event );
-	CloseHandle ( pdb->idle_event );	
-      }
       break;
 
     default: