user: Fix WM_QUIT message ordering from PostQuitMessage.
Added a new server call as PostQuitMessage should set a flag in the
message queue to return the WM_QUIT message when there are no other
pending messages, rather than posting a message to the thread queue as
it does at the moment.
diff --git a/server/queue.c b/server/queue.c
index 3bc64d4..57b94b8 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -120,6 +120,8 @@
     unsigned int           changed_bits;    /* changed wakeup bits */
     unsigned int           changed_mask;    /* changed wakeup mask */
     int                    paint_count;     /* pending paint messages count */
+    int                    quit_message;    /* is there a pending quit message? */
+    int                    exit_code;       /* exit code of pending quit message */
     struct list            msg_list[NB_MSG_KINDS];  /* lists of messages */
     struct list            send_result;     /* stack of sent messages waiting for result */
     struct list            callback_result; /* list of callback messages waiting for result */
@@ -244,6 +246,7 @@
         queue->changed_bits    = 0;
         queue->changed_mask    = 0;
         queue->paint_count     = 0;
+        queue->quit_message    = 0;
         queue->recv_result     = NULL;
         queue->next_timer_id   = 1;
         queue->timeout         = NULL;
@@ -642,7 +645,6 @@
     /* check against the filters */
     LIST_FOR_EACH_ENTRY( msg, &queue->msg_list[POST_MESSAGE], struct message, entry )
     {
-        if (msg->msg == WM_QUIT) goto found;  /* WM_QUIT is never filtered */
         if (win && msg->win && msg->win != win && !is_child_window( win, msg->win )) continue;
         if (!check_msg_filter( msg->msg, first, last )) continue;
         goto found; /* found one */
@@ -682,6 +684,31 @@
     return 1;
 }
 
+static int get_quit_message( struct msg_queue *queue, unsigned int flags,
+                             struct get_message_reply *reply )
+{
+    if (queue->quit_message)
+    {
+        reply->total  = 0;
+        reply->type   = MSG_POSTED;
+        reply->win    = NULL;
+        reply->msg    = WM_QUIT;
+        reply->wparam = queue->exit_code;
+        reply->lparam = 0;
+        reply->x      = 0;
+        reply->y      = 0;
+        reply->time   = get_tick_count();
+        reply->info   = 0;
+
+        if (flags & GET_MSG_REMOVE)
+            queue->quit_message = 0;
+
+        return 1;
+    }
+    else
+        return 0;
+}
+
 /* empty a message list and free all the messages */
 static void empty_msg_list( struct list *list )
 {
@@ -1614,6 +1641,18 @@
     if (thread) release_object( thread );
 }
 
+/* post a quit message to the current queue */
+DECL_HANDLER(post_quit_message)
+{
+    struct msg_queue *queue = get_current_queue();
+
+    if (!queue)
+        return;
+
+    queue->quit_message = 1;
+    queue->exit_code = req->exit_code;
+    set_queue_bits( queue, QS_POSTMESSAGE|QS_ALLPOSTMESSAGE );
+}
 
 /* get a message from the current queue */
 DECL_HANDLER(get_message)
@@ -1645,6 +1684,11 @@
     if (get_posted_message( queue, get_win, req->get_first, req->get_last, req->flags, reply ))
         return;
 
+    /* only check for quit messages if not posted messages pending.
+     * note: the quit message isn't filtered */
+    if (get_quit_message( queue, req->flags, reply ))
+        return;
+
     /* then check for any raw hardware message */
     if (filter_contains_hw_range( req->get_first, req->get_last ) &&
         get_hardware_message( current, req->hw_id, get_win, req->get_first, req->get_last, reply ))