server: Pass the original hardware input data to the server and set the message parameters on the server side.
This commit is contained in:
parent
e572dca4cc
commit
02e30f5f77
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
165
server/queue.c
165
server/queue.c
|
@ -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 );
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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 = ();
|
||||
|
|
Loading…
Reference in New Issue