server: Invoke low-level hardware hooks directly from the server side.

This commit is contained in:
Alexandre Julliard 2011-03-02 19:53:03 +01:00
parent ae895a1f10
commit c7efa293f0
10 changed files with 211 additions and 143 deletions

View File

@ -2709,6 +2709,38 @@ static BOOL peek_message( MSG *msg, HWND hwnd, UINT first, UINT last, UINT flags
info.msg.lParam, msg_data->winevent.tid, info.msg.time);
}
continue;
case MSG_HOOK_LL:
info.flags = ISMEX_SEND;
result = 0;
if (info.msg.message == WH_KEYBOARD_LL && size >= sizeof(msg_data->hardware))
{
KBDLLHOOKSTRUCT hook;
hook.vkCode = LOWORD( info.msg.lParam );
hook.scanCode = HIWORD( info.msg.lParam );
hook.flags = msg_data->hardware.flags;
hook.time = info.msg.time;
hook.dwExtraInfo = msg_data->hardware.info;
TRACE( "calling keyboard LL hook vk %x scan %x flags %x time %u info %lx\n",
hook.vkCode, hook.scanCode, hook.flags, hook.time, hook.dwExtraInfo );
result = HOOK_CallHooks( WH_KEYBOARD_LL, HC_ACTION, info.msg.wParam, (LPARAM)&hook, TRUE );
}
else if (info.msg.message == WH_MOUSE_LL && size >= sizeof(msg_data->hardware))
{
MSLLHOOKSTRUCT hook;
hook.pt.x = msg_data->hardware.x;
hook.pt.y = msg_data->hardware.y;
hook.mouseData = info.msg.lParam;
hook.flags = msg_data->hardware.flags;
hook.time = info.msg.time;
hook.dwExtraInfo = msg_data->hardware.info;
TRACE( "calling mouse LL hook pos %d,%d data %x flags %x time %u info %lx\n",
hook.pt.x, hook.pt.y, hook.mouseData, hook.flags, hook.time, hook.dwExtraInfo );
result = HOOK_CallHooks( WH_MOUSE_LL, HC_ACTION, info.msg.wParam, (LPARAM)&hook, TRUE );
}
reply_message( &info, result, TRUE );
continue;
case MSG_OTHER_PROCESS:
info.flags = ISMEX_SEND;
if (!unpack_message( info.msg.hwnd, info.msg.message, &info.msg.wParam,
@ -3072,7 +3104,15 @@ static BOOL send_message( struct send_message_info *info, DWORD_PTR *res_ptr, BO
*/
NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, UINT flags )
{
struct send_message_info info;
NTSTATUS ret;
BOOL wait;
info.type = MSG_HARDWARE;
info.dest_tid = 0;
info.hwnd = hwnd;
info.flags = 0;
info.timeout = 0;
SERVER_START_REQ( send_hardware_message )
{
@ -3102,8 +3142,16 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, UINT flags )
break;
}
ret = wine_server_call( req );
wait = reply->wait;
}
SERVER_END_REQ;
if (wait)
{
LRESULT ignored;
wait_message_reply( 0 );
retrieve_reply( &info, 0, &ignored );
}
return ret;
}

View File

@ -1155,7 +1155,6 @@ void X11DRV_send_keyboard_input( HWND hwnd, WORD wVk, WORD wScan, DWORD event_fl
{
UINT message;
INPUT input;
KBDLLHOOKSTRUCT hook;
WORD flags, wVkStripped, wVkL, wVkR, vk_hook = wVk;
if (!time) time = GetTickCount();
@ -1227,14 +1226,6 @@ void X11DRV_send_keyboard_input( HWND hwnd, WORD wVk, WORD wScan, DWORD event_fl
if (event_flags & KEYEVENTF_UNICODE) vk_hook = wVk = VK_PACKET;
/* Hook gets whatever key was sent. */
hook.vkCode = vk_hook;
hook.scanCode = wScan;
hook.flags = (flags >> 8) | injected_flags;
hook.time = time;
hook.dwExtraInfo = dwExtraInfo;
if (HOOK_CallHooks( WH_KEYBOARD_LL, HC_ACTION, message, (LPARAM)&hook, TRUE )) return;
input.type = INPUT_KEYBOARD;
input.u.ki.wVk = vk_hook;
input.u.ki.wScan = wScan;

View File

@ -293,7 +293,6 @@ void X11DRV_send_mouse_input( HWND hwnd, DWORD flags, DWORD x, DWORD y,
{
POINT pt;
INPUT input;
MSLLHOOKSTRUCT hook;
if (!time) time = GetTickCount();
@ -308,34 +307,29 @@ void X11DRV_send_mouse_input( HWND hwnd, DWORD flags, DWORD x, DWORD y,
{
pt.x = x;
pt.y = y;
wine_tsx11_lock();
if (cursor_pos.x == x && cursor_pos.y == y &&
(flags & ~(MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE)))
flags &= ~MOUSEEVENTF_MOVE;
wine_tsx11_unlock();
}
}
else if (flags & MOUSEEVENTF_MOVE)
{
int accel[3], xMult = 1, yMult = 1;
int accel[3];
/* dx and dy can be negative numbers for relative movements */
SystemParametersInfoW(SPI_GETMOUSE, 0, accel, 0);
if (abs(x) > accel[0] && accel[2] != 0)
{
xMult = 2;
if ((abs(x) > accel[1]) && (accel[2] == 2)) xMult = 4;
x = (int)x * 2;
if ((abs(x) > accel[1]) && (accel[2] == 2)) x = (int)x * 2;
}
if (abs(y) > accel[0] && accel[2] != 0)
{
yMult = 2;
if ((abs(y) > accel[1]) && (accel[2] == 2)) yMult = 4;
y = (int)y * 2;
if ((abs(y) > accel[1]) && (accel[2] == 2)) y = (int)y * 2;
}
wine_tsx11_lock();
pt.x = cursor_pos.x + (long)x * xMult;
pt.y = cursor_pos.y + (long)y * yMult;
pt.x = cursor_pos.x + x;
pt.y = cursor_pos.y + y;
wine_tsx11_unlock();
}
else
@ -345,85 +339,28 @@ void X11DRV_send_mouse_input( HWND hwnd, DWORD flags, DWORD x, DWORD y,
wine_tsx11_unlock();
}
hook.pt.x = pt.x;
hook.pt.y = pt.y;
hook.mouseData = MAKELONG( 0, data );
hook.flags = injected_flags;
hook.time = time;
hook.dwExtraInfo = extra_info;
last_time_modified = GetTickCount();
if (flags & MOUSEEVENTF_MOVE)
{
if (HOOK_CallHooks( WH_MOUSE_LL, HC_ACTION, WM_MOUSEMOVE, (LPARAM)&hook, TRUE )) return;
if ((injected_flags & LLMHF_INJECTED) &&
((flags & MOUSEEVENTF_ABSOLUTE) || x || y)) /* we have to actually move the cursor */
{
clip_point_to_rect( &cursor_clip, &pt );
X11DRV_SetCursorPos( pt.x, pt.y );
}
else
{
wine_tsx11_lock();
clip_point_to_rect( &cursor_clip, &pt);
cursor_pos = pt;
wine_tsx11_unlock();
}
}
if (flags & MOUSEEVENTF_LEFTDOWN)
{
if (HOOK_CallHooks( WH_MOUSE_LL, HC_ACTION,
GetSystemMetrics(SM_SWAPBUTTON) ? WM_RBUTTONDOWN : WM_LBUTTONDOWN,
(LPARAM)&hook, TRUE )) return;
}
if (flags & MOUSEEVENTF_LEFTUP)
{
if (HOOK_CallHooks( WH_MOUSE_LL, HC_ACTION,
GetSystemMetrics(SM_SWAPBUTTON) ? WM_RBUTTONUP : WM_LBUTTONUP,
(LPARAM)&hook, TRUE )) return;
}
if (flags & MOUSEEVENTF_RIGHTDOWN)
{
if (HOOK_CallHooks( WH_MOUSE_LL, HC_ACTION,
GetSystemMetrics(SM_SWAPBUTTON) ? WM_LBUTTONDOWN : WM_RBUTTONDOWN,
(LPARAM)&hook, TRUE )) return;
}
if (flags & MOUSEEVENTF_RIGHTUP)
{
if (HOOK_CallHooks( WH_MOUSE_LL, HC_ACTION,
GetSystemMetrics(SM_SWAPBUTTON) ? WM_LBUTTONUP : WM_RBUTTONUP,
(LPARAM)&hook, TRUE )) return;
}
if (flags & MOUSEEVENTF_MIDDLEDOWN)
{
if (HOOK_CallHooks( WH_MOUSE_LL, HC_ACTION, WM_MBUTTONDOWN, (LPARAM)&hook, TRUE )) return;
}
if (flags & MOUSEEVENTF_MIDDLEUP)
{
if (HOOK_CallHooks( WH_MOUSE_LL, HC_ACTION, WM_MBUTTONUP, (LPARAM)&hook, TRUE )) return;
}
if (flags & MOUSEEVENTF_WHEEL)
{
if (HOOK_CallHooks( WH_MOUSE_LL, HC_ACTION, WM_MOUSEWHEEL, (LPARAM)&hook, TRUE )) return;
}
if (flags & MOUSEEVENTF_XDOWN)
{
if (HOOK_CallHooks( WH_MOUSE_LL, HC_ACTION, WM_XBUTTONDOWN, (LPARAM)&hook, TRUE )) return;
}
if (flags & MOUSEEVENTF_XUP)
{
if (HOOK_CallHooks( WH_MOUSE_LL, HC_ACTION, WM_XBUTTONUP, (LPARAM)&hook, TRUE )) return;
}
input.type = INPUT_MOUSE;
input.u.mi.dx = pt.x;
input.u.mi.dy = pt.y;
input.u.mi.dx = x;
input.u.mi.dy = y;
input.u.mi.mouseData = data;
input.u.mi.dwFlags = flags | MOUSEEVENTF_ABSOLUTE;
input.u.mi.dwFlags = flags;
input.u.mi.time = time;
input.u.mi.dwExtraInfo = extra_info;
__wine_send_input( hwnd, &input, (injected_flags & LLMHF_INJECTED) != 0 );
if (injected_flags & LLMHF_INJECTED)
{
if ((flags & MOUSEEVENTF_MOVE) &&
((flags & MOUSEEVENTF_ABSOLUTE) || x || y)) /* we have to actually move the cursor */
{
GetCursorPos( &pt );
if (!(flags & MOUSEEVENTF_ABSOLUTE) || pt.x != x || pt.y != y)
X11DRV_SetCursorPos( pt.x, pt.y );
}
}
}
#ifdef SONAME_LIBXCURSOR

View File

@ -283,7 +283,7 @@ struct hardware_msg_data
int x;
int y;
unsigned int hw_id;
int __pad;
unsigned int flags;
};
struct callback_msg_data
@ -2782,7 +2782,8 @@ enum message_type
MSG_OTHER_PROCESS,
MSG_POSTED,
MSG_HARDWARE,
MSG_WINEVENT
MSG_WINEVENT,
MSG_HOOK_LL
};
#define SEND_MSG_ABORT_IF_HUNG 0x01
@ -2794,11 +2795,13 @@ struct send_hardware_message_request
user_handle_t win;
hw_input_t input;
unsigned int flags;
unsigned int msg;
char __pad_52[4];
};
struct send_hardware_message_reply
{
struct reply_header __header;
int wait;
char __pad_12[4];
};
#define SEND_HWMSG_INJECTED 0x01
@ -5556,6 +5559,6 @@ union generic_reply
struct set_cursor_reply set_cursor_reply;
};
#define SERVER_PROTOCOL_VERSION 416
#define SERVER_PROTOCOL_VERSION 417
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */

View File

@ -369,6 +369,17 @@ unsigned int get_active_hooks(void)
return ret;
}
/* return the thread that owns the first global hook */
struct thread *get_first_global_hook( int id )
{
struct hook *hook;
struct hook_table *global_hooks = get_global_hooks( current );
if (!global_hooks) return NULL;
if (!(hook = get_first_valid_hook( global_hooks, id - WH_MINHOOK, EVENT_MIN, 0, 0, 0 ))) return NULL;
return hook->owner;
}
/* set a window hook */
DECL_HANDLER(set_hook)
{

View File

@ -299,7 +299,7 @@ struct hardware_msg_data
int x; /* x position */
int y; /* y position */
unsigned int hw_id; /* unique id */
int __pad;
unsigned int flags; /* hook flags */
};
struct callback_msg_data
@ -2024,7 +2024,8 @@ enum message_type
MSG_OTHER_PROCESS, /* sent from other process, may include vararg data, always Unicode */
MSG_POSTED, /* posted message (from PostMessageW), always Unicode */
MSG_HARDWARE, /* hardware message */
MSG_WINEVENT /* winevent message */
MSG_WINEVENT, /* winevent message */
MSG_HOOK_LL /* low-level hardware hook */
};
#define SEND_MSG_ABORT_IF_HUNG 0x01
@ -2034,7 +2035,8 @@ enum message_type
user_handle_t win; /* window handle */
hw_input_t input; /* input data */
unsigned int flags; /* flags (see below) */
unsigned int msg; /* message code */
@REPLY
int wait; /* do we need to wait for a reply? */
@END
#define SEND_HWMSG_INJECTED 0x01

