Commit 89faee01 authored by Alexandre Julliard's avatar Alexandre Julliard

server: Added support for the PM_QS_* flags in PeekMessage.

parent c6eee93a
......@@ -1942,7 +1942,7 @@ static void *get_hook_proc( void *proc, const WCHAR *module )
* Peek for a message matching the given parameters. Return FALSE if none available.
* All pending sent messages are processed before returning.
*/
static BOOL peek_message( MSG *msg, HWND hwnd, UINT first, UINT last, int flags )
static BOOL peek_message( MSG *msg, HWND hwnd, UINT first, UINT last, UINT flags )
{
LRESULT result;
ULONG_PTR extra_info = 0;
......@@ -2071,7 +2071,7 @@ static BOOL peek_message( MSG *msg, HWND hwnd, UINT first, UINT last, int flags
break;
case MSG_HARDWARE:
if (!process_hardware_message( &info.msg, hw_id, extra_info,
hwnd, first, last, flags & GET_MSG_REMOVE ))
hwnd, first, last, flags & PM_REMOVE ))
{
TRACE("dropping msg %x\n", info.msg.message );
goto next; /* ignore it */
......@@ -2100,6 +2100,9 @@ static BOOL peek_message( MSG *msg, HWND hwnd, UINT first, UINT last, int flags
thread_info->receive_info = old_info;
next:
HeapFree( GetProcessHeap(), 0, buffer );
/* if some PM_QS* flags were specified, only handle sent messages from now on */
if (HIWORD(flags)) flags = PM_QS_SENDMESSAGE | LOWORD(flags);
}
}
......@@ -2112,7 +2115,7 @@ static BOOL peek_message( MSG *msg, HWND hwnd, UINT first, UINT last, int flags
inline static void process_sent_messages(void)
{
MSG msg;
peek_message( &msg, 0, 0, 0, GET_MSG_REMOVE | GET_MSG_SENT_ONLY );
peek_message( &msg, 0, 0, 0, PM_REMOVE | PM_QS_SENDMESSAGE );
}
......@@ -2755,9 +2758,6 @@ BOOL WINAPI PeekMessageW( MSG *msg_out, HWND hwnd, UINT first, UINT last, UINT f
struct user_thread_info *thread_info = get_user_thread_info();
MSG msg;
if (HIWORD(flags))
FIXME("PM_QS_xxxx flags (%04x) are not handled\n", flags >> 16);
USER_CheckNotLock();
/* check for graphics events */
......@@ -2767,7 +2767,7 @@ BOOL WINAPI PeekMessageW( MSG *msg_out, HWND hwnd, UINT first, UINT last, UINT f
for (;;)
{
if (!peek_message( &msg, hwnd, first, last, (flags & PM_REMOVE) ? GET_MSG_REMOVE : 0 ))
if (!peek_message( &msg, hwnd, first, last, flags ))
{
if (!(flags & PM_NOYIELD))
{
......@@ -2785,7 +2785,7 @@ BOOL WINAPI PeekMessageW( MSG *msg_out, HWND hwnd, UINT first, UINT last, UINT f
/* Have to remove the message explicitly.
Do this before handling it, because the message handler may
call PeekMessage again */
peek_message( &msg, msg.hwnd, msg.message, msg.message, GET_MSG_REMOVE );
peek_message( &msg, msg.hwnd, msg.message, msg.message, flags | PM_REMOVE );
}
handle_internal_message( msg.hwnd, msg.message, msg.wParam, msg.lParam );
}
......
......@@ -7876,73 +7876,55 @@ static void test_PeekMessage(void)
msg.message = 0;
ret = PeekMessageA(&msg, 0, 0, 0, PM_REMOVE | (qs_input << 16));
todo_wine {
ok(!ret,
"PeekMessageA should have returned FALSE instead of msg %04x\n",
msg.message);
}
ok_sequence(WmUser, "WmUser", FALSE);
qstatus = GetQueueStatus(qs_all_input);
todo_wine {
ok(qstatus == MAKELONG(0, QS_PAINT|QS_POSTMESSAGE|QS_KEY),
"wrong qstatus %08x\n", qstatus);
}
trace("signalling to send message\n");
SetEvent(info.hevent[EV_SENDMSG]);
WaitForSingleObject(info.hevent[EV_ACK], INFINITE);
qstatus = GetQueueStatus(qs_all_input);
todo_wine {
ok(qstatus == MAKELONG(QS_SENDMESSAGE, QS_SENDMESSAGE|QS_PAINT|QS_POSTMESSAGE|QS_KEY),
"wrong qstatus %08x\n", qstatus);
}
msg.message = 0;
ret = PeekMessageA(&msg, 0, 0, 0, PM_REMOVE | PM_QS_POSTMESSAGE);
todo_wine {
ok(!ret,
"PeekMessageA should have returned FALSE instead of msg %04x\n",
msg.message);
}
ok_sequence(WmUser, "WmUser", FALSE);
qstatus = GetQueueStatus(qs_all_input);
todo_wine {
ok(qstatus == MAKELONG(0, QS_PAINT|QS_POSTMESSAGE|QS_KEY),
"wrong qstatus %08x\n", qstatus);
}
msg.message = 0;
ret = PeekMessageA(&msg, 0, 0, 0, PM_REMOVE | PM_QS_POSTMESSAGE);
todo_wine {
ok(ret && msg.message == WM_CHAR && msg.wParam == 'z',
"got %d and %04x wParam %08x instead of TRUE and WM_CHAR wParam 'z'\n",
ret, msg.message, msg.wParam);
}
ok_sequence(WmEmptySeq, "WmEmptySeq", FALSE);
qstatus = GetQueueStatus(qs_all_input);
todo_wine {
ok(qstatus == MAKELONG(0, QS_PAINT|QS_KEY),
"wrong qstatus %08x\n", qstatus);
}
msg.message = 0;
ret = PeekMessageA(&msg, 0, 0, 0, PM_REMOVE | PM_QS_POSTMESSAGE);
todo_wine {
ok(!ret,
"PeekMessageA should have returned FALSE instead of msg %04x\n",
msg.message);
}
ok_sequence(WmEmptySeq, "WmEmptySeq", FALSE);
qstatus = GetQueueStatus(qs_all_input);
todo_wine {
ok(qstatus == MAKELONG(0, QS_PAINT|QS_KEY),
"wrong qstatus %08x\n", qstatus);
}
msg.message = 0;
ret = PeekMessageA(&msg, 0, 0, 0, PM_REMOVE | PM_QS_PAINT);
......@@ -7952,10 +7934,8 @@ todo_wine {
ok_sequence(WmPaint, "WmPaint", FALSE);
qstatus = GetQueueStatus(qs_all_input);
todo_wine {
ok(qstatus == MAKELONG(0, QS_KEY),
"wrong qstatus %08x\n", qstatus);
}
msg.message = 0;
ret = PeekMessageA(&msg, 0, 0, 0, PM_REMOVE | PM_QS_PAINT);
......@@ -7965,28 +7945,22 @@ todo_wine {
ok_sequence(WmEmptySeq, "WmEmptySeq", FALSE);
qstatus = GetQueueStatus(qs_all_input);
todo_wine {
ok(qstatus == MAKELONG(0, QS_KEY),
"wrong qstatus %08x\n", qstatus);
}
trace("signalling to send message\n");
SetEvent(info.hevent[EV_SENDMSG]);
WaitForSingleObject(info.hevent[EV_ACK], INFINITE);
qstatus = GetQueueStatus(qs_all_input);
todo_wine {
ok(qstatus == MAKELONG(QS_SENDMESSAGE, QS_SENDMESSAGE|QS_KEY),
"wrong qstatus %08x\n", qstatus);
}
PostMessageA(info.hwnd, WM_CHAR, 'z', 0);
qstatus = GetQueueStatus(qs_all_input);
todo_wine {
ok(qstatus == MAKELONG(QS_POSTMESSAGE, QS_SENDMESSAGE|QS_POSTMESSAGE|QS_KEY),
"wrong qstatus %08x\n", qstatus);
}
msg.message = 0;
ret = PeekMessageA(&msg, 0, WM_CHAR, WM_CHAR, PM_REMOVE);
......@@ -7996,10 +7970,8 @@ todo_wine {
ok_sequence(WmUser, "WmUser", FALSE);
qstatus = GetQueueStatus(qs_all_input);
todo_wine {
ok(qstatus == MAKELONG(0, QS_KEY),
"wrong qstatus %08x\n", qstatus);
}
msg.message = 0;
ret = PeekMessageA(&msg, 0, WM_CHAR, WM_CHAR, PM_REMOVE);
......@@ -8009,73 +7981,55 @@ todo_wine {
ok_sequence(WmEmptySeq, "WmEmptySeq", FALSE);
qstatus = GetQueueStatus(qs_all_input);
todo_wine {
ok(qstatus == MAKELONG(0, QS_KEY),
"wrong qstatus %08x\n", qstatus);
}
PostMessageA(info.hwnd, WM_CHAR, 'z', 0);
qstatus = GetQueueStatus(qs_all_input);
todo_wine {
ok(qstatus == MAKELONG(QS_POSTMESSAGE, QS_POSTMESSAGE|QS_KEY),
"wrong qstatus %08x\n", qstatus);
}
trace("signalling to send message\n");
SetEvent(info.hevent[EV_SENDMSG]);
WaitForSingleObject(info.hevent[EV_ACK], INFINITE);
qstatus = GetQueueStatus(qs_all_input);
todo_wine {
ok(qstatus == MAKELONG(QS_SENDMESSAGE, QS_SENDMESSAGE|QS_POSTMESSAGE|QS_KEY),
"wrong qstatus %08x\n", qstatus);
}
msg.message = 0;
ret = PeekMessageA(&msg, 0, 0, 0, PM_REMOVE | (QS_KEY << 16));
todo_wine {
ok(!ret,
"PeekMessageA should have returned FALSE instead of msg %04x\n",
msg.message);
}
ok_sequence(WmUser, "WmUser", FALSE);
qstatus = GetQueueStatus(qs_all_input);
todo_wine {
ok(qstatus == MAKELONG(0, QS_POSTMESSAGE|QS_KEY),
"wrong qstatus %08x\n", qstatus);
}
msg.message = 0;
ret = PeekMessageA(&msg, 0, 0, 0, PM_REMOVE | (QS_RAWINPUT << 16));
todo_wine {
ok(ret && msg.message == WM_KEYDOWN && msg.wParam == 'N',
"got %d and %04x wParam %08x instead of TRUE and WM_KEYDOWN wParam 'N'\n",
ret, msg.message, msg.wParam);
ok_sequence(WmKeyDownSkippedSeq, "WmKeyDownSkippedSeq", FALSE);
}
qstatus = GetQueueStatus(qs_all_input);
todo_wine {
ok(qstatus == MAKELONG(0, QS_POSTMESSAGE|QS_KEY),
"wrong qstatus %08x\n", qstatus);
}
msg.message = 0;
ret = PeekMessageA(&msg, 0, 0, 0, PM_REMOVE | (QS_RAWINPUT << 16));
todo_wine {
ok(ret && msg.message == WM_KEYUP && msg.wParam == 'N',
"got %d and %04x wParam %08x instead of TRUE and WM_KEYUP wParam 'N'\n",
ret, msg.message, msg.wParam);
ok_sequence(WmKeyUpSkippedSeq, "WmKeyUpSkippedSeq", FALSE);
}
qstatus = GetQueueStatus(qs_all_input);
todo_wine {
ok(qstatus == MAKELONG(0, QS_POSTMESSAGE),
"wrong qstatus %08x\n", qstatus);
}
msg.message = 0;
ret = PeekMessageA(&msg, 0, 0, 0, PM_REMOVE | PM_QS_SENDMESSAGE);
......@@ -8085,18 +8039,14 @@ todo_wine {
ok_sequence(WmEmptySeq, "WmEmptySeq", FALSE);
qstatus = GetQueueStatus(qs_all_input);
todo_wine {
ok(qstatus == MAKELONG(0, QS_POSTMESSAGE),
"wrong qstatus %08x\n", qstatus);
}
msg.message = 0;
ret = PeekMessageA(&msg, 0, 0, 0, PM_REMOVE);
todo_wine {
ok(ret && msg.message == WM_CHAR && msg.wParam == 'z',
"got %d and %04x wParam %08x instead of TRUE and WM_CHAR wParam 'z'\n",
ret, msg.message, msg.wParam);
}
ok_sequence(WmEmptySeq, "WmEmptySeq", FALSE);
qstatus = GetQueueStatus(qs_all_input);
......
......@@ -2485,7 +2485,7 @@ struct send_hardware_message_reply
struct get_message_request
{
struct request_header __header;
int flags;
unsigned int flags;
user_handle_t get_win;
unsigned int get_first;
unsigned int get_last;
......@@ -2508,8 +2508,7 @@ struct get_message_reply
data_size_t total;
/* VARARG(data,message_data); */
};
#define GET_MSG_REMOVE 1
#define GET_MSG_SENT_ONLY 2
struct reply_message_request
......@@ -4657,6 +4656,6 @@ union generic_reply
struct get_object_info_reply get_object_info_reply;
};
#define SERVER_PROTOCOL_VERSION 276
#define SERVER_PROTOCOL_VERSION 277
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
......@@ -1839,7 +1839,7 @@ enum message_type
/* Get a message from the current queue */
@REQ(get_message)
int flags; /* see below */
unsigned int flags; /* PM_* flags */
user_handle_t get_win; /* window handle to get */
unsigned int get_first; /* first message code to get */
unsigned int get_last; /* last message code to get */
......@@ -1859,8 +1859,7 @@ enum message_type
data_size_t total; /* total size of extra data */
VARARG(data,message_data); /* message data for sent messages */
@END
#define GET_MSG_REMOVE 1 /* remove the message */
#define GET_MSG_SENT_ONLY 2 /* only get sent messages */
/* Reply to a sent message */
@REQ(reply_message)
......
......@@ -669,7 +669,7 @@ found:
reply->time = msg->time;
reply->info = msg->info;
if (flags & GET_MSG_REMOVE)
if (flags & PM_REMOVE)
{
if (msg->data)
{
......@@ -700,7 +700,7 @@ static int get_quit_message( struct msg_queue *queue, unsigned int flags,
reply->time = get_tick_count();
reply->info = 0;
if (flags & GET_MSG_REMOVE)
if (flags & PM_REMOVE)
{
queue->quit_message = 0;
if (list_empty( &queue->msg_list[POST_MESSAGE] ))
......@@ -1691,11 +1691,13 @@ DECL_HANDLER(get_message)
struct list *ptr;
struct msg_queue *queue = get_current_queue();
user_handle_t get_win = get_user_full_handle( req->get_win );
unsigned int filter = req->flags >> 16;
reply->active_hooks = get_active_hooks();
if (!queue) return;
queue->last_get_msg = current_time;
if (!filter) filter = QS_ALLINPUT;
/* first check for sent messages */
if ((ptr = list_head( &queue->msg_list[SEND_MESSAGE] )))
......@@ -1704,14 +1706,19 @@ DECL_HANDLER(get_message)
receive_message( queue, msg, reply );
return;
}
if (req->flags & GET_MSG_SENT_ONLY) goto done; /* nothing else to check */
/* clear changed bits so we can wait on them if we don't find a message */
if (req->get_first == 0 && req->get_last == ~0U) queue->changed_bits = 0;
else queue->changed_bits &= QS_ALLPOSTMESSAGE;
if (filter & QS_POSTMESSAGE)
{
queue->changed_bits &= ~(QS_POSTMESSAGE | QS_HOTKEY | QS_TIMER);
if (req->get_first == 0 && req->get_last == ~0U) queue->changed_bits &= ~QS_ALLPOSTMESSAGE;
}
if (filter & QS_INPUT) queue->changed_bits &= ~QS_INPUT;
if (filter & QS_PAINT) queue->changed_bits &= ~QS_PAINT;
/* then check for posted messages */
if (get_posted_message( queue, get_win, req->get_first, req->get_last, req->flags, reply ))
if ((filter & QS_POSTMESSAGE) &&
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.
......@@ -1720,12 +1727,14 @@ DECL_HANDLER(get_message)
return;
/* then check for any raw hardware message */
if (filter_contains_hw_range( req->get_first, req->get_last ) &&
if ((filter & QS_INPUT) &&
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 ))
return;
/* now check for WM_PAINT */
if (queue->paint_count &&
if ((filter & QS_PAINT) &&
queue->paint_count &&
check_msg_filter( WM_PAINT, req->get_first, req->get_last ) &&
(reply->win = find_window_to_repaint( get_win, current )))
{
......@@ -1741,8 +1750,9 @@ DECL_HANDLER(get_message)
}
/* now check for timer */
if ((timer = find_expired_timer( queue, get_win, req->get_first,
req->get_last, (req->flags & GET_MSG_REMOVE) )))
if ((filter & QS_TIMER) &&
(timer = find_expired_timer( queue, get_win, req->get_first,
req->get_last, (req->flags & PM_REMOVE) )))
{
reply->type = MSG_POSTED;
reply->win = timer->win;
......@@ -1756,7 +1766,6 @@ DECL_HANDLER(get_message)
return;
}
done:
set_error( STATUS_PENDING ); /* FIXME */
}
......
......@@ -2267,7 +2267,7 @@ static void dump_send_hardware_message_request( const struct send_hardware_messa
static void dump_get_message_request( const struct get_message_request *req )
{
fprintf( stderr, " flags=%d,", req->flags );
fprintf( stderr, " flags=%08x,", req->flags );
fprintf( stderr, " get_win=%p,", req->get_win );
fprintf( stderr, " get_first=%08x,", req->get_first );
fprintf( stderr, " get_last=%08x,", req->get_last );
......@@ -4111,9 +4111,11 @@ static const struct
{ "ALERTED", STATUS_ALERTED },
{ "ALIAS_EXISTS", STATUS_ALIAS_EXISTS },
{ "BAD_DEVICE_TYPE", STATUS_BAD_DEVICE_TYPE },
{ "BAD_IMPERSONATION_LEVEL", STATUS_BAD_IMPERSONATION_LEVEL },
{ "BUFFER_OVERFLOW", STATUS_BUFFER_OVERFLOW },
{ "BUFFER_TOO_SMALL", STATUS_BUFFER_TOO_SMALL },
{ "CANCELLED", STATUS_CANCELLED },
{ "CANT_OPEN_ANONYMOUS", STATUS_CANT_OPEN_ANONYMOUS },
{ "CHILD_MUST_BE_VOLATILE", STATUS_CHILD_MUST_BE_VOLATILE },
{ "DEVICE_BUSY", STATUS_DEVICE_BUSY },
{ "DIRECTORY_NOT_EMPTY", STATUS_DIRECTORY_NOT_EMPTY },
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment