Moved hardware message queue handling to the server.
This commit is contained in:
parent
4b29d669fc
commit
838d65aebe
|
@ -197,7 +197,6 @@ static void tweak_init(void)
|
|||
static BOOL process_attach(void)
|
||||
{
|
||||
HINSTANCE16 instance;
|
||||
int queueSize;
|
||||
|
||||
/* Create USER heap */
|
||||
if ((instance = LoadLibrary16( "USER.EXE" )) < 32) return FALSE;
|
||||
|
@ -232,10 +231,6 @@ static BOOL process_attach(void)
|
|||
/* Initialize message spying */
|
||||
if (!SPY_Init()) return FALSE;
|
||||
|
||||
/* Create system message queue */
|
||||
queueSize = GetProfileIntA( "windows", "TypeAhead", 120 );
|
||||
if (!QUEUE_CreateSysMsgQueue( queueSize )) return FALSE;
|
||||
|
||||
/* Set double click time */
|
||||
SetDoubleClickTime( GetProfileIntA("windows","DoubleClickSpeed",452) );
|
||||
|
||||
|
|
|
@ -897,7 +897,8 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode )
|
|||
if (!ret)
|
||||
{
|
||||
WIN_UnlinkWindow( hwnd );
|
||||
goto failed;
|
||||
X11DRV_DestroyWindow( hwnd );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Send the size messages */
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
/* Message as stored in the queue (contains the extraInfo field) */
|
||||
typedef struct tagQMSG
|
||||
{
|
||||
int kind; /* message kind (sent,posted,hardware) */
|
||||
int type;
|
||||
MSG msg;
|
||||
DWORD extraInfo; /* Only in 3.1 */
|
||||
|
@ -98,22 +99,16 @@ extern void QUEUE_Unlock( MESSAGEQUEUE *queue );
|
|||
extern void QUEUE_DumpQueue( HQUEUE16 hQueue );
|
||||
extern BOOL QUEUE_IsExitingQueue( HQUEUE16 hQueue );
|
||||
extern void QUEUE_SetExitingQueue( HQUEUE16 hQueue );
|
||||
extern MESSAGEQUEUE *QUEUE_GetSysQueue(void);
|
||||
extern void QUEUE_SetWakeBit( MESSAGEQUEUE *queue, WORD set, WORD clear );
|
||||
extern void QUEUE_ClearWakeBit( MESSAGEQUEUE *queue, WORD bit );
|
||||
extern WORD QUEUE_TestWakeBit( MESSAGEQUEUE *queue, WORD bit );
|
||||
extern int QUEUE_WaitBits( WORD bits, DWORD timeout );
|
||||
extern void QUEUE_IncPaintCount( HQUEUE16 hQueue );
|
||||
extern void QUEUE_DecPaintCount( HQUEUE16 hQueue );
|
||||
extern BOOL QUEUE_CreateSysMsgQueue( int size );
|
||||
extern BOOL QUEUE_DeleteMsgQueue( HQUEUE16 hQueue );
|
||||
extern HTASK16 QUEUE_GetQueueTask( HQUEUE16 hQueue );
|
||||
extern BOOL QUEUE_FindMsg( HWND hwnd, UINT first, UINT last, BOOL remove,
|
||||
BOOL sent_only, QMSG *msg );
|
||||
extern BOOL QUEUE_FindMsg( HWND hwnd, UINT first, UINT last, BOOL remove, QMSG *msg );
|
||||
extern void QUEUE_RemoveMsg( MESSAGEQUEUE * msgQueue, QMSG *qmsg );
|
||||
extern void QUEUE_CleanupWindow( HWND hwnd );
|
||||
extern void hardware_event( UINT message, WPARAM wParam, LPARAM lParam,
|
||||
int xPos, int yPos, DWORD time, DWORD extraInfo );
|
||||
|
||||
extern HQUEUE16 WINAPI InitThreadInput16( WORD unknown, WORD flags );
|
||||
|
||||
|
|
|
@ -1345,34 +1345,43 @@ struct wait_input_idle_request
|
|||
struct send_message_request
|
||||
{
|
||||
REQUEST_HEADER; /* request header */
|
||||
IN int posted; /* posted instead of sent message? */
|
||||
IN int kind; /* message kind (see below) */
|
||||
IN void* id; /* thread id */
|
||||
IN int type; /* message type */
|
||||
IN handle_t win; /* window handle */
|
||||
IN unsigned int msg; /* message code */
|
||||
IN unsigned int wparam; /* parameters */
|
||||
IN unsigned int lparam; /* parameters */
|
||||
IN unsigned short x; /* x position */
|
||||
IN unsigned short y; /* y position */
|
||||
IN unsigned int time; /* message time */
|
||||
IN unsigned int info; /* extra info */
|
||||
};
|
||||
enum message_kind { SEND_MESSAGE, POST_MESSAGE, COOKED_HW_MESSAGE, RAW_HW_MESSAGE };
|
||||
#define NB_MSG_KINDS (RAW_HW_MESSAGE+1)
|
||||
|
||||
|
||||
/* Get a message from the current queue */
|
||||
struct get_message_request
|
||||
{
|
||||
REQUEST_HEADER; /* request header */
|
||||
IN int remove; /* remove it? */
|
||||
IN int posted; /* check posted messages too? */
|
||||
IN int flags; /* see below */
|
||||
IN handle_t get_win; /* window handle to get */
|
||||
IN unsigned int get_first; /* first message code to get */
|
||||
IN unsigned int get_last; /* last message code to get */
|
||||
OUT int sent; /* it is a sent message */
|
||||
OUT int kind; /* message kind */
|
||||
OUT int type; /* message type */
|
||||
OUT handle_t win; /* window handle */
|
||||
OUT unsigned int msg; /* message code */
|
||||
OUT unsigned int wparam; /* parameters */
|
||||
OUT unsigned int lparam; /* parameters */
|
||||
OUT unsigned short x; /* x position */
|
||||
OUT unsigned short y; /* y position */
|
||||
OUT unsigned int time; /* message time */
|
||||
OUT unsigned int info; /* extra info */
|
||||
};
|
||||
#define GET_MSG_REMOVE 1 /* remove the message */
|
||||
#define GET_MSG_SENT_ONLY 2 /* only get sent messages */
|
||||
|
||||
|
||||
/* Reply to a sent message */
|
||||
|
@ -1734,7 +1743,7 @@ union generic_request
|
|||
struct create_async_request create_async;
|
||||
};
|
||||
|
||||
#define SERVER_PROTOCOL_VERSION 45
|
||||
#define SERVER_PROTOCOL_VERSION 46
|
||||
|
||||
/* ### make_requests end ### */
|
||||
/* Everything above this line is generated automatically by tools/make_requests */
|
||||
|
|
211
server/queue.c
211
server/queue.c
|
@ -37,6 +37,9 @@ struct message
|
|||
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 @@ struct msg_queue
|
|||
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 const struct object_ops msg_queue_ops =
|
|||
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 @@ static struct msg_queue *create_msg_queue( struct thread *thread )
|
|||
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 @@ inline static void change_queue_bits( struct msg_queue *queue, unsigned int set,
|
|||
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 @@ static void free_message( struct message *msg )
|
|||
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 @@ static int send_message( struct msg_queue *send_queue, struct msg_queue *recv_qu
|
|||
|
||||
/* 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 @@ static void receive_message( struct msg_queue *queue, struct message *msg )
|
|||
{
|
||||
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 @@ static void msg_queue_destroy( struct object *obj )
|
|||
{
|
||||
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 @@ static void unlink_timer( struct msg_queue *queue, struct timer *timer )
|
|||
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 @@ static void cleanup_window( struct msg_queue *queue, handle_t win )
|
|||
{
|
||||
struct timer *timer;
|
||||
struct message *msg;
|
||||
int i;
|
||||
|
||||
/* remove timers */
|
||||
timer = queue->first_timer;
|
||||
|
@ -535,22 +558,16 @@ static void cleanup_window( struct msg_queue *queue, handle_t win )
|
|||
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 @@ DECL_HANDLER(send_message)
|
|||
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 @@ DECL_HANDLER(get_message)
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -1464,20 +1464,22 @@ static void dump_wait_input_idle_reply( const struct wait_input_idle_request *re
|
|||
|
||||
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_request( const struct get_message_request *req )
|
|||
|
||||
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 );
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
"int" => "%d",
|
||||
"char" => "%c",
|
||||
"unsigned char" => "%02x",
|
||||
"unsigned short"=> "%04x",
|
||||
"unsigned int" => "%08x",
|
||||
"void*" => "%p",
|
||||
"time_t" => "%ld",
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "wine/winbase16.h"
|
||||
#include "wine/winuser16.h"
|
||||
#include "wine/keyboard16.h"
|
||||
#include "server.h"
|
||||
#include "win.h"
|
||||
#include "heap.h"
|
||||
#include "input.h"
|
||||
|
@ -33,10 +34,10 @@
|
|||
#include "debugtools.h"
|
||||
#include "winerror.h"
|
||||
|
||||
DECLARE_DEBUG_CHANNEL(event);
|
||||
DECLARE_DEBUG_CHANNEL(key);
|
||||
DECLARE_DEBUG_CHANNEL(keyboard);
|
||||
DECLARE_DEBUG_CHANNEL(win);
|
||||
DEFAULT_DEBUG_CHANNEL(event);
|
||||
|
||||
static BOOL InputEnabled = TRUE;
|
||||
static BOOL SwappedButtons;
|
||||
|
@ -73,6 +74,35 @@ typedef union
|
|||
unsigned long lp2;
|
||||
} KEYLP;
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* queue_raw_hardware_message
|
||||
*
|
||||
* Add a message to the raw hardware queue.
|
||||
* Note: the position is relative to the desktop window.
|
||||
*/
|
||||
static void queue_raw_hardware_message( UINT message, WPARAM wParam, LPARAM lParam,
|
||||
int xPos, int yPos, DWORD time, DWORD extraInfo )
|
||||
{
|
||||
SERVER_START_REQ( send_message )
|
||||
{
|
||||
req->kind = RAW_HW_MESSAGE;
|
||||
req->id = (void *)GetCurrentThreadId();
|
||||
req->type = QMSG_HARDWARE;
|
||||
req->win = 0;
|
||||
req->msg = message;
|
||||
req->wparam = wParam;
|
||||
req->lparam = lParam;
|
||||
req->x = xPos;
|
||||
req->y = yPos;
|
||||
req->time = time;
|
||||
req->info = extraInfo;
|
||||
SERVER_CALL();
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* keybd_event (USER32.@)
|
||||
*/
|
||||
|
@ -147,7 +177,7 @@ void WINAPI keybd_event( BYTE bVk, BYTE bScan,
|
|||
TRACE_(key)(" wParam=%04X, lParam=%08lX\n", bVk, keylp.lp2 );
|
||||
TRACE_(key)(" InputKeyState=%X\n", InputKeyStateTable[bVk] );
|
||||
|
||||
hardware_event( message, bVk, keylp.lp2, PosX, PosY, time, extra );
|
||||
queue_raw_hardware_message( message, bVk, keylp.lp2, PosX, PosY, time, extra );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -242,49 +272,41 @@ void WINAPI mouse_event( DWORD dwFlags, DWORD dx, DWORD dy,
|
|||
|
||||
if ( dwFlags & MOUSEEVENTF_MOVE )
|
||||
{
|
||||
hardware_event( WM_MOUSEMOVE,
|
||||
keyState, 0L, PosX, PosY, time, extra );
|
||||
queue_raw_hardware_message( WM_MOUSEMOVE, keyState, 0, PosX, PosY, time, extra );
|
||||
}
|
||||
if ( dwFlags & (!SwappedButtons? MOUSEEVENTF_LEFTDOWN : MOUSEEVENTF_RIGHTDOWN) )
|
||||
{
|
||||
MouseButtonsStates[0] = AsyncMouseButtonsStates[0] = TRUE;
|
||||
hardware_event( WM_LBUTTONDOWN,
|
||||
keyState, 0L, PosX, PosY, time, extra );
|
||||
queue_raw_hardware_message( WM_LBUTTONDOWN, keyState, 0, PosX, PosY, time, extra );
|
||||
}
|
||||
if ( dwFlags & (!SwappedButtons? MOUSEEVENTF_LEFTUP : MOUSEEVENTF_RIGHTUP) )
|
||||
{
|
||||
MouseButtonsStates[0] = FALSE;
|
||||
hardware_event( WM_LBUTTONUP,
|
||||
keyState, 0L, PosX, PosY, time, extra );
|
||||
queue_raw_hardware_message( WM_LBUTTONUP, keyState, 0, PosX, PosY, time, extra );
|
||||
}
|
||||
if ( dwFlags & (!SwappedButtons? MOUSEEVENTF_RIGHTDOWN : MOUSEEVENTF_LEFTDOWN) )
|
||||
{
|
||||
MouseButtonsStates[2] = AsyncMouseButtonsStates[2] = TRUE;
|
||||
hardware_event( WM_RBUTTONDOWN,
|
||||
keyState, 0L, PosX, PosY, time, extra );
|
||||
queue_raw_hardware_message( WM_RBUTTONDOWN, keyState, 0, PosX, PosY, time, extra );
|
||||
}
|
||||
if ( dwFlags & (!SwappedButtons? MOUSEEVENTF_RIGHTUP : MOUSEEVENTF_LEFTUP) )
|
||||
{
|
||||
MouseButtonsStates[2] = FALSE;
|
||||
hardware_event( WM_RBUTTONUP,
|
||||
keyState, 0L, PosX, PosY, time, extra );
|
||||
queue_raw_hardware_message( WM_RBUTTONUP, keyState, 0, PosX, PosY, time, extra );
|
||||
}
|
||||
if ( dwFlags & MOUSEEVENTF_MIDDLEDOWN )
|
||||
{
|
||||
MouseButtonsStates[1] = AsyncMouseButtonsStates[1] = TRUE;
|
||||
hardware_event( WM_MBUTTONDOWN,
|
||||
keyState, 0L, PosX, PosY, time, extra );
|
||||
queue_raw_hardware_message( WM_MBUTTONDOWN, keyState, 0, PosX, PosY, time, extra );
|
||||
}
|
||||
if ( dwFlags & MOUSEEVENTF_MIDDLEUP )
|
||||
{
|
||||
MouseButtonsStates[1] = FALSE;
|
||||
hardware_event( WM_MBUTTONUP,
|
||||
keyState, 0L, PosX, PosY, time, extra );
|
||||
queue_raw_hardware_message( WM_MBUTTONUP, keyState, 0, PosX, PosY, time, extra );
|
||||
}
|
||||
if ( dwFlags & MOUSEEVENTF_WHEEL )
|
||||
{
|
||||
hardware_event( WM_MOUSEWHEEL,
|
||||
keyState, 0L, PosX, PosY, time, extra );
|
||||
queue_raw_hardware_message( WM_MOUSEWHEEL, keyState, 0, PosX, PosY, time, extra );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
1165
windows/message.c
1165
windows/message.c
File diff suppressed because it is too large
Load Diff
397
windows/queue.c
397
windows/queue.c
|
@ -21,20 +21,13 @@
|
|||
#include "server.h"
|
||||
#include "spy.h"
|
||||
|
||||
DECLARE_DEBUG_CHANNEL(sendmsg);
|
||||
DEFAULT_DEBUG_CHANNEL(msg);
|
||||
|
||||
#define MAX_QUEUE_SIZE 120 /* Max. size of a message queue */
|
||||
|
||||
static HQUEUE16 hExitingQueue = 0;
|
||||
static HQUEUE16 hmemSysMsgQueue = 0;
|
||||
static MESSAGEQUEUE *sysMsgQueue = NULL;
|
||||
static PERQUEUEDATA *pQDataWin16 = NULL; /* Global perQData for Win16 tasks */
|
||||
|
||||
static MESSAGEQUEUE *pMouseQueue = NULL; /* Queue for last mouse message */
|
||||
static MESSAGEQUEUE *pKbdQueue = NULL; /* Queue for last kbd message */
|
||||
|
||||
HQUEUE16 hCursorQueue = 0;
|
||||
HQUEUE16 hActiveQueue = 0;
|
||||
|
||||
|
||||
|
@ -471,7 +464,6 @@ BOOL QUEUE_DeleteMsgQueue( HQUEUE16 hQueue )
|
|||
|
||||
msgQueue->magic = 0;
|
||||
|
||||
if( hCursorQueue == hQueue ) hCursorQueue = 0;
|
||||
if( hActiveQueue == hQueue ) hActiveQueue = 0;
|
||||
|
||||
HeapLock( GetProcessHeap() ); /* FIXME: a bit overkill */
|
||||
|
@ -496,142 +488,10 @@ BOOL QUEUE_DeleteMsgQueue( HQUEUE16 hQueue )
|
|||
|
||||
|
||||
/***********************************************************************
|
||||
* QUEUE_CreateSysMsgQueue
|
||||
* handle_sent_message
|
||||
*
|
||||
* Create the system message queue, and set the double-click speed.
|
||||
* Must be called only once.
|
||||
* Handle the reception of a sent message by calling the corresponding window proc
|
||||
*/
|
||||
BOOL QUEUE_CreateSysMsgQueue( int size )
|
||||
{
|
||||
/* Note: We dont need perQ data for the system message queue */
|
||||
if (!(hmemSysMsgQueue = QUEUE_CreateMsgQueue( FALSE )))
|
||||
return FALSE;
|
||||
FarSetOwner16( hmemSysMsgQueue, 0 );
|
||||
sysMsgQueue = (MESSAGEQUEUE *) GlobalLock16( hmemSysMsgQueue );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* QUEUE_GetSysQueue
|
||||
*/
|
||||
MESSAGEQUEUE *QUEUE_GetSysQueue(void)
|
||||
{
|
||||
return sysMsgQueue;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* QUEUE_SetWakeBit
|
||||
*
|
||||
* See "Windows Internals", p.449
|
||||
*/
|
||||
static BOOL QUEUE_TrySetWakeBit( MESSAGEQUEUE *queue, WORD set, WORD clear, BOOL always )
|
||||
{
|
||||
BOOL wake = FALSE;
|
||||
|
||||
TRACE_(msg)("queue = %04x, set = %04x, clear = %04x, always = %d\n",
|
||||
queue->self, set, clear, always );
|
||||
if (!queue->server_queue) return FALSE;
|
||||
|
||||
SERVER_START_REQ( set_queue_bits )
|
||||
{
|
||||
req->handle = queue->server_queue;
|
||||
req->set = set;
|
||||
req->clear = clear;
|
||||
req->mask_cond = always ? 0 : set;
|
||||
if (!SERVER_CALL()) wake = (req->changed_mask & set) != 0;
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
if (wake || always)
|
||||
{
|
||||
if (set & QS_MOUSE) pMouseQueue = queue;
|
||||
if (set & QS_KEY) pKbdQueue = queue;
|
||||
}
|
||||
return wake;
|
||||
}
|
||||
void QUEUE_SetWakeBit( MESSAGEQUEUE *queue, WORD set, WORD clear )
|
||||
{
|
||||
QUEUE_TrySetWakeBit( queue, set, clear, TRUE );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* QUEUE_ClearWakeBit
|
||||
*/
|
||||
void QUEUE_ClearWakeBit( MESSAGEQUEUE *queue, WORD bit )
|
||||
{
|
||||
QUEUE_SetWakeBit( queue, 0, bit );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* QUEUE_WaitBits
|
||||
*
|
||||
* See "Windows Internals", p.447
|
||||
*
|
||||
* return values:
|
||||
* 0 if exit with timeout
|
||||
* 1 otherwise
|
||||
*/
|
||||
int QUEUE_WaitBits( WORD bits, DWORD timeout )
|
||||
{
|
||||
MESSAGEQUEUE *queue;
|
||||
HQUEUE16 hQueue;
|
||||
|
||||
TRACE_(msg)("q %04x waiting for %04x\n", GetFastQueue16(), bits);
|
||||
|
||||
hQueue = GetFastQueue16();
|
||||
if (!(queue = QUEUE_Lock( hQueue ))) return 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
unsigned int wake_bits = 0, changed_bits = 0;
|
||||
DWORD dwlc;
|
||||
|
||||
SERVER_START_REQ( set_queue_mask )
|
||||
{
|
||||
req->wake_mask = QS_SENDMESSAGE;
|
||||
req->changed_mask = bits | QS_SENDMESSAGE;
|
||||
req->skip_wait = 1;
|
||||
if (!SERVER_CALL())
|
||||
{
|
||||
wake_bits = req->wake_bits;
|
||||
changed_bits = req->changed_bits;
|
||||
}
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
if (changed_bits & bits)
|
||||
{
|
||||
/* One of the bits is set; we can return */
|
||||
QUEUE_Unlock( queue );
|
||||
return 1;
|
||||
}
|
||||
if (wake_bits & QS_SENDMESSAGE)
|
||||
{
|
||||
/* Process the sent message immediately */
|
||||
QMSG msg;
|
||||
QUEUE_FindMsg( 0, 0, 0, TRUE, TRUE, &msg );
|
||||
continue; /* nested sm crux */
|
||||
}
|
||||
|
||||
TRACE_(msg)("(%04x) mask=%08x, bits=%08x, changed=%08x, waiting\n",
|
||||
queue->self, bits, wake_bits, changed_bits );
|
||||
|
||||
ReleaseThunkLock( &dwlc );
|
||||
if (dwlc) TRACE_(msg)("had win16 lock\n");
|
||||
|
||||
if (USER_Driver.pMsgWaitForMultipleObjectsEx)
|
||||
USER_Driver.pMsgWaitForMultipleObjectsEx( 1, &queue->server_queue, timeout, 0, 0 );
|
||||
else
|
||||
WaitForSingleObject( queue->server_queue, timeout );
|
||||
if (dwlc) RestoreThunkLock( dwlc );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* handle the reception of a sent message by calling the corresponding window proc */
|
||||
static void handle_sent_message( QMSG *msg )
|
||||
{
|
||||
LRESULT result = 0;
|
||||
|
@ -679,14 +539,151 @@ static void handle_sent_message( QMSG *msg )
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* process_sent_messages
|
||||
*
|
||||
* Process all pending sent messages
|
||||
*/
|
||||
static void process_sent_messages(void)
|
||||
{
|
||||
QMSG msg;
|
||||
unsigned int res;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
SERVER_START_REQ( get_message )
|
||||
{
|
||||
req->flags = GET_MSG_REMOVE | GET_MSG_SENT_ONLY;
|
||||
req->get_win = 0;
|
||||
req->get_first = 0;
|
||||
req->get_last = ~0;
|
||||
if (!(res = SERVER_CALL()))
|
||||
{
|
||||
msg.type = req->type;
|
||||
msg.msg.hwnd = req->win;
|
||||
msg.msg.message = req->msg;
|
||||
msg.msg.wParam = req->wparam;
|
||||
msg.msg.lParam = req->lparam;
|
||||
msg.msg.time = req->time;
|
||||
msg.msg.pt.x = req->x;
|
||||
msg.msg.pt.y = req->y;
|
||||
msg.extraInfo = req->info;
|
||||
}
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
if (res) break;
|
||||
handle_sent_message( &msg );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* QUEUE_SetWakeBit
|
||||
*
|
||||
* See "Windows Internals", p.449
|
||||
*/
|
||||
void QUEUE_SetWakeBit( MESSAGEQUEUE *queue, WORD set, WORD clear )
|
||||
{
|
||||
TRACE_(msg)("queue = %04x, set = %04x, clear = %04x\n",
|
||||
queue->self, set, clear );
|
||||
if (!queue->server_queue) return;
|
||||
|
||||
SERVER_START_REQ( set_queue_bits )
|
||||
{
|
||||
req->handle = queue->server_queue;
|
||||
req->set = set;
|
||||
req->clear = clear;
|
||||
req->mask_cond = 0;
|
||||
SERVER_CALL();
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* QUEUE_ClearWakeBit
|
||||
*/
|
||||
void QUEUE_ClearWakeBit( MESSAGEQUEUE *queue, WORD bit )
|
||||
{
|
||||
QUEUE_SetWakeBit( queue, 0, bit );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* QUEUE_WaitBits
|
||||
*
|
||||
* See "Windows Internals", p.447
|
||||
*
|
||||
* return values:
|
||||
* 0 if exit with timeout
|
||||
* 1 otherwise
|
||||
*/
|
||||
int QUEUE_WaitBits( WORD bits, DWORD timeout )
|
||||
{
|
||||
MESSAGEQUEUE *queue;
|
||||
HQUEUE16 hQueue;
|
||||
|
||||
TRACE_(msg)("q %04x waiting for %04x\n", GetFastQueue16(), bits);
|
||||
|
||||
hQueue = GetFastQueue16();
|
||||
if (!(queue = QUEUE_Lock( hQueue ))) return 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
unsigned int wake_bits = 0, changed_bits = 0;
|
||||
DWORD dwlc;
|
||||
|
||||
SERVER_START_REQ( set_queue_mask )
|
||||
{
|
||||
req->wake_mask = QS_SENDMESSAGE;
|
||||
req->changed_mask = bits | QS_SENDMESSAGE;
|
||||
req->skip_wait = 1;
|
||||
if (!SERVER_CALL())
|
||||
{
|
||||
wake_bits = req->wake_bits;
|
||||
changed_bits = req->changed_bits;
|
||||
}
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
if (changed_bits & bits)
|
||||
{
|
||||
/* One of the bits is set; we can return */
|
||||
QUEUE_Unlock( queue );
|
||||
return 1;
|
||||
}
|
||||
if (wake_bits & QS_SENDMESSAGE)
|
||||
{
|
||||
/* Process the sent message immediately */
|
||||
process_sent_messages();
|
||||
continue; /* nested sm crux */
|
||||
}
|
||||
|
||||
TRACE_(msg)("(%04x) mask=%08x, bits=%08x, changed=%08x, waiting\n",
|
||||
queue->self, bits, wake_bits, changed_bits );
|
||||
|
||||
ReleaseThunkLock( &dwlc );
|
||||
if (dwlc) TRACE_(msg)("had win16 lock\n");
|
||||
|
||||
if (USER_Driver.pMsgWaitForMultipleObjectsEx)
|
||||
USER_Driver.pMsgWaitForMultipleObjectsEx( 1, &queue->server_queue, timeout, 0, 0 );
|
||||
else
|
||||
WaitForSingleObject( queue->server_queue, timeout );
|
||||
if (dwlc) RestoreThunkLock( dwlc );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* QUEUE_FindMsg
|
||||
*
|
||||
* Find a message matching the given parameters. Return -1 if none available.
|
||||
* Find a message matching the given parameters. Return FALSE if none available.
|
||||
*/
|
||||
BOOL QUEUE_FindMsg( HWND hwnd, UINT first, UINT last, BOOL remove, BOOL sent_only, QMSG *msg )
|
||||
BOOL QUEUE_FindMsg( HWND hwnd, UINT first, UINT last, BOOL remove, QMSG *msg )
|
||||
{
|
||||
BOOL ret = FALSE, sent = FALSE;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
if (!first && !last) last = ~0;
|
||||
|
||||
|
@ -694,28 +691,27 @@ BOOL QUEUE_FindMsg( HWND hwnd, UINT first, UINT last, BOOL remove, BOOL sent_onl
|
|||
{
|
||||
SERVER_START_REQ( get_message )
|
||||
{
|
||||
req->remove = remove;
|
||||
req->posted = !sent_only;
|
||||
req->flags = remove ? GET_MSG_REMOVE : 0;
|
||||
req->get_win = hwnd;
|
||||
req->get_first = first;
|
||||
req->get_last = last;
|
||||
if ((ret = !SERVER_CALL()))
|
||||
{
|
||||
sent = req->sent;
|
||||
msg->kind = req->kind;
|
||||
msg->type = req->type;
|
||||
msg->msg.hwnd = req->win;
|
||||
msg->msg.message = req->msg;
|
||||
msg->msg.wParam = req->wparam;
|
||||
msg->msg.lParam = req->lparam;
|
||||
msg->msg.time = 0; /* FIXME */
|
||||
msg->msg.pt.x = 0; /* FIXME */
|
||||
msg->msg.pt.y = 0; /* FIXME */
|
||||
msg->msg.time = req->time;
|
||||
msg->msg.pt.x = req->x;
|
||||
msg->msg.pt.y = req->y;
|
||||
msg->extraInfo = req->info;
|
||||
}
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
if (!ret || !sent) break;
|
||||
if (!ret || (msg->kind != SEND_MESSAGE)) break;
|
||||
handle_sent_message( msg );
|
||||
}
|
||||
|
||||
|
@ -772,92 +768,6 @@ void QUEUE_CleanupWindow( HWND hwnd )
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* hardware_event
|
||||
*
|
||||
* Add an event to the system message queue.
|
||||
* Note: the position is relative to the desktop window.
|
||||
*/
|
||||
void hardware_event( UINT message, WPARAM wParam, LPARAM lParam,
|
||||
int xPos, int yPos, DWORD time, DWORD extraInfo )
|
||||
{
|
||||
MSG *msg;
|
||||
QMSG *qmsg;
|
||||
MESSAGEQUEUE *queue;
|
||||
int mergeMsg = 0;
|
||||
|
||||
if (!sysMsgQueue) return;
|
||||
|
||||
EnterCriticalSection( &sysMsgQueue->cSection );
|
||||
|
||||
/* Merge with previous event if possible */
|
||||
qmsg = sysMsgQueue->lastMsg;
|
||||
|
||||
if ((message == WM_MOUSEMOVE) && sysMsgQueue->lastMsg)
|
||||
{
|
||||
msg = &(sysMsgQueue->lastMsg->msg);
|
||||
|
||||
if ((msg->message == message) && (msg->wParam == wParam))
|
||||
{
|
||||
/* Merge events */
|
||||
qmsg = sysMsgQueue->lastMsg;
|
||||
mergeMsg = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!mergeMsg)
|
||||
{
|
||||
/* Should I limit the number of messages in
|
||||
the system message queue??? */
|
||||
|
||||
/* Don't merge allocate a new msg in the global heap */
|
||||
|
||||
if (!(qmsg = (QMSG *) HeapAlloc( GetProcessHeap(), 0, sizeof(QMSG) ) ))
|
||||
{
|
||||
LeaveCriticalSection( &sysMsgQueue->cSection );
|
||||
return;
|
||||
}
|
||||
|
||||
/* put message at the end of the linked list */
|
||||
qmsg->nextMsg = 0;
|
||||
qmsg->prevMsg = sysMsgQueue->lastMsg;
|
||||
|
||||
if (sysMsgQueue->lastMsg)
|
||||
sysMsgQueue->lastMsg->nextMsg = qmsg;
|
||||
|
||||
/* set last and first anchor index in system message queue */
|
||||
sysMsgQueue->lastMsg = qmsg;
|
||||
if (!sysMsgQueue->firstMsg)
|
||||
sysMsgQueue->firstMsg = qmsg;
|
||||
}
|
||||
|
||||
/* Store message */
|
||||
msg = &(qmsg->msg);
|
||||
msg->hwnd = 0;
|
||||
msg->message = message;
|
||||
msg->wParam = wParam;
|
||||
msg->lParam = lParam;
|
||||
msg->time = time;
|
||||
msg->pt.x = xPos;
|
||||
msg->pt.y = yPos;
|
||||
qmsg->extraInfo = extraInfo;
|
||||
qmsg->type = QMSG_HARDWARE;
|
||||
|
||||
LeaveCriticalSection( &sysMsgQueue->cSection );
|
||||
|
||||
if ((queue = QUEUE_Lock( GetFastQueue16() )))
|
||||
{
|
||||
WORD wakeBit;
|
||||
|
||||
if ((message >= WM_KEYFIRST) && (message <= WM_KEYLAST)) wakeBit = QS_KEY;
|
||||
else wakeBit = (message == WM_MOUSEMOVE) ? QS_MOUSEMOVE : QS_MOUSEBUTTON;
|
||||
|
||||
QUEUE_SetWakeBit( queue, wakeBit, 0 );
|
||||
QUEUE_Unlock( queue );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* QUEUE_GetQueueTask
|
||||
*/
|
||||
|
@ -1116,8 +1026,7 @@ DWORD WINAPI WaitForInputIdle (HANDLE hProcess, DWORD dwTimeOut)
|
|||
ret = MsgWaitForMultipleObjects ( 1, &idle_event, FALSE, dwTimeOut, QS_SENDMESSAGE );
|
||||
if ( ret == ( WAIT_OBJECT_0 + 1 ))
|
||||
{
|
||||
QMSG msg;
|
||||
QUEUE_FindMsg( 0, 0, 0, TRUE, TRUE, &msg );
|
||||
process_sent_messages();
|
||||
continue;
|
||||
}
|
||||
if ( ret == WAIT_TIMEOUT || ret == 0xFFFFFFFF )
|
||||
|
@ -1141,18 +1050,14 @@ DWORD WINAPI WaitForInputIdle (HANDLE hProcess, DWORD dwTimeOut)
|
|||
*/
|
||||
void WINAPI UserYield16(void)
|
||||
{
|
||||
QMSG msg;
|
||||
|
||||
/* Handle sent messages */
|
||||
while (QUEUE_FindMsg( 0, 0, 0, TRUE, TRUE, &msg ))
|
||||
;
|
||||
process_sent_messages();
|
||||
|
||||
/* Yield */
|
||||
OldYield16();
|
||||
|
||||
/* Handle sent messages again */
|
||||
while (QUEUE_FindMsg( 0, 0, 0, TRUE, TRUE, &msg ))
|
||||
;
|
||||
process_sent_messages();
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
|
Loading…
Reference in New Issue