View File

@ -58,6 +58,8 @@ struct message_result
int replied; /* has it been replied to? */
unsigned int error; /* error code to pass back to sender */
lparam_t result; /* reply result */
struct message *hardware_msg; /* hardware message if low-level hook result */
struct desktop *desktop; /* desktop for hardware message */
struct message *callback_msg; /* message to queue for callback */
void *data; /* message reply data */
unsigned int data_size; /* size of message reply data */
@ -201,6 +203,7 @@ static const struct object_ops thread_input_ops =
/* pointer to input structure of foreground thread */
static unsigned int last_input_time;
static void queue_hardware_message( struct desktop *desktop, struct message *msg );
static void free_message( struct message *msg );
/* set the caret window in a given thread input */
@ -436,6 +439,8 @@ static void free_result( struct message_result *result )
if (result->timeout) remove_timeout_user( result->timeout );
free( result->data );
if (result->callback_msg) free_message( result->callback_msg );
if (result->hardware_msg) free_message( result->hardware_msg );
if (result->desktop) release_object( result->desktop );
free( result );
}
@ -460,6 +465,17 @@ static void store_message_result( struct message_result *res, lparam_t result, u
remove_timeout_user( res->timeout );
res->timeout = NULL;
}
if (res->hardware_msg)
{
if (!error && result) /* rejected by the hook */
free_message( res->hardware_msg );
else
queue_hardware_message( res->desktop, res->hardware_msg );
res->hardware_msg = NULL;
}
if (res->sender)
{
if (res->callback_msg)
@ -479,7 +495,7 @@ static void store_message_result( struct message_result *res, lparam_t result, u
set_queue_bits( res->sender, QS_SMRESULT );
}
}
else if (!res->receiver) free_result( res );
}
/* free a message when deleting a queue or window */
@ -489,12 +505,8 @@ static void free_message( struct message *msg )
if (result)
{
result->msg = NULL;
if (result->sender)
{
result->receiver = NULL;
store_message_result( result, 0, STATUS_ACCESS_DENIED /*FIXME*/ );
}
else free_result( result );
result->receiver = NULL;
store_message_result( result, 0, STATUS_ACCESS_DENIED /*FIXME*/ );
}
free( msg->data );
free( msg );
@ -535,13 +547,7 @@ static void result_timeout( void *private )
msg->result = NULL;
remove_queue_message( result->receiver, msg, SEND_MESSAGE );
result->receiver = NULL;
if (!result->sender)
{
free_result( result );
return;
}
}
store_message_result( result, 0, STATUS_TIMEOUT );
}
@ -553,13 +559,16 @@ static struct message_result *alloc_message_result( struct msg_queue *send_queue
struct message_result *result = mem_alloc( sizeof(*result) );
if (result)
{
result->msg = msg;
result->sender = send_queue;
result->receiver = recv_queue;
result->replied = 0;
result->data = NULL;
result->data_size = 0;
result->timeout = NULL;
result->msg = msg;
result->sender = send_queue;
result->receiver = recv_queue;
result->replied = 0;
result->data = NULL;
result->data_size = 0;
result->timeout = NULL;
result->hardware_msg = NULL;
result->desktop = NULL;
result->callback_msg = NULL;
if (msg->type == MSG_CALLBACK)
{
@ -586,11 +595,7 @@ static struct message_result *alloc_message_result( struct msg_queue *send_queue
result->callback_msg = callback_msg;
list_add_head( &send_queue->callback_result, &result->sender_entry );
}
else
{
result->callback_msg = NULL;
list_add_head( &send_queue->send_result, &result->sender_entry );
}
else if (send_queue) list_add_head( &send_queue->send_result, &result->sender_entry );
if (timeout != TIMEOUT_INFINITE)
result->timeout = add_timeout_user( timeout, result_timeout, result );
@ -641,7 +646,7 @@ static void reply_message( struct msg_queue *queue, lparam_t result,
{
queue->recv_result = res->recv_next;
res->receiver = NULL;
if (!res->sender) /* no one waiting for it */
if (!res->sender && !res->hardware_msg) /* no one waiting for it */
{
free_result( res );
return;
@ -1328,13 +1333,58 @@ static void queue_hardware_message( struct desktop *desktop, struct message *msg
release_object( thread );
}
/* send the low-level hook message for a given hardware message */
static int send_hook_ll_message( struct desktop *desktop, struct message *hardware_msg,
const hw_input_t *input, struct msg_queue *sender )
{
struct thread *hook_thread;
struct msg_queue *queue;
struct message *msg;
timeout_t timeout = 2000 * -10000; /* FIXME: load from registry */
int id = (input->type == INPUT_MOUSE) ? WH_MOUSE_LL : WH_KEYBOARD_LL;
if (!(hook_thread = get_first_global_hook( id ))) return 0;
if (!(queue = hook_thread->queue)) return 0;
if (!(msg = mem_alloc( sizeof(*msg) ))) return 0;
msg->type = MSG_HOOK_LL;
msg->win = 0;
msg->msg = id;
msg->wparam = hardware_msg->msg;
msg->time = hardware_msg->time;
msg->data_size = hardware_msg->data_size;
msg->result = NULL;
if (input->type == INPUT_KEYBOARD)
{
unsigned short vkey = input->kbd.vkey;
if (input->kbd.flags & KEYEVENTF_UNICODE) vkey = VK_PACKET;
msg->lparam = (input->kbd.scan << 16) | vkey;
}
else msg->lparam = input->mouse.data;
if (!(msg->data = memdup( hardware_msg->data, hardware_msg->data_size )) ||
!(msg->result = alloc_message_result( sender, queue, msg, timeout )))
{
free_message( msg );
return 0;
}
msg->result->hardware_msg = hardware_msg;
msg->result->desktop = (struct desktop *)grab_object( desktop );
list_add_tail( &queue->msg_list[SEND_MESSAGE], &msg->entry );
set_queue_bits( queue, QS_SENDMESSAGE );
return 1;
}
/* queue a hardware message for a mouse event */
static void queue_mouse_message( struct desktop *desktop, user_handle_t win, const hw_input_t *input )
static int queue_mouse_message( struct desktop *desktop, user_handle_t win, const hw_input_t *input,
unsigned int hook_flags, struct msg_queue *sender )
{
struct hardware_msg_data *msg_data;
struct message *msg;
unsigned int i, time, flags;
int x, y;
int wait = 0, x, y;
static const unsigned int messages[] =
{
@ -1383,12 +1433,13 @@ static void queue_mouse_message( struct desktop *desktop, user_handle_t win, con
{
if (!messages[i]) continue;
if (!(flags & (1 << i))) continue;
flags &= ~(1 << i);
if (!(msg = mem_alloc( sizeof(*msg) ))) return;
if (!(msg = mem_alloc( sizeof(*msg) ))) return 0;
if (!(msg_data = mem_alloc( sizeof(*msg_data) )))
{
free( msg );
return;
return 0;
}
memset( msg_data, 0, sizeof(*msg_data) );
@ -1404,23 +1455,34 @@ static void queue_mouse_message( struct desktop *desktop, user_handle_t win, con
msg_data->x = x;
msg_data->y = y;
msg_data->info = input->mouse.info;
if (hook_flags & SEND_HWMSG_INJECTED) msg_data->flags = LLMHF_INJECTED;
queue_hardware_message( desktop, msg );
/* specify a sender only when sending the last message */
if (!(flags & ((1 << sizeof(messages)/sizeof(messages[0])) - 1)))
{
if (!(wait = send_hook_ll_message( desktop, msg, input, sender )))
queue_hardware_message( desktop, msg );
}
else if (!send_hook_ll_message( desktop, msg, input, NULL ))
queue_hardware_message( desktop, msg );
}
return wait;
}
/* queue a hardware message for a keyboard event */
static void queue_keyboard_message( struct desktop *desktop, user_handle_t win, const hw_input_t *input )
static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, const hw_input_t *input,
unsigned int hook_flags, struct msg_queue *sender )
{
struct hardware_msg_data *msg_data;
struct message *msg;
unsigned char vkey = input->kbd.vkey;
int wait;
if (!(msg = mem_alloc( sizeof(*msg) ))) return;
if (!(msg = mem_alloc( sizeof(*msg) ))) return 0;
if (!(msg_data = mem_alloc( sizeof(*msg_data) )))
{
free( msg );
return;
return 0;
}
memset( msg_data, 0, sizeof(*msg_data) );
@ -1433,6 +1495,7 @@ static void queue_keyboard_message( struct desktop *desktop, user_handle_t win,
msg->data_size = sizeof(*msg_data);
msg_data->info = input->kbd.info;
if (!msg->time) msg->time = get_tick_count();
if (hook_flags & SEND_HWMSG_INJECTED) msg_data->flags = LLKHF_INJECTED;
if (input->kbd.flags & KEYEVENTF_UNICODE)
{
@ -1440,6 +1503,7 @@ static void queue_keyboard_message( struct desktop *desktop, user_handle_t win,
}
else
{
unsigned int flags = 0;
switch (vkey)
{
case VK_MENU:
@ -1458,12 +1522,14 @@ static void queue_keyboard_message( struct desktop *desktop, user_handle_t win,
vkey = (input->kbd.flags & KEYEVENTF_EXTENDEDKEY) ? VK_RSHIFT : VK_LSHIFT;
break;
}
if (input->kbd.flags & KEYEVENTF_EXTENDEDKEY) msg->lparam |= KF_EXTENDED << 16;
if (input->kbd.flags & KEYEVENTF_EXTENDEDKEY) flags |= KF_EXTENDED;
/* FIXME: set KF_DLGMODE and KF_MENUMODE when needed */
if (input->kbd.flags & KEYEVENTF_KEYUP) msg->lparam |= (KF_REPEAT | KF_UP) << 16;
else if (desktop->keystate[vkey] & 0x80) msg->lparam |= KF_REPEAT << 16;
if (input->kbd.flags & KEYEVENTF_KEYUP) flags |= KF_REPEAT | KF_UP;
else if (desktop->keystate[vkey] & 0x80) flags |= KF_REPEAT;
msg->wparam = vkey;
msg->lparam |= flags << 16;
msg_data->flags |= (flags & (KF_EXTENDED | KF_ALTDOWN | KF_UP)) >> 8;
}
msg->msg = (input->kbd.flags & KEYEVENTF_KEYUP) ? WM_KEYUP : WM_KEYDOWN;
@ -1508,8 +1574,10 @@ static void queue_keyboard_message( struct desktop *desktop, user_handle_t win,
desktop->keystate[VK_MENU] &= ~0x02;
break;
}
if (!(wait = send_hook_ll_message( desktop, msg, input, sender )))
queue_hardware_message( desktop, msg );
queue_hardware_message( desktop, msg );
return wait;
}
/* queue a hardware message for a custom type of event */
@ -1941,6 +2009,7 @@ DECL_HANDLER(send_message)
break;
case MSG_HARDWARE: /* should use send_hardware_message instead */
case MSG_CALLBACK_RESULT: /* cannot send this one */
case MSG_HOOK_LL: /* generated internally */
default:
set_error( STATUS_INVALID_PARAMETER );
free( msg );
@ -1955,6 +2024,7 @@ DECL_HANDLER(send_hardware_message)
{
struct thread *thread = NULL;
struct desktop *desktop;
struct msg_queue *sender = get_current_queue();
if (req->win)
{
@ -1966,10 +2036,10 @@ DECL_HANDLER(send_hardware_message)
switch (req->input.type)
{
case INPUT_MOUSE:
queue_mouse_message( desktop, req->win, &req->input );
reply->wait = queue_mouse_message( desktop, req->win, &req->input, req->flags, sender );
break;
case INPUT_KEYBOARD:
queue_keyboard_message( desktop, req->win, &req->input );
reply->wait = queue_keyboard_message( desktop, req->win, &req->input, req->flags, sender );
break;
case INPUT_HARDWARE:
queue_custom_hardware_message( desktop, req->win, &req->input );

View File

@ -1381,8 +1381,9 @@ C_ASSERT( sizeof(struct post_quit_message_request) == 16 );
C_ASSERT( FIELD_OFFSET(struct send_hardware_message_request, win) == 12 );
C_ASSERT( FIELD_OFFSET(struct send_hardware_message_request, input) == 16 );
C_ASSERT( FIELD_OFFSET(struct send_hardware_message_request, flags) == 48 );
C_ASSERT( FIELD_OFFSET(struct send_hardware_message_request, msg) == 52 );
C_ASSERT( sizeof(struct send_hardware_message_request) == 56 );
C_ASSERT( FIELD_OFFSET(struct send_hardware_message_reply, wait) == 8 );
C_ASSERT( sizeof(struct send_hardware_message_reply) == 16 );
C_ASSERT( FIELD_OFFSET(struct get_message_request, flags) == 12 );
C_ASSERT( FIELD_OFFSET(struct get_message_request, get_win) == 16 );
C_ASSERT( FIELD_OFFSET(struct get_message_request, get_first) == 20 );

View File

@ -2496,7 +2496,11 @@ static void dump_send_hardware_message_request( const struct send_hardware_messa
fprintf( stderr, " win=%08x", req->win );
dump_hw_input( ", input=", &req->input );
fprintf( stderr, ", flags=%08x", req->flags );
fprintf( stderr, ", msg=%08x", req->msg );
}
static void dump_send_hardware_message_reply( const struct send_hardware_message_reply *req )
{
fprintf( stderr, " wait=%d", req->wait );
}
static void dump_get_message_request( const struct get_message_request *req )
@ -4275,7 +4279,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_get_process_idle_event_reply,
NULL,
NULL,
NULL,
(dump_func)dump_send_hardware_message_reply,
(dump_func)dump_get_message_reply,
NULL,
NULL,

View File

@ -87,6 +87,7 @@ extern void cleanup_clipboard_thread( struct thread *thread );
extern void remove_thread_hooks( struct thread *thread );
extern unsigned int get_active_hooks(void);
extern struct thread *get_first_global_hook( int id );
/* queue functions */