Properly cope with get_message being called recursively while
processing a hardware message.
This commit is contained in:
parent
d574e9a2db
commit
99615021fb
|
@ -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 ))
|
||||
{
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 )
|
||||
|
|
Loading…
Reference in New Issue