diff --git a/dlls/user/message.c b/dlls/user/message.c index be999b72994..9a6b32e998a 100644 --- a/dlls/user/message.c +++ b/dlls/user/message.c @@ -1585,6 +1585,7 @@ BOOL MSG_peek_message( MSG *msg, HWND hwnd, UINT first, UINT last, int flags ) ULONG_PTR extra_info = 0; MESSAGEQUEUE *queue = QUEUE_Current(); struct received_message_info info, *old_info; + int get_next_hw = 0; /* set when the previous message was a rejected hardware message */ if (!first && !last) last = ~0; @@ -1604,6 +1605,7 @@ BOOL MSG_peek_message( MSG *msg, HWND hwnd, UINT first, UINT last, int flags ) req->get_win = hwnd; req->get_first = first; req->get_last = last; + req->get_next_hw = get_next_hw; if (buffer_size) wine_server_set_reply( req, buffer, buffer_size ); if (!(res = wine_server_call( req ))) { @@ -1630,6 +1632,7 @@ BOOL MSG_peek_message( MSG *msg, HWND hwnd, UINT first, UINT last, int flags ) } while (res == STATUS_BUFFER_OVERFLOW); if (res) return FALSE; + get_next_hw = 0; TRACE( "got type %d msg %x (%s) hwnd %p wp %x lp %lx\n", info.type, info.msg.message, @@ -1694,6 +1697,7 @@ BOOL MSG_peek_message( MSG *msg, HWND hwnd, UINT first, UINT last, int flags ) } break; case MSG_HARDWARE: + get_next_hw = 1; if (!process_hardware_message( &info.msg, extra_info, hwnd, first, last, flags & GET_MSG_REMOVE )) { diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index 1615763b9e1..74667f2d978 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -2156,6 +2156,7 @@ struct get_message_request user_handle_t get_win; unsigned int get_first; unsigned int get_last; + int get_next_hw; }; struct get_message_reply { @@ -3781,6 +3782,6 @@ union generic_reply struct duplicate_token_reply duplicate_token_reply; }; -#define SERVER_PROTOCOL_VERSION 158 +#define SERVER_PROTOCOL_VERSION 159 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/server/protocol.def b/server/protocol.def index d7d2b53b329..01584516f88 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -1531,6 +1531,7 @@ enum message_type 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 */ + int get_next_hw; /* do we want the get the next hardware msg? */ @REPLY int type; /* message type */ user_handle_t win; /* window handle */ diff --git a/server/queue.c b/server/queue.c index da2fe87737a..cd78cba7b01 100644 --- a/server/queue.c +++ b/server/queue.c @@ -1121,7 +1121,7 @@ static void queue_hardware_message( struct msg_queue *queue, struct message *msg } /* find a hardware message for the given queue */ -static int get_hardware_message( struct thread *thread, struct message *first, +static int get_hardware_message( struct thread *thread, int get_next_hw, struct message *first, user_handle_t filter_win, struct get_message_reply *reply ) { struct thread_input *input = thread->queue->input; @@ -1131,8 +1131,8 @@ static int get_hardware_message( struct thread *thread, struct message *first, int clear_bits, got_one = 0; unsigned int msg_code; - if (input->msg_thread && input->msg_thread != thread) - return 0; /* locked by another thread */ + if (input->msg_thread && ((input->msg_thread != thread) || !get_next_hw)) + return 0; /* locked by another thread, or another recursion level of the same thread */ if (!first) { @@ -1492,7 +1492,7 @@ DECL_HANDLER(get_message) /* first of all release the hardware input lock if we own it */ /* we'll grab it again if we find a hardware message */ - if (queue->input->msg_thread == current) + if (queue->input->msg_thread == current && req->get_next_hw) { first_hw_msg = queue->input->msg; release_hardware_message( current, 0 ); @@ -1515,7 +1515,7 @@ DECL_HANDLER(get_message) return; /* then check for any raw hardware message */ - if (get_hardware_message( current, first_hw_msg, get_win, reply )) + if (get_hardware_message( current, req->get_next_hw, first_hw_msg, get_win, reply )) return; /* now check for WM_PAINT */ diff --git a/server/trace.c b/server/trace.c index bfd69191b04..3b46f2597e2 100644 --- a/server/trace.c +++ b/server/trace.c @@ -1871,7 +1871,8 @@ static void dump_get_message_request( const struct get_message_request *req ) fprintf( stderr, " flags=%d,", 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 ); + fprintf( stderr, " get_last=%08x,", req->get_last ); + fprintf( stderr, " get_next_hw=%d", req->get_next_hw ); } static void dump_get_message_reply( const struct get_message_reply *req )