Signed-off-by: Derek Lesho dereklesho52@Gmail.com --- v10: - Only send rawinput to foreground window, even if hwnd is specified - Minor structuring adjustments as Remi recommended --- server/protocol.def | 50 ++++++++++++++++++++++++++++----------------- server/queue.c | 48 +++++++++++++++++++++++++++++++++++++++++++ server/trace.c | 21 +++++++++++++++++++ tools/make_requests | 1 + 4 files changed, 101 insertions(+), 19 deletions(-)
diff --git a/server/protocol.def b/server/protocol.def index f7e0008b04..15cd48bbb5 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -286,31 +286,38 @@ struct hw_msg_source unsigned int origin; /* source origin (IMO_* values) */ };
+typedef union +{ + int type; + struct + { + int type; /* RIM_TYPEKEYBOARD */ + unsigned int message; /* message generated by this rawinput event */ + unsigned short vkey; /* virtual key code */ + unsigned short scan; /* scan code */ + } kbd; + struct + { + int type; /* RIM_TYPEMOUSE */ + int x; /* x coordinate */ + int y; /* y coordinate */ + unsigned short button_flags; /* mouse button */ + unsigned short button_data; /* event details */ + } mouse; + struct + { + int type; /* RIM_TYPEHID */ + /* TODO: fill this in if/when necessary */ + } hid; +} hw_rawinput_t; + struct hardware_msg_data { lparam_t info; /* extra info */ unsigned int hw_id; /* unique id */ unsigned int flags; /* hook flags */ struct hw_msg_source source; /* message source */ - union - { - int type; - struct - { - int type; /* RIM_TYPEKEYBOARD */ - unsigned int message; /* message generated by this rawinput event */ - unsigned short vkey; /* virtual key code */ - unsigned short scan; /* scan code */ - } kbd; - struct - { - int type; /* RIM_TYPEMOUSE */ - int x; /* x coordinate */ - int y; /* y coordinate */ - unsigned short button_flags; /* mouse button */ - unsigned short button_data; /* event details */ - } mouse; - } rawinput; + hw_rawinput_t rawinput; };
struct callback_msg_data @@ -2318,6 +2325,11 @@ enum message_type #define SEND_HWMSG_INJECTED 0x01
+@REQ(send_rawinput_message) + hw_rawinput_t input; +@END + + /* Get a message from the current queue */ @REQ(get_message) unsigned int flags; /* PM_* flags */ diff --git a/server/queue.c b/server/queue.c index c87801001e..f2e9c4fab1 100644 --- a/server/queue.c +++ b/server/queue.c @@ -2421,6 +2421,54 @@ DECL_HANDLER(send_hardware_message) release_object( desktop ); }
+/* send a hardware rawinput message to the queue thread */ +DECL_HANDLER(send_rawinput_message) +{ + const struct rawinput_device *device; + struct hardware_msg_data *msg_data; + struct message *msg; + struct desktop *desktop; + struct hw_msg_source source = { IMDT_MOUSE, IMO_HARDWARE }; + + desktop = get_thread_desktop( current, 0 ); + + switch (req->input.type) + { + case RIM_TYPEMOUSE: + if ((device = current->process->rawinput_mouse)) + { + struct thread *thread = device->target ? get_window_thread( device->target ) : NULL; + if ((current->queue->input != desktop->foreground_input) || (thread && thread != current)) + goto done; + + if (!(msg = alloc_hardware_message( 0, source, 0 ))) goto done; + msg_data = msg->data; + + msg->win = device->target; + msg->msg = WM_INPUT; + msg->wparam = RIM_INPUT; + msg->lparam = 0; + + msg_data->flags = 0; + msg_data->rawinput.type = RIM_TYPEMOUSE; + msg_data->rawinput.mouse.x = req->input.mouse.x; + msg_data->rawinput.mouse.y = req->input.mouse.y; + msg_data->rawinput.mouse.button_flags = req->input.mouse.button_flags; + msg_data->rawinput.mouse.button_data = req->input.mouse.button_data; + + queue_hardware_message( desktop, msg, 0 ); + + done: + if (thread) release_object( thread ); + } + break; + default: + set_error( STATUS_INVALID_PARAMETER ); + } + + release_object(desktop); +} + /* post a quit message to the current queue */ DECL_HANDLER(post_quit_message) { diff --git a/server/trace.c b/server/trace.c index 0df649ea29..d849d89772 100644 --- a/server/trace.c +++ b/server/trace.c @@ -405,6 +405,27 @@ static void dump_hw_input( const char *prefix, const hw_input_t *input ) } }
+static void dump_hw_rawinput( const char *prefix, const hw_rawinput_t *rawinput ) +{ + switch (rawinput->type) + { + case RIM_TYPEMOUSE: + fprintf( stderr, "%s{type=MOUSE,x=%d,y=%d,button_flags=%04hx,button_data=%04hx}", + prefix, rawinput->mouse.x, rawinput->mouse.y, rawinput->mouse.button_flags, + rawinput->mouse.button_data); + break; + case RIM_TYPEKEYBOARD: + fprintf( stderr, "%s{type=KEYBOARD}\n", prefix); + break; + case RIM_TYPEHID: + fprintf( stderr, "%s{type=HID}\n", prefix); + break; + default: + fprintf( stderr, "%s{type=%04x}", prefix, rawinput->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 ); diff --git a/tools/make_requests b/tools/make_requests index faeabe5852..8b1f1a263b 100755 --- a/tools/make_requests +++ b/tools/make_requests @@ -53,6 +53,7 @@ my %formats = "ioctl_code_t" => [ 4, 4, "&dump_ioctl_code" ], "client_cpu_t" => [ 4, 4, "&dump_client_cpu" ], "hw_input_t" => [ 32, 8, "&dump_hw_input" ], + "hw_rawinput_t" => [ 16, 8, "&dump_hw_rawinput" ] );
my @requests = ();