From 89faee01948f22b337f0c36669744d16882c4ae6 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Wed, 21 Feb 2007 15:21:05 +0100 Subject: [PATCH] server: Added support for the PM_QS_* flags in PeekMessage. --- dlls/user32/message.c | 16 +++++------ dlls/user32/tests/msg.c | 50 ---------------------------------- include/wine/server_protocol.h | 7 ++--- server/protocol.def | 5 ++-- server/queue.c | 31 +++++++++++++-------- server/trace.c | 4 ++- 6 files changed, 36 insertions(+), 77 deletions(-) diff --git a/dlls/user32/message.c b/dlls/user32/message.c index 4a4f7c3dae5..22b922d155c 100644 --- a/dlls/user32/message.c +++ b/dlls/user32/message.c @@ -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 ); } diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c index b5440a53314..f45a0591ed3 100644 --- a/dlls/user32/tests/msg.c +++ b/dlls/user32/tests/msg.c @@ -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); diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index 4e7cec0e021..b5c620170c2 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -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 */ diff --git a/server/protocol.def b/server/protocol.def index 2073a20990a..e4f16a995a7 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -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) diff --git a/server/queue.c b/server/queue.c index 1efed556dba..7efdd78f03f 100644 --- a/server/queue.c +++ b/server/queue.c @@ -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 */ } diff --git a/server/trace.c b/server/trace.c index 2909dedd810..50926f581b5 100644 --- a/server/trace.c +++ b/server/trace.c @@ -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 },