server: Split the queuing of hardware messages into a separate send_hardware_message request.
diff --git a/server/protocol.def b/server/protocol.def
index 25e93e9..27122ab 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -1571,9 +1571,6 @@
     unsigned int    msg;       /* message code */
     unsigned long   wparam;    /* parameters */
     unsigned long   lparam;    /* parameters */
-    int             x;         /* x position */
-    int             y;         /* y position */
-    unsigned int    time;      /* message time */
     unsigned int    info;      /* extra info */
     int             timeout;   /* timeout for reply */
     void*           callback;  /* callback address */
@@ -1599,6 +1596,20 @@
 #define SEND_MSG_ABORT_IF_HUNG  0x01
 
 
+/* Send a hardware message to a thread queue */
+@REQ(send_hardware_message)
+    thread_id_t     id;        /* thread id */
+    user_handle_t   win;       /* window handle */
+    unsigned int    msg;       /* message code */
+    unsigned long   wparam;    /* parameters */
+    unsigned long   lparam;    /* parameters */
+    int             x;         /* x position */
+    int             y;         /* y position */
+    unsigned int    time;      /* message time */
+    unsigned int    info;      /* extra info */
+@END
+
+
 /* Get a message from the current queue */
 @REQ(get_message)
     int             flags;     /* see below */
diff --git a/server/queue.c b/server/queue.c
index a292c80..7a77bd4 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -1569,24 +1569,15 @@
     struct msg_queue *recv_queue = NULL;
     struct thread *thread = NULL;
 
-    if (req->id)
-    {
-        if (!(thread = get_thread_from_id( req->id ))) return;
-    }
-    else if (req->type != MSG_HARDWARE)
-    {
-        /* only hardware messages are allowed without destination thread */
-        set_error( STATUS_INVALID_PARAMETER );
-        return;
-    }
+    if (!(thread = get_thread_from_id( req->id ))) return;
 
-    if (thread && !(recv_queue = thread->queue))
+    if (!(recv_queue = thread->queue))
     {
         set_error( STATUS_INVALID_PARAMETER );
         release_object( thread );
         return;
     }
-    if (recv_queue && (req->flags & SEND_MSG_ABORT_IF_HUNG) && is_queue_hung(recv_queue))
+    if ((req->flags & SEND_MSG_ABORT_IF_HUNG) && is_queue_hung(recv_queue))
     {
         set_error( STATUS_TIMEOUT );
         release_object( thread );
@@ -1600,9 +1591,9 @@
         msg->msg       = req->msg;
         msg->wparam    = req->wparam;
         msg->lparam    = req->lparam;
-        msg->time      = req->time;
-        msg->x         = req->x;
-        msg->y         = req->y;
+        msg->time      = get_tick_count();
+        msg->x         = 0;
+        msg->y         = 0;
         msg->info      = req->info;
         msg->hook      = 0;
         msg->hook_proc = NULL;
@@ -1645,9 +1636,7 @@
             list_add_tail( &recv_queue->msg_list[POST_MESSAGE], &msg->entry );
             set_queue_bits( recv_queue, QS_POSTMESSAGE|QS_ALLPOSTMESSAGE );
             break;
-        case MSG_HARDWARE:
-            queue_hardware_message( recv_queue, msg );
-            break;
+        case MSG_HARDWARE:  /* should use send_hardware_message instead */
         case MSG_CALLBACK_RESULT:  /* cannot send this one */
         default:
             set_error( STATUS_INVALID_PARAMETER );
@@ -1655,6 +1644,46 @@
             break;
         }
     }
+    release_object( thread );
+}
+
+/* send a hardware message to a thread queue */
+DECL_HANDLER(send_hardware_message)
+{
+    struct message *msg;
+    struct msg_queue *recv_queue = NULL;
+    struct thread *thread = NULL;
+
+    if (req->id)
+    {
+        if (!(thread = get_thread_from_id( req->id ))) return;
+    }
+
+    if (thread && !(recv_queue = thread->queue))
+    {
+        set_error( STATUS_INVALID_PARAMETER );
+        release_object( thread );
+        return;
+    }
+
+    if ((msg = mem_alloc( sizeof(*msg) )))
+    {
+        msg->type      = MSG_HARDWARE;
+        msg->win       = get_user_full_handle( req->win );
+        msg->msg       = req->msg;
+        msg->wparam    = req->wparam;
+        msg->lparam    = req->lparam;
+        msg->time      = req->time;
+        msg->x         = req->x;
+        msg->y         = req->y;
+        msg->info      = req->info;
+        msg->hook      = 0;
+        msg->hook_proc = NULL;
+        msg->result    = NULL;
+        msg->data      = NULL;
+        msg->data_size = 0;
+        queue_hardware_message( recv_queue, msg );
+    }
     if (thread) release_object( thread );
 }
 
diff --git a/server/request.h b/server/request.h
index a6d720a..751473f 100644
--- a/server/request.h
+++ b/server/request.h
@@ -233,6 +233,7 @@
 DECL_HANDLER(get_process_idle_event);
 DECL_HANDLER(send_message);
 DECL_HANDLER(post_quit_message);
+DECL_HANDLER(send_hardware_message);
 DECL_HANDLER(get_message);
 DECL_HANDLER(reply_message);
 DECL_HANDLER(accept_hardware_message);
@@ -452,6 +453,7 @@
     (req_handler)req_get_process_idle_event,
     (req_handler)req_send_message,
     (req_handler)req_post_quit_message,
+    (req_handler)req_send_hardware_message,
     (req_handler)req_get_message,
     (req_handler)req_reply_message,
     (req_handler)req_accept_hardware_message,
diff --git a/server/trace.c b/server/trace.c
index c5248fe..d4f8fed 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -2091,9 +2091,6 @@
     fprintf( stderr, " msg=%08x,", req->msg );
     fprintf( stderr, " wparam=%lx,", req->wparam );
     fprintf( stderr, " lparam=%lx,", req->lparam );
-    fprintf( stderr, " x=%d,", req->x );
-    fprintf( stderr, " y=%d,", req->y );
-    fprintf( stderr, " time=%08x,", req->time );
     fprintf( stderr, " info=%08x,", req->info );
     fprintf( stderr, " timeout=%d,", req->timeout );
     fprintf( stderr, " callback=%p,", req->callback );
@@ -2106,6 +2103,19 @@
     fprintf( stderr, " exit_code=%d", req->exit_code );
 }
 
+static void dump_send_hardware_message_request( const struct send_hardware_message_request *req )
+{
+    fprintf( stderr, " id=%04x,", req->id );
+    fprintf( stderr, " win=%p,", req->win );
+    fprintf( stderr, " msg=%08x,", req->msg );
+    fprintf( stderr, " wparam=%lx,", req->wparam );
+    fprintf( stderr, " lparam=%lx,", req->lparam );
+    fprintf( stderr, " x=%d,", req->x );
+    fprintf( stderr, " y=%d,", req->y );
+    fprintf( stderr, " time=%08x,", req->time );
+    fprintf( stderr, " info=%08x", req->info );
+}
+
 static void dump_get_message_request( const struct get_message_request *req )
 {
     fprintf( stderr, " flags=%d,", req->flags );
@@ -3396,6 +3406,7 @@
     (dump_func)dump_get_process_idle_event_request,
     (dump_func)dump_send_message_request,
     (dump_func)dump_post_quit_message_request,
+    (dump_func)dump_send_hardware_message_request,
     (dump_func)dump_get_message_request,
     (dump_func)dump_reply_message_request,
     (dump_func)dump_accept_hardware_message_request,
@@ -3612,6 +3623,7 @@
     (dump_func)dump_get_process_idle_event_reply,
     (dump_func)0,
     (dump_func)0,
+    (dump_func)0,
     (dump_func)dump_get_message_reply,
     (dump_func)0,
     (dump_func)0,
@@ -3828,6 +3840,7 @@
     "get_process_idle_event",
     "send_message",
     "post_quit_message",
+    "send_hardware_message",
     "get_message",
     "reply_message",
     "accept_hardware_message",