Moved hardware message queue handling to the server.
diff --git a/server/queue.c b/server/queue.c
index 678506e..ccbd1ea 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -37,6 +37,9 @@
unsigned int msg; /* message code */
unsigned int wparam; /* parameters */
unsigned int lparam; /* parameters */
+ unsigned short x; /* x position */
+ unsigned short y; /* y position */
+ unsigned int time; /* message time */
unsigned int info; /* extra info */
struct message_result *result; /* result in sender queue */
};
@@ -66,8 +69,7 @@
unsigned int wake_mask; /* wakeup mask */
unsigned int changed_bits; /* changed wakeup bits */
unsigned int changed_mask; /* changed wakeup mask */
- struct message_list send_list; /* list of sent messages */
- struct message_list post_list; /* list of posted messages */
+ struct message_list msg_list[NB_MSG_KINDS]; /* lists of messages */
struct message_result *send_result; /* stack of sent messages waiting for result */
struct message_result *recv_result; /* stack of received messages waiting for result */
struct timer *first_timer; /* head of timer list */
@@ -104,6 +106,7 @@
static struct msg_queue *create_msg_queue( struct thread *thread )
{
struct msg_queue *queue;
+ int i;
if ((queue = alloc_object( &msg_queue_ops, -1 )))
{
@@ -111,16 +114,15 @@
queue->wake_mask = 0;
queue->changed_bits = 0;
queue->changed_mask = 0;
- queue->send_list.first = NULL;
- queue->send_list.last = NULL;
- queue->post_list.first = NULL;
- queue->post_list.last = NULL;
queue->send_result = NULL;
queue->recv_result = NULL;
queue->first_timer = NULL;
queue->last_timer = NULL;
queue->next_timer = NULL;
queue->timeout = NULL;
+ for (i = 0; i < NB_MSG_KINDS; i++)
+ queue->msg_list[i].first = queue->msg_list[i].last = NULL;
+
thread->queue = queue;
if (!thread->process->queue)
thread->process->queue = (struct msg_queue *)grab_object( queue );
@@ -142,6 +144,14 @@
if (is_signaled( queue )) wake_up( &queue->obj, 0 );
}
+/* get the QS_* bit corresponding to a given hardware message */
+inline static int get_hardware_msg_bit( struct message *msg )
+{
+ if (msg->msg == WM_MOUSEMOVE || msg->msg == WM_NCMOUSEMOVE) return QS_MOUSEMOVE;
+ if (msg->msg >= WM_KEYFIRST && msg->msg <= WM_KEYLAST) return QS_KEY;
+ return QS_MOUSEBUTTON;
+}
+
/* get the current thread queue, creating it if needed */
inline struct msg_queue *get_current_queue(void)
{
@@ -189,20 +199,31 @@
free( msg );
}
-/* remove (and free) a message from the sent messages list */
-static void remove_sent_message( struct msg_queue *queue, struct message *msg )
+/* remove (and free) a message from a message list */
+static void remove_queue_message( struct msg_queue *queue, struct message *msg,
+ enum message_kind kind )
{
- unlink_message( &queue->send_list, msg );
- free_message( msg );
- if (!queue->send_list.first) change_queue_bits( queue, 0, QS_SENDMESSAGE );
-}
+ int clr_bit;
+ struct message *other;
-/* remove (and free) a message from the posted messages list */
-static void remove_posted_message( struct msg_queue *queue, struct message *msg )
-{
- unlink_message( &queue->post_list, msg );
+ unlink_message( &queue->msg_list[kind], msg );
+ switch(kind)
+ {
+ case SEND_MESSAGE:
+ if (!queue->msg_list[kind].first) change_queue_bits( queue, 0, QS_SENDMESSAGE );
+ break;
+ case POST_MESSAGE:
+ if (!queue->msg_list[kind].first) change_queue_bits( queue, 0, QS_POSTMESSAGE );
+ break;
+ case COOKED_HW_MESSAGE:
+ case RAW_HW_MESSAGE:
+ clr_bit = get_hardware_msg_bit( msg );
+ for (other = queue->msg_list[kind].first; other; other = other->next)
+ if (get_hardware_msg_bit( other ) == clr_bit) break;
+ if (!other) change_queue_bits( queue, 0, clr_bit );
+ break;
+ }
free_message( msg );
- if (!queue->post_list.first) change_queue_bits( queue, 0, QS_POSTMESSAGE );
}
/* send a message from the sender queue to the receiver queue */
@@ -221,7 +242,7 @@
/* and put the message on the receiver queue */
msg->result = result;
- append_message( &recv_queue->send_list, msg );
+ append_message( &recv_queue->msg_list[SEND_MESSAGE], msg );
change_queue_bits( recv_queue, QS_SENDMESSAGE, 0 );
return 1;
}
@@ -231,12 +252,12 @@
{
struct message_result *result = msg->result;
- unlink_message( &queue->send_list, msg );
+ unlink_message( &queue->msg_list[SEND_MESSAGE], msg );
/* put the result on the receiver result stack */
result->recv_next = queue->recv_result;
queue->recv_result = result;
free( msg );
- if (!queue->send_list.first) change_queue_bits( queue, 0, QS_SENDMESSAGE );
+ if (!queue->msg_list[SEND_MESSAGE].first) change_queue_bits( queue, 0, QS_SENDMESSAGE );
}
/* set the result of the current received message */
@@ -380,10 +401,10 @@
{
struct msg_queue *queue = (struct msg_queue *)obj;
struct timer *timer = queue->first_timer;
+ int i;
cleanup_results( queue );
- empty_msg_list( &queue->send_list );
- empty_msg_list( &queue->post_list );
+ for (i = 0; i < NB_MSG_KINDS; i++) empty_msg_list( &queue->msg_list[i] );
while (timer)
{
@@ -457,6 +478,7 @@
else queue->first_timer = timer->next;
/* check if we removed the next timer */
if (queue->next_timer == timer) set_next_timer( queue, timer->next );
+ else if (queue->next_timer == queue->first_timer) change_queue_bits( queue, 0, QS_TIMER );
}
/* restart an expired timer */
@@ -521,6 +543,7 @@
{
struct timer *timer;
struct message *msg;
+ int i;
/* remove timers */
timer = queue->first_timer;
@@ -535,22 +558,16 @@
timer = next;
}
- /* remove sent messages */
- msg = queue->send_list.first;
- while (msg)
+ /* remove messages */
+ for (i = 0; i < NB_MSG_KINDS; i++)
{
- struct message *next = msg->next;
- if (msg->win == win) remove_sent_message( queue, msg );
- msg = next;
- }
-
- /* remove posted messages */
- msg = queue->post_list.first;
- while (msg)
- {
- struct message *next = msg->next;
- if (msg->win == win) remove_posted_message( queue, msg );
- msg = next;
+ msg = queue->msg_list[i].first;
+ while (msg)
+ {
+ struct message *next = msg->next;
+ if (msg->win == win) remove_queue_message( queue, msg, i );
+ msg = next;
+ }
}
}
@@ -638,18 +655,65 @@
msg->msg = req->msg;
msg->wparam = req->wparam;
msg->lparam = req->lparam;
+ msg->x = req->x;
+ msg->y = req->y;
+ msg->time = req->time;
msg->info = req->info;
msg->result = NULL;
- if (!req->posted) send_message( send_queue, recv_queue, msg );
- else
+ switch(req->kind)
{
- append_message( &recv_queue->post_list, msg );
+ case SEND_MESSAGE:
+ send_message( send_queue, recv_queue, msg );
+ break;
+ case POST_MESSAGE:
+ append_message( &recv_queue->msg_list[POST_MESSAGE], msg );
change_queue_bits( recv_queue, QS_POSTMESSAGE, 0 );
+ break;
+ case COOKED_HW_MESSAGE:
+ case RAW_HW_MESSAGE:
+ append_message( &recv_queue->msg_list[req->kind], msg );
+ change_queue_bits( recv_queue, get_hardware_msg_bit(msg), 0 );
+ break;
+ default:
+ free( msg );
+ set_error( STATUS_INVALID_PARAMETER );
+ break;
}
}
release_object( thread );
}
+/* store a message contents into the request buffer; helper for get_message */
+inline static void put_req_message( struct get_message_request *req, const struct message *msg )
+{
+ req->type = msg->type;
+ req->win = msg->win;
+ req->msg = msg->msg;
+ req->wparam = msg->wparam;
+ req->lparam = msg->lparam;
+ req->x = msg->x;
+ req->y = msg->y;
+ req->time = msg->time;
+ req->info = msg->info;
+}
+
+inline static struct message *find_matching_message( const struct message_list *list, handle_t win,
+ unsigned int first, unsigned int last )
+{
+ struct message *msg;
+
+ for (msg = list->first; msg; msg = msg->next)
+ {
+ /* check against the filters */
+ if (win && msg->win && msg->win != win) continue;
+ if (msg->msg < first) continue;
+ if (msg->msg > last) continue;
+ break; /* found one */
+ }
+ return msg;
+}
+
+
/* get a message from the current queue */
DECL_HANDLER(get_message)
{
@@ -660,62 +724,75 @@
if (!queue) return;
/* first check for sent messages */
- if ((msg = queue->send_list.first))
+ if ((msg = queue->msg_list[SEND_MESSAGE].first))
{
- req->sent = 1;
- req->type = msg->type;
- req->win = msg->win;
- req->msg = msg->msg;
- req->wparam = msg->wparam;
- req->lparam = msg->lparam;
- req->info = msg->info;
+ req->kind = SEND_MESSAGE;
+ put_req_message( req, msg );
receive_message( queue, msg );
return;
}
- if (!req->posted) goto done; /* nothing else to check */
+ if (req->flags & GET_MSG_SENT_ONLY) goto done; /* nothing else to check */
- /* then try a posted message */
- req->sent = 0;
- for (msg = queue->post_list.first; msg; msg = msg->next)
+ /* then check for posted messages */
+ if ((msg = find_matching_message( &queue->msg_list[POST_MESSAGE], req->get_win,
+ req->get_first, req->get_last )))
{
- /* check against the filters */
- if (req->get_win && msg->win != req->get_win) continue;
- if (msg->msg >= req->get_first && msg->msg <= req->get_last)
- {
- /* found one */
- req->type = msg->type;
- req->win = msg->win;
- req->msg = msg->msg;
- req->wparam = msg->wparam;
- req->lparam = msg->lparam;
- req->info = msg->info;
- if (req->remove) remove_posted_message( queue, msg );
- return;
- }
+ req->kind = POST_MESSAGE;
+ put_req_message( req, msg );
+ if (req->flags & GET_MSG_REMOVE) remove_queue_message( queue, msg, POST_MESSAGE );
+ return;
+ }
+
+ /* then check for cooked hardware messages */
+ if ((msg = find_matching_message( &queue->msg_list[COOKED_HW_MESSAGE], req->get_win,
+ req->get_first, req->get_last )))
+ {
+ req->kind = COOKED_HW_MESSAGE;
+ put_req_message( req, msg );
+ if (req->flags & GET_MSG_REMOVE) remove_queue_message( queue, msg, COOKED_HW_MESSAGE );
+ return;
+ }
+
+ /* then check for any raw hardware message */
+ if ((msg = queue->msg_list[RAW_HW_MESSAGE].first))
+ {
+ req->kind = RAW_HW_MESSAGE;
+ put_req_message( req, msg );
+ /* raw messages always get removed */
+ remove_queue_message( queue, msg, RAW_HW_MESSAGE );
+ return;
}
/* now check for WM_PAINT */
if ((queue->wake_bits & QS_PAINT) &&
(WM_PAINT >= req->get_first) && (WM_PAINT <= req->get_last))
{
+ req->kind = POST_MESSAGE;
req->type = 0;
req->win = 0;
req->msg = WM_PAINT;
req->wparam = 0;
req->lparam = 0;
+ req->x = 0;
+ req->y = 0;
+ req->time = 0;
req->info = 0;
return;
}
/* now check for timer */
if ((timer = find_expired_timer( queue, req->get_win, req->get_first,
- req->get_last, req->remove )))
+ req->get_last, (req->flags & GET_MSG_REMOVE) )))
{
+ req->kind = POST_MESSAGE;
req->type = 0;
req->win = timer->win;
req->msg = timer->msg;
req->wparam = timer->id;
req->lparam = timer->lparam;
+ req->x = 0;
+ req->y = 0;
+ req->time = 0;
req->info = 0;
return;
}
diff --git a/server/trace.c b/server/trace.c
index a0f1fc2..2876fbd 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -1464,20 +1464,22 @@
static void dump_send_message_request( const struct send_message_request *req )
{
- fprintf( stderr, " posted=%d,", req->posted );
+ fprintf( stderr, " kind=%d,", req->kind );
fprintf( stderr, " id=%p,", req->id );
fprintf( stderr, " type=%d,", req->type );
fprintf( stderr, " win=%d,", req->win );
fprintf( stderr, " msg=%08x,", req->msg );
fprintf( stderr, " wparam=%08x,", req->wparam );
fprintf( stderr, " lparam=%08x,", req->lparam );
+ fprintf( stderr, " x=%04x,", req->x );
+ fprintf( stderr, " y=%04x,", 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, " remove=%d,", req->remove );
- fprintf( stderr, " posted=%d,", req->posted );
+ fprintf( stderr, " flags=%d,", req->flags );
fprintf( stderr, " get_win=%d,", req->get_win );
fprintf( stderr, " get_first=%08x,", req->get_first );
fprintf( stderr, " get_last=%08x", req->get_last );
@@ -1485,12 +1487,15 @@
static void dump_get_message_reply( const struct get_message_request *req )
{
- fprintf( stderr, " sent=%d,", req->sent );
+ fprintf( stderr, " kind=%d,", req->kind );
fprintf( stderr, " type=%d,", req->type );
fprintf( stderr, " win=%d,", req->win );
fprintf( stderr, " msg=%08x,", req->msg );
fprintf( stderr, " wparam=%08x,", req->wparam );
fprintf( stderr, " lparam=%08x,", req->lparam );
+ fprintf( stderr, " x=%04x,", req->x );
+ fprintf( stderr, " y=%04x,", req->y );
+ fprintf( stderr, " time=%08x,", req->time );
fprintf( stderr, " info=%08x", req->info );
}