Create a new server request for accepting hardware messages instead of
abusing reply_message. Allow passing the determined window for a hardware message back to the server to have it redispatch the message to the correct thread.
This commit is contained in:
parent
caec6026e7
commit
0bc8377bc2
|
@ -1133,7 +1133,6 @@ static void reply_message( struct received_message_info *info, LRESULT result, B
|
||||||
|
|
||||||
SERVER_START_REQ( reply_message )
|
SERVER_START_REQ( reply_message )
|
||||||
{
|
{
|
||||||
req->type = info->type;
|
|
||||||
req->result = result;
|
req->result = result;
|
||||||
req->remove = remove;
|
req->remove = remove;
|
||||||
for (i = 0; i < data.count; i++) wine_server_add_data( req, data.data[i], data.size[i] );
|
for (i = 0; i < data.count; i++) wine_server_add_data( req, data.data[i], data.size[i] );
|
||||||
|
@ -1566,13 +1565,12 @@ static void send_parent_notify( HWND hwnd, WORD event, WORD idChild, POINT pt )
|
||||||
* Tell the server we have passed the message to the app
|
* Tell the server we have passed the message to the app
|
||||||
* (even though we may end up dropping it later on)
|
* (even though we may end up dropping it later on)
|
||||||
*/
|
*/
|
||||||
static void accept_hardware_message( BOOL remove )
|
static void accept_hardware_message( BOOL remove, HWND new_hwnd )
|
||||||
{
|
{
|
||||||
SERVER_START_REQ( reply_message )
|
SERVER_START_REQ( accept_hardware_message )
|
||||||
{
|
{
|
||||||
req->type = MSG_HARDWARE;
|
req->remove = remove;
|
||||||
req->result = 0;
|
req->new_win = new_hwnd;
|
||||||
req->remove = remove;
|
|
||||||
if (wine_server_call( req ))
|
if (wine_server_call( req ))
|
||||||
FIXME("Failed to reply to MSG_HARDWARE message. Message may not be removed from queue.\n");
|
FIXME("Failed to reply to MSG_HARDWARE message. Message may not be removed from queue.\n");
|
||||||
}
|
}
|
||||||
|
@ -1626,10 +1624,10 @@ static BOOL process_keyboard_message( MSG *msg, HWND hwnd_filter, UINT first, UI
|
||||||
{
|
{
|
||||||
/* skip this message */
|
/* skip this message */
|
||||||
HOOK_CallHooks( WH_CBT, HCBT_KEYSKIPPED, LOWORD(msg->wParam), msg->lParam, TRUE );
|
HOOK_CallHooks( WH_CBT, HCBT_KEYSKIPPED, LOWORD(msg->wParam), msg->lParam, TRUE );
|
||||||
accept_hardware_message( TRUE );
|
accept_hardware_message( TRUE, 0 );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
accept_hardware_message( remove );
|
accept_hardware_message( remove, 0 );
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1651,7 +1649,6 @@ static BOOL process_mouse_message( MSG *msg, ULONG_PTR extra_info, HWND hwnd_fil
|
||||||
GUITHREADINFO info;
|
GUITHREADINFO info;
|
||||||
MOUSEHOOKSTRUCT hook;
|
MOUSEHOOKSTRUCT hook;
|
||||||
BOOL eatMsg;
|
BOOL eatMsg;
|
||||||
HWND hWndScope = msg->hwnd;
|
|
||||||
|
|
||||||
/* find the window to dispatch this mouse message to */
|
/* find the window to dispatch this mouse message to */
|
||||||
|
|
||||||
|
@ -1659,6 +1656,7 @@ static BOOL process_mouse_message( MSG *msg, ULONG_PTR extra_info, HWND hwnd_fil
|
||||||
GetGUIThreadInfo( GetCurrentThreadId(), &info );
|
GetGUIThreadInfo( GetCurrentThreadId(), &info );
|
||||||
if (!(msg->hwnd = info.hwndCapture))
|
if (!(msg->hwnd = info.hwndCapture))
|
||||||
{
|
{
|
||||||
|
HWND hWndScope = msg->hwnd;
|
||||||
/* If no capture HWND, find window which contains the mouse position.
|
/* If no capture HWND, find window which contains the mouse position.
|
||||||
* Also find the position of the cursor hot spot (hittest) */
|
* Also find the position of the cursor hot spot (hittest) */
|
||||||
if (!IsWindow(hWndScope)) hWndScope = 0;
|
if (!IsWindow(hWndScope)) hWndScope = 0;
|
||||||
|
@ -1666,6 +1664,12 @@ static BOOL process_mouse_message( MSG *msg, ULONG_PTR extra_info, HWND hwnd_fil
|
||||||
msg->hwnd = GetDesktopWindow();
|
msg->hwnd = GetDesktopWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!WIN_IsCurrentThread( msg->hwnd ))
|
||||||
|
{
|
||||||
|
accept_hardware_message( FALSE, msg->hwnd );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/* FIXME: is this really the right place for this hook? */
|
/* FIXME: is this really the right place for this hook? */
|
||||||
event.message = msg->message;
|
event.message = msg->message;
|
||||||
event.time = msg->time;
|
event.time = msg->time;
|
||||||
|
@ -1746,7 +1750,7 @@ static BOOL process_mouse_message( MSG *msg, ULONG_PTR extra_info, HWND hwnd_fil
|
||||||
hook.wHitTestCode = hittest;
|
hook.wHitTestCode = hittest;
|
||||||
hook.dwExtraInfo = extra_info;
|
hook.dwExtraInfo = extra_info;
|
||||||
HOOK_CallHooks( WH_CBT, HCBT_CLICKSKIPPED, message, (LPARAM)&hook, TRUE );
|
HOOK_CallHooks( WH_CBT, HCBT_CLICKSKIPPED, message, (LPARAM)&hook, TRUE );
|
||||||
accept_hardware_message( TRUE );
|
accept_hardware_message( TRUE, 0 );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1754,11 +1758,11 @@ static BOOL process_mouse_message( MSG *msg, ULONG_PTR extra_info, HWND hwnd_fil
|
||||||
{
|
{
|
||||||
SendMessageW( msg->hwnd, WM_SETCURSOR, (WPARAM)msg->hwnd,
|
SendMessageW( msg->hwnd, WM_SETCURSOR, (WPARAM)msg->hwnd,
|
||||||
MAKELONG( hittest, msg->message ));
|
MAKELONG( hittest, msg->message ));
|
||||||
accept_hardware_message( TRUE );
|
accept_hardware_message( TRUE, 0 );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
accept_hardware_message( remove );
|
accept_hardware_message( remove, 0 );
|
||||||
|
|
||||||
if (!remove || info.hwndCapture)
|
if (!remove || info.hwndCapture)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2182,7 +2182,6 @@ struct get_message_reply
|
||||||
struct reply_message_request
|
struct reply_message_request
|
||||||
{
|
{
|
||||||
struct request_header __header;
|
struct request_header __header;
|
||||||
int type;
|
|
||||||
unsigned int result;
|
unsigned int result;
|
||||||
int remove;
|
int remove;
|
||||||
/* VARARG(data,bytes); */
|
/* VARARG(data,bytes); */
|
||||||
|
@ -2194,6 +2193,19 @@ struct reply_message_reply
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct accept_hardware_message_request
|
||||||
|
{
|
||||||
|
struct request_header __header;
|
||||||
|
int remove;
|
||||||
|
user_handle_t new_win;
|
||||||
|
};
|
||||||
|
struct accept_hardware_message_reply
|
||||||
|
{
|
||||||
|
struct reply_header __header;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct get_message_reply_request
|
struct get_message_reply_request
|
||||||
{
|
{
|
||||||
struct request_header __header;
|
struct request_header __header;
|
||||||
|
@ -3353,6 +3365,7 @@ enum request
|
||||||
REQ_send_message,
|
REQ_send_message,
|
||||||
REQ_get_message,
|
REQ_get_message,
|
||||||
REQ_reply_message,
|
REQ_reply_message,
|
||||||
|
REQ_accept_hardware_message,
|
||||||
REQ_get_message_reply,
|
REQ_get_message_reply,
|
||||||
REQ_set_win_timer,
|
REQ_set_win_timer,
|
||||||
REQ_kill_win_timer,
|
REQ_kill_win_timer,
|
||||||
|
@ -3544,6 +3557,7 @@ union generic_request
|
||||||
struct send_message_request send_message_request;
|
struct send_message_request send_message_request;
|
||||||
struct get_message_request get_message_request;
|
struct get_message_request get_message_request;
|
||||||
struct reply_message_request reply_message_request;
|
struct reply_message_request reply_message_request;
|
||||||
|
struct accept_hardware_message_request accept_hardware_message_request;
|
||||||
struct get_message_reply_request get_message_reply_request;
|
struct get_message_reply_request get_message_reply_request;
|
||||||
struct set_win_timer_request set_win_timer_request;
|
struct set_win_timer_request set_win_timer_request;
|
||||||
struct kill_win_timer_request kill_win_timer_request;
|
struct kill_win_timer_request kill_win_timer_request;
|
||||||
|
@ -3733,6 +3747,7 @@ union generic_reply
|
||||||
struct send_message_reply send_message_reply;
|
struct send_message_reply send_message_reply;
|
||||||
struct get_message_reply get_message_reply;
|
struct get_message_reply get_message_reply;
|
||||||
struct reply_message_reply reply_message_reply;
|
struct reply_message_reply reply_message_reply;
|
||||||
|
struct accept_hardware_message_reply accept_hardware_message_reply;
|
||||||
struct get_message_reply_reply get_message_reply_reply;
|
struct get_message_reply_reply get_message_reply_reply;
|
||||||
struct set_win_timer_reply set_win_timer_reply;
|
struct set_win_timer_reply set_win_timer_reply;
|
||||||
struct kill_win_timer_reply kill_win_timer_reply;
|
struct kill_win_timer_reply kill_win_timer_reply;
|
||||||
|
@ -3797,6 +3812,6 @@ union generic_reply
|
||||||
struct duplicate_token_reply duplicate_token_reply;
|
struct duplicate_token_reply duplicate_token_reply;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SERVER_PROTOCOL_VERSION 162
|
#define SERVER_PROTOCOL_VERSION 163
|
||||||
|
|
||||||
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
||||||
|
|
|
@ -1552,13 +1552,19 @@ enum message_type
|
||||||
|
|
||||||
/* Reply to a sent message */
|
/* Reply to a sent message */
|
||||||
@REQ(reply_message)
|
@REQ(reply_message)
|
||||||
int type; /* type of original message */
|
|
||||||
unsigned int result; /* message result */
|
unsigned int result; /* message result */
|
||||||
int remove; /* should we remove the message? */
|
int remove; /* should we remove the message? */
|
||||||
VARARG(data,bytes); /* message data for sent messages */
|
VARARG(data,bytes); /* message data for sent messages */
|
||||||
@END
|
@END
|
||||||
|
|
||||||
|
|
||||||
|
/* Accept the current hardware message */
|
||||||
|
@REQ(accept_hardware_message)
|
||||||
|
int remove; /* should we remove the message? */
|
||||||
|
user_handle_t new_win; /* new destination window for current message */
|
||||||
|
@END
|
||||||
|
|
||||||
|
|
||||||
/* Retrieve the reply for the last message sent */
|
/* Retrieve the reply for the last message sent */
|
||||||
@REQ(get_message_reply)
|
@REQ(get_message_reply)
|
||||||
int cancel; /* cancel message if not ready? */
|
int cancel; /* cancel message if not ready? */
|
||||||
|
|
|
@ -1058,28 +1058,45 @@ static void update_input_key_state( struct thread_input *input, const struct mes
|
||||||
}
|
}
|
||||||
|
|
||||||
/* release the hardware message currently being processed by the given thread */
|
/* release the hardware message currently being processed by the given thread */
|
||||||
static void release_hardware_message( struct thread *thread, int remove )
|
static void release_hardware_message( struct thread *thread, int remove, user_handle_t new_win )
|
||||||
{
|
{
|
||||||
struct thread_input *input = thread->queue->input;
|
struct thread_input *input = thread->queue->input;
|
||||||
|
|
||||||
if (input->msg_thread != thread) return;
|
if (input->msg_thread != thread) return;
|
||||||
if (remove)
|
|
||||||
|
/* clear the queue bit for that message */
|
||||||
|
if (remove || new_win)
|
||||||
{
|
{
|
||||||
struct message *other;
|
struct message *other;
|
||||||
int clr_bit;
|
int clr_bit;
|
||||||
|
|
||||||
update_input_key_state( input, input->msg );
|
|
||||||
list_remove( &input->msg->entry );
|
|
||||||
clr_bit = get_hardware_msg_bit( input->msg );
|
clr_bit = get_hardware_msg_bit( input->msg );
|
||||||
LIST_FOR_EACH_ENTRY( other, &input->msg_list, struct message, entry )
|
LIST_FOR_EACH_ENTRY( other, &input->msg_list, struct message, entry )
|
||||||
{
|
{
|
||||||
if (get_hardware_msg_bit( other ) == clr_bit)
|
if (other != input->msg && get_hardware_msg_bit( other ) == clr_bit)
|
||||||
{
|
{
|
||||||
clr_bit = 0;
|
clr_bit = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (clr_bit) clear_queue_bits( thread->queue, clr_bit );
|
if (clr_bit) clear_queue_bits( thread->queue, clr_bit );
|
||||||
|
}
|
||||||
|
|
||||||
|
if (new_win) /* set the new window */
|
||||||
|
{
|
||||||
|
struct thread *owner = get_window_thread( new_win );
|
||||||
|
if (owner)
|
||||||
|
{
|
||||||
|
input->msg->win = new_win;
|
||||||
|
set_queue_bits( owner->queue, get_hardware_msg_bit( input->msg ));
|
||||||
|
release_object( owner );
|
||||||
|
}
|
||||||
|
if (!remove) return; /* don't release the message */
|
||||||
|
}
|
||||||
|
else if (remove)
|
||||||
|
{
|
||||||
|
update_input_key_state( input, input->msg );
|
||||||
|
list_remove( &input->msg->entry );
|
||||||
free_message( input->msg );
|
free_message( input->msg );
|
||||||
}
|
}
|
||||||
release_object( input->msg_thread );
|
release_object( input->msg_thread );
|
||||||
|
@ -1513,7 +1530,7 @@ DECL_HANDLER(get_message)
|
||||||
if (queue->input->msg_thread == current && req->get_next_hw)
|
if (queue->input->msg_thread == current && req->get_next_hw)
|
||||||
{
|
{
|
||||||
first_hw_msg = queue->input->msg;
|
first_hw_msg = queue->input->msg;
|
||||||
release_hardware_message( current, 0 );
|
release_hardware_message( current, 0, 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* first check for sent messages */
|
/* first check for sent messages */
|
||||||
|
@ -1577,23 +1594,29 @@ DECL_HANDLER(get_message)
|
||||||
/* reply to a sent message */
|
/* reply to a sent message */
|
||||||
DECL_HANDLER(reply_message)
|
DECL_HANDLER(reply_message)
|
||||||
{
|
{
|
||||||
if (!current->queue)
|
if (!current->queue) set_error( STATUS_ACCESS_DENIED );
|
||||||
{
|
|
||||||
set_error( STATUS_ACCESS_DENIED );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (req->type == MSG_HARDWARE)
|
|
||||||
{
|
|
||||||
struct thread_input *input = current->queue->input;
|
|
||||||
if (input->msg_thread == current) release_hardware_message( current, req->remove );
|
|
||||||
else set_error( STATUS_ACCESS_DENIED );
|
|
||||||
}
|
|
||||||
else if (current->queue->recv_result)
|
else if (current->queue->recv_result)
|
||||||
reply_message( current->queue, req->result, 0, req->remove,
|
reply_message( current->queue, req->result, 0, req->remove,
|
||||||
get_req_data(), get_req_data_size() );
|
get_req_data(), get_req_data_size() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* accept the current hardware message */
|
||||||
|
DECL_HANDLER(accept_hardware_message)
|
||||||
|
{
|
||||||
|
if (current->queue)
|
||||||
|
{
|
||||||
|
struct thread_input *input = current->queue->input;
|
||||||
|
if (input->msg_thread == current)
|
||||||
|
{
|
||||||
|
release_hardware_message( current, req->remove, req->new_win );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set_error( STATUS_ACCESS_DENIED );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* retrieve the reply for the last message sent */
|
/* retrieve the reply for the last message sent */
|
||||||
DECL_HANDLER(get_message_reply)
|
DECL_HANDLER(get_message_reply)
|
||||||
{
|
{
|
||||||
|
|
|
@ -225,6 +225,7 @@ DECL_HANDLER(wait_input_idle);
|
||||||
DECL_HANDLER(send_message);
|
DECL_HANDLER(send_message);
|
||||||
DECL_HANDLER(get_message);
|
DECL_HANDLER(get_message);
|
||||||
DECL_HANDLER(reply_message);
|
DECL_HANDLER(reply_message);
|
||||||
|
DECL_HANDLER(accept_hardware_message);
|
||||||
DECL_HANDLER(get_message_reply);
|
DECL_HANDLER(get_message_reply);
|
||||||
DECL_HANDLER(set_win_timer);
|
DECL_HANDLER(set_win_timer);
|
||||||
DECL_HANDLER(kill_win_timer);
|
DECL_HANDLER(kill_win_timer);
|
||||||
|
@ -415,6 +416,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
|
||||||
(req_handler)req_send_message,
|
(req_handler)req_send_message,
|
||||||
(req_handler)req_get_message,
|
(req_handler)req_get_message,
|
||||||
(req_handler)req_reply_message,
|
(req_handler)req_reply_message,
|
||||||
|
(req_handler)req_accept_hardware_message,
|
||||||
(req_handler)req_get_message_reply,
|
(req_handler)req_get_message_reply,
|
||||||
(req_handler)req_set_win_timer,
|
(req_handler)req_set_win_timer,
|
||||||
(req_handler)req_kill_win_timer,
|
(req_handler)req_kill_win_timer,
|
||||||
|
|
|
@ -1895,13 +1895,18 @@ static void dump_get_message_reply( const struct get_message_reply *req )
|
||||||
|
|
||||||
static void dump_reply_message_request( const struct reply_message_request *req )
|
static void dump_reply_message_request( const struct reply_message_request *req )
|
||||||
{
|
{
|
||||||
fprintf( stderr, " type=%d,", req->type );
|
|
||||||
fprintf( stderr, " result=%08x,", req->result );
|
fprintf( stderr, " result=%08x,", req->result );
|
||||||
fprintf( stderr, " remove=%d,", req->remove );
|
fprintf( stderr, " remove=%d,", req->remove );
|
||||||
fprintf( stderr, " data=" );
|
fprintf( stderr, " data=" );
|
||||||
dump_varargs_bytes( cur_size );
|
dump_varargs_bytes( cur_size );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void dump_accept_hardware_message_request( const struct accept_hardware_message_request *req )
|
||||||
|
{
|
||||||
|
fprintf( stderr, " remove=%d,", req->remove );
|
||||||
|
fprintf( stderr, " new_win=%p", req->new_win );
|
||||||
|
}
|
||||||
|
|
||||||
static void dump_get_message_reply_request( const struct get_message_reply_request *req )
|
static void dump_get_message_reply_request( const struct get_message_reply_request *req )
|
||||||
{
|
{
|
||||||
fprintf( stderr, " cancel=%d", req->cancel );
|
fprintf( stderr, " cancel=%d", req->cancel );
|
||||||
|
@ -2814,6 +2819,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
|
||||||
(dump_func)dump_send_message_request,
|
(dump_func)dump_send_message_request,
|
||||||
(dump_func)dump_get_message_request,
|
(dump_func)dump_get_message_request,
|
||||||
(dump_func)dump_reply_message_request,
|
(dump_func)dump_reply_message_request,
|
||||||
|
(dump_func)dump_accept_hardware_message_request,
|
||||||
(dump_func)dump_get_message_reply_request,
|
(dump_func)dump_get_message_reply_request,
|
||||||
(dump_func)dump_set_win_timer_request,
|
(dump_func)dump_set_win_timer_request,
|
||||||
(dump_func)dump_kill_win_timer_request,
|
(dump_func)dump_kill_win_timer_request,
|
||||||
|
@ -3001,6 +3007,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
|
||||||
(dump_func)0,
|
(dump_func)0,
|
||||||
(dump_func)dump_get_message_reply,
|
(dump_func)dump_get_message_reply,
|
||||||
(dump_func)0,
|
(dump_func)0,
|
||||||
|
(dump_func)0,
|
||||||
(dump_func)dump_get_message_reply_reply,
|
(dump_func)dump_get_message_reply_reply,
|
||||||
(dump_func)dump_set_win_timer_reply,
|
(dump_func)dump_set_win_timer_reply,
|
||||||
(dump_func)0,
|
(dump_func)0,
|
||||||
|
@ -3188,6 +3195,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
|
||||||
"send_message",
|
"send_message",
|
||||||
"get_message",
|
"get_message",
|
||||||
"reply_message",
|
"reply_message",
|
||||||
|
"accept_hardware_message",
|
||||||
"get_message_reply",
|
"get_message_reply",
|
||||||
"set_win_timer",
|
"set_win_timer",
|
||||||
"kill_win_timer",
|
"kill_win_timer",
|
||||||
|
|
Loading…
Reference in New Issue