server: Pass the original hardware input data to the server and set the message parameters on the server side.

This commit is contained in:
Alexandre Julliard 2011-03-01 20:33:15 +01:00
parent e572dca4cc
commit 02e30f5f77
8 changed files with 267 additions and 81 deletions

View File

@ -1156,7 +1156,6 @@ void X11DRV_send_keyboard_input( HWND hwnd, WORD wVk, WORD wScan, DWORD event_fl
UINT message;
KBDLLHOOKSTRUCT hook;
WORD flags, wVkStripped, wVkL, wVkR, vk_hook = wVk;
LPARAM lParam = 0;
if (!time) time = GetTickCount();
@ -1225,13 +1224,7 @@ void X11DRV_send_keyboard_input( HWND hwnd, WORD wVk, WORD wScan, DWORD event_fl
if (!(event_flags & KEYEVENTF_UNICODE) && key_state_table[wVk] & 0x80) flags |= KF_REPEAT;
}
if (event_flags & KEYEVENTF_UNICODE)
{
vk_hook = wVk = VK_PACKET;
lParam = MAKELPARAM(1 /* repeat count */, wScan);
TRACE_(key)("message=0x%04x wParam=0x%04X lParam=0x%08lx\n",
message, wVk, lParam);
}
if (event_flags & KEYEVENTF_UNICODE) vk_hook = wVk = VK_PACKET;
/* Hook gets whatever key was sent. */
hook.vkCode = vk_hook;
@ -1254,25 +1247,22 @@ void X11DRV_send_keyboard_input( HWND hwnd, WORD wVk, WORD wScan, DWORD event_fl
key_state_table[wVk] |= 0xc0;
key_state_table[wVkStripped] = key_state_table[wVkL] | key_state_table[wVkR];
}
if (key_state_table[VK_MENU] & 0x80) flags |= KF_ALTDOWN;
if (wVkStripped == VK_SHIFT) flags &= ~KF_EXTENDED;
lParam = MAKELPARAM(1 /* repeat count */, flags);
TRACE_(key)(" message=0x%04x wParam=0x%04X, lParam=0x%08lx, InputKeyState=0x%x\n",
message, wVk, lParam, key_state_table[wVk]);
}
TRACE_(key)("message=0x%04x wParam=0x%04x InputKeyState=0x%x\n",
message, wVk, key_state_table[wVk]);
SERVER_START_REQ( send_hardware_message )
{
req->win = wine_server_user_handle( hwnd );
req->msg = message;
req->wparam = wVk;
req->lparam = lParam;
req->time = time;
req->info = dwExtraInfo;
req->win = wine_server_user_handle( hwnd );
req->msg = message;
req->input.type = INPUT_KEYBOARD;
req->input.kbd.vkey = vk_hook;
req->input.kbd.scan = wScan;
req->input.kbd.flags = event_flags;
req->input.kbd.time = time;
req->input.kbd.info = dwExtraInfo;
if (injected_flags & LLKHF_INJECTED) req->flags = SEND_HWMSG_INJECTED;
wine_server_call( req );
}
SERVER_END_REQ;

View File

@ -306,14 +306,16 @@ static void queue_raw_mouse_message( UINT message, HWND hwnd, DWORD x, DWORD y,
SERVER_START_REQ( send_hardware_message )
{
req->win = wine_server_user_handle( hwnd );
req->msg = message;
req->wparam = MAKEWPARAM( 0, data );
req->lparam = 0;
req->x = x;
req->y = y;
req->time = time;
req->info = extra_info;
req->win = wine_server_user_handle( hwnd );
req->msg = message;
req->input.type = INPUT_MOUSE;
req->input.mouse.x = x;
req->input.mouse.y = y;
req->input.mouse.data = data;
req->input.mouse.flags = 0; /* FIXME */
req->input.mouse.time = time;
req->input.mouse.info = extra_info;
if (injected_flags & LLMHF_INJECTED) req->flags = SEND_HWMSG_INJECTED;
wine_server_call( req );
}
SERVER_END_REQ;

View File

@ -301,6 +301,36 @@ struct winevent_msg_data
};
typedef union
{
int type;
struct
{
int type;
unsigned short vkey;
unsigned short scan;
unsigned int flags;
unsigned int time;
lparam_t info;
} kbd;
struct
{
int type;
int x;
int y;
unsigned int data;
unsigned int flags;
unsigned int time;
lparam_t info;
} mouse;
struct
{
int type;
unsigned int msg;
lparam_t lparam;
} hw;
} hw_input_t;
typedef union
{
unsigned char bytes[1];
@ -2762,18 +2792,15 @@ struct send_hardware_message_request
{
struct request_header __header;
user_handle_t win;
hw_input_t input;
unsigned int flags;
unsigned int msg;
unsigned int time;
lparam_t wparam;
lparam_t lparam;
lparam_t info;
int x;
int y;
};
struct send_hardware_message_reply
{
struct reply_header __header;
};
#define SEND_HWMSG_INJECTED 0x01
@ -5529,6 +5556,6 @@ union generic_reply
struct set_cursor_reply set_cursor_reply;
};
#define SERVER_PROTOCOL_VERSION 415
#define SERVER_PROTOCOL_VERSION 416
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */

View File

@ -317,6 +317,36 @@ struct winevent_msg_data
/* followed by module name if any */
};
typedef union
{
int type;
struct
{
int type; /* INPUT_KEYBOARD */
unsigned short vkey; /* virtual key code */
unsigned short scan; /* scan code */
unsigned int flags; /* event flags */
unsigned int time; /* event time */
lparam_t info; /* extra info */
} kbd;
struct
{
int type; /* INPUT_MOUSE */
int x; /* coordinates */
int y;
unsigned int data; /* mouse data */
unsigned int flags; /* event flags */
unsigned int time; /* event time */
lparam_t info; /* extra info */
} mouse;
struct
{
int type; /* INPUT_HARDWARE */
unsigned int msg; /* message code */
lparam_t lparam; /* message param */
} hw;
} hw_input_t;
typedef union
{
unsigned char bytes[1]; /* raw data for sent messages */
@ -2002,14 +2032,11 @@ enum message_type
/* Send a hardware message to a thread queue */
@REQ(send_hardware_message)
user_handle_t win; /* window handle */
hw_input_t input; /* input data */
unsigned int flags; /* flags (see below) */
unsigned int msg; /* message code */
unsigned int time; /* message time */
lparam_t wparam; /* parameters */
lparam_t lparam; /* parameters */
lparam_t info; /* extra info */
int x; /* x position */
int y; /* y position */
@END
#define SEND_HWMSG_INJECTED 0x01
/* Get a message from the current queue */

View File

@ -1282,7 +1282,13 @@ static void queue_hardware_message( struct desktop *desktop, struct message *msg
update_input_key_state( desktop, desktop->keystate, msg );
last_input_time = get_tick_count();
if (!is_keyboard_msg( msg ))
if (is_keyboard_msg( msg ))
{
if (desktop->keystate[VK_MENU] & 0x80) msg->lparam |= KF_ALTDOWN << 16;
if (msg->wparam == VK_SHIFT || msg->wparam == VK_LSHIFT || msg->wparam == VK_RSHIFT)
msg->lparam &= ~(KF_EXTENDED << 16);
}
else
{
if (msg->msg == WM_MOUSEMOVE) set_cursor_pos( desktop, data->x, data->y );
if (desktop->keystate[VK_LBUTTON] & 0x80) msg->wparam |= MK_LBUTTON;
@ -1322,6 +1328,128 @@ static void queue_hardware_message( struct desktop *desktop, struct message *msg
release_object( thread );
}
/* queue a hardware message for a mouse event */
static void queue_mouse_message( struct desktop *desktop, user_handle_t win, unsigned int message,
const hw_input_t *input )
{
struct hardware_msg_data *msg_data;
struct message *msg;
if (!(msg = mem_alloc( sizeof(*msg) ))) return;
if (!(msg_data = mem_alloc( sizeof(*msg_data) )))
{
free( msg );
return;
}
memset( msg_data, 0, sizeof(*msg_data) );
msg->type = MSG_HARDWARE;
msg->win = get_user_full_handle( win );
msg->msg = message;
msg->wparam = input->mouse.data << 16;
msg->lparam = 0;
msg->time = input->mouse.time;
msg->result = NULL;
msg->data = msg_data;
msg->data_size = sizeof(*msg_data);
msg_data->x = input->mouse.x;
msg_data->y = input->mouse.y;
msg_data->info = input->mouse.info;
if (!msg->time) msg->time = get_tick_count();
queue_hardware_message( desktop, msg );
}
/* queue a hardware message for a keyboard event */
static void queue_keyboard_message( struct desktop *desktop, user_handle_t win, unsigned int message,
const hw_input_t *input )
{
struct hardware_msg_data *msg_data;
struct message *msg;
unsigned char vkey = input->kbd.vkey;
if (!(msg = mem_alloc( sizeof(*msg) ))) return;
if (!(msg_data = mem_alloc( sizeof(*msg_data) )))
{
free( msg );
return;
}
memset( msg_data, 0, sizeof(*msg_data) );
msg->type = MSG_HARDWARE;
msg->win = get_user_full_handle( win );
msg->msg = message;
msg->lparam = (input->kbd.scan << 16) | 1; /* repeat count */
msg->time = input->kbd.time;
msg->result = NULL;
msg->data = msg_data;
msg->data_size = sizeof(*msg_data);
msg_data->info = input->kbd.info;
if (!msg->time) msg->time = get_tick_count();
if (input->kbd.flags & KEYEVENTF_UNICODE)
{
msg->wparam = VK_PACKET;
}
else
{
switch (vkey)
{
case VK_MENU:
case VK_LMENU:
case VK_RMENU:
vkey = (input->kbd.flags & KEYEVENTF_EXTENDEDKEY) ? VK_RMENU : VK_LMENU;
break;
case VK_CONTROL:
case VK_LCONTROL:
case VK_RCONTROL:
vkey = (input->kbd.flags & KEYEVENTF_EXTENDEDKEY) ? VK_RCONTROL : VK_LCONTROL;
break;
case VK_SHIFT:
case VK_LSHIFT:
case VK_RSHIFT:
vkey = (input->kbd.flags & KEYEVENTF_EXTENDEDKEY) ? VK_RSHIFT : VK_LSHIFT;
break;
}
if (input->kbd.flags & KEYEVENTF_EXTENDEDKEY) msg->lparam |= KF_EXTENDED << 16;
/* 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;
msg->wparam = vkey;
}
queue_hardware_message( desktop, msg );
}
/* queue a hardware message for a custom type of event */
static void queue_custom_hardware_message( struct desktop *desktop, user_handle_t win,
const hw_input_t *input )
{
struct hardware_msg_data *msg_data;
struct message *msg;
if (!(msg = mem_alloc( sizeof(*msg) ))) return;
if (!(msg_data = mem_alloc( sizeof(*msg_data) )))
{
free( msg );
return;
}
memset( msg_data, 0, sizeof(*msg_data) );
msg->type = MSG_HARDWARE;
msg->win = get_user_full_handle( win );
msg->msg = input->hw.msg;
msg->wparam = 0;
msg->lparam = input->hw.lparam;
msg->time = get_tick_count();
msg->result = NULL;
msg->data = msg_data;
msg->data_size = sizeof(*msg_data);
queue_hardware_message( desktop, msg );
}
/* check message filter for a hardware message */
static int check_hw_message_filter( user_handle_t win, unsigned int msg_code,
user_handle_t filter_win, unsigned int first, unsigned int last )
@ -1735,10 +1863,8 @@ DECL_HANDLER(send_message)
/* send a hardware message to a thread queue */
DECL_HANDLER(send_hardware_message)
{
struct message *msg;
struct thread *thread = NULL;
struct desktop *desktop;
struct hardware_msg_data *data;
if (req->win)
{
@ -1747,29 +1873,20 @@ DECL_HANDLER(send_hardware_message)
}
else if (!(desktop = get_thread_desktop( current, 0 ))) return;
if (!(data = mem_alloc( sizeof(*data) ))) goto done;
memset( data, 0, sizeof(*data) );
data->x = req->x;
data->y = req->y;
data->info = req->info;
if ((msg = mem_alloc( sizeof(*msg) )))
switch (req->input.type)
{
msg->type = MSG_HARDWARE;
msg->win = get_user_full_handle( req->win );
msg->msg = req->msg;
msg->wparam = req->wparam;
msg->lparam = req->lparam;
msg->time = req->time;
msg->result = NULL;
msg->data = data;
msg->data_size = sizeof(*data);
queue_hardware_message( desktop, msg );
case INPUT_MOUSE:
queue_mouse_message( desktop, req->win, req->msg, &req->input );
break;
case INPUT_KEYBOARD:
queue_keyboard_message( desktop, req->win, req->msg, &req->input );
break;
case INPUT_HARDWARE:
queue_custom_hardware_message( desktop, req->win, &req->input );
break;
default:
set_error( STATUS_INVALID_PARAMETER );
}
else free( data );
done:
if (thread) release_object( thread );
release_object( desktop );
}

View File

@ -617,6 +617,7 @@ C_ASSERT( sizeof(client_ptr_t) == 8 );
C_ASSERT( sizeof(cpu_type_t) == 4 );
C_ASSERT( sizeof(data_size_t) == 4 );
C_ASSERT( sizeof(file_pos_t) == 8 );
C_ASSERT( sizeof(hw_input_t) == 32 );
C_ASSERT( sizeof(int) == 4 );
C_ASSERT( sizeof(ioctl_code_t) == 4 );
C_ASSERT( sizeof(lparam_t) == 8 );
@ -1378,13 +1379,9 @@ C_ASSERT( sizeof(struct send_message_request) == 56 );
C_ASSERT( FIELD_OFFSET(struct post_quit_message_request, exit_code) == 12 );
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, msg) == 16 );
C_ASSERT( FIELD_OFFSET(struct send_hardware_message_request, time) == 20 );
C_ASSERT( FIELD_OFFSET(struct send_hardware_message_request, wparam) == 24 );
C_ASSERT( FIELD_OFFSET(struct send_hardware_message_request, lparam) == 32 );
C_ASSERT( FIELD_OFFSET(struct send_hardware_message_request, info) == 40 );
C_ASSERT( FIELD_OFFSET(struct send_hardware_message_request, x) == 48 );
C_ASSERT( FIELD_OFFSET(struct send_hardware_message_request, y) == 52 );
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 get_message_request, flags) == 12 );
C_ASSERT( FIELD_OFFSET(struct get_message_request, get_win) == 16 );

View File

@ -36,6 +36,7 @@
#include "winbase.h"
#include "wincon.h"
#include "winternl.h"
#include "winuser.h"
#include "winioctl.h"
#include "file.h"
#include "request.h"
@ -293,6 +294,34 @@ static void dump_async_data( const char *prefix, const async_data_t *data )
fputc( '}', stderr );
}
static void dump_hw_input( const char *prefix, const hw_input_t *input )
{
switch (input->type)
{
case INPUT_MOUSE:
fprintf( stderr, "%s{type=MOUSE,x=%d,y=%d,data=%08x,flags=%08x,time=%u",
prefix, input->mouse.x, input->mouse.y, input->mouse.data, input->mouse.flags,
input->mouse.time );
dump_uint64( ",info=", &input->mouse.info );
fputc( '}', stderr );
break;
case INPUT_KEYBOARD:
fprintf( stderr, "%s{type=KEYBOARD,vkey=%04hx,scan=%04hx,flags=%08x,time=%u",
prefix, input->kbd.vkey, input->kbd.scan, input->kbd.flags, input->kbd.time );
dump_uint64( ",info=", &input->kbd.info );
fputc( '}', stderr );
break;
case INPUT_HARDWARE:
fprintf( stderr, "%s{type=HARDWARE,msg=%04x", prefix, input->hw.msg );
dump_uint64( ",lparam=", &input->hw.lparam );
fputc( '}', stderr );
break;
default:
fprintf( stderr, "%s{type=%04x}", prefix, input->type );
break;
}
}
static void dump_luid( const char *prefix, const luid_t *luid )
{
fprintf( stderr, "%s%d.%u", prefix, luid->high_part, luid->low_part );
@ -2465,13 +2494,9 @@ static void dump_post_quit_message_request( const struct post_quit_message_reque
static void dump_send_hardware_message_request( const struct send_hardware_message_request *req )
{
fprintf( stderr, " win=%08x", req->win );
dump_hw_input( ", input=", &req->input );
fprintf( stderr, ", flags=%08x", req->flags );
fprintf( stderr, ", msg=%08x", req->msg );
fprintf( stderr, ", time=%08x", req->time );
dump_uint64( ", wparam=", &req->wparam );
dump_uint64( ", lparam=", &req->lparam );
dump_uint64( ", info=", &req->info );
fprintf( stderr, ", x=%d", req->x );
fprintf( stderr, ", y=%d", req->y );
}
static void dump_get_message_request( const struct get_message_request *req )

View File

@ -51,6 +51,7 @@ my %formats =
"luid_t" => [ 8, 4, "&dump_luid" ],
"ioctl_code_t" => [ 4, 4, "&dump_ioctl_code" ],
"cpu_type_t" => [ 4, 4, "&dump_cpu_type" ],
"hw_input_t" => [ 32, 8, "&dump_hw_input" ],
);
my @requests = ();