From: "Rémi Bernon" Subject: [PATCH resend 5/7] server: Add HID input message type to send_hardware_message request. Message-Id: <20191022065700.7216-5-rbernon@codeweavers.com> Date: Tue, 22 Oct 2019 08:56:58 +0200 In-Reply-To: <20191022065700.7216-1-rbernon@codeweavers.com> References: <20191022065700.7216-1-rbernon@codeweavers.com> Signed-off-by: Rémi Bernon --- server/protocol.def | 28 +++++++++++++++++++++++---- server/queue.c | 47 ++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 66 insertions(+), 9 deletions(-) diff --git a/server/protocol.def b/server/protocol.def index 3b5da8dcaed..4352044d795 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -309,6 +309,13 @@ struct hardware_msg_data int y; /* y coordinate */ unsigned int data; /* mouse data */ } mouse; + struct + { + int type; /* RIM_TYPEHID */ + obj_handle_t device; + unsigned int length; /* HID report length */ + /* followed by length bytes of HID report data */ + } hid; } rawinput; }; @@ -332,7 +339,7 @@ typedef union int type; struct { - int type; /* INPUT_KEYBOARD */ + int type; /* HW_INPUT_KEYBOARD */ unsigned short vkey; /* virtual key code */ unsigned short scan; /* scan code */ unsigned int flags; /* event flags */ @@ -341,7 +348,7 @@ typedef union } kbd; struct { - int type; /* INPUT_MOUSE */ + int type; /* HW_INPUT_MOUSE */ int x; /* coordinates */ int y; unsigned int data; /* mouse data */ @@ -351,11 +358,23 @@ typedef union } mouse; struct { - int type; /* INPUT_HARDWARE */ + int type; /* HW_INPUT_HARDWARE */ unsigned int msg; /* message code */ lparam_t lparam; /* message param */ } hw; + struct + { + int type; /* HW_INPUT_HID */ + obj_handle_t device; + unsigned char usage_page; + unsigned char usage; + unsigned int length; + } hid; } hw_input_t; +#define HW_INPUT_KEYBOARD INPUT_KEYBOARD +#define HW_INPUT_MOUSE INPUT_MOUSE +#define HW_INPUT_HARDWARE INPUT_HARDWARE +#define HW_INPUT_HID -1 typedef union { @@ -2304,8 +2323,9 @@ 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 */ + hw_input_t input; unsigned int flags; /* flags (see below) */ + VARARG(data,bytes); /* hid report data */ @REPLY int wait; /* do we need to wait for a reply? */ int prev_x; /* previous cursor position */ diff --git a/server/queue.c b/server/queue.c index 8b9a3d73603..8ea425154cb 100644 --- a/server/queue.c +++ b/server/queue.c @@ -1557,7 +1557,7 @@ static int send_hook_ll_message( struct desktop *desktop, struct message *hardwa 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; + int id = (input->type == HW_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; @@ -1575,7 +1575,7 @@ static int send_hook_ll_message( struct desktop *desktop, struct message *hardwa msg->data_size = hardware_msg->data_size; msg->result = NULL; - if (input->type == INPUT_KEYBOARD) + if (input->type == HW_INPUT_KEYBOARD) { unsigned short vkey = input->kbd.vkey; if (input->kbd.flags & KEYEVENTF_UNICODE) vkey = VK_PACKET; @@ -1601,6 +1601,8 @@ struct rawinput_message struct desktop *desktop; struct hw_msg_source source; unsigned int time; + unsigned char usage_page; + unsigned char usage; struct hardware_msg_data data; const void *extra; data_size_t extra_len; @@ -1609,6 +1611,7 @@ struct rawinput_message static int queue_rawinput_message( struct process* process, void* user ) { const struct rawinput_message* raw_msg = user; + const struct rawinput_device_entry *entry; const struct rawinput_device *device = NULL; struct desktop *desktop = NULL; struct thread *thread = NULL; @@ -1619,6 +1622,8 @@ static int queue_rawinput_message( struct process* process, void* user ) device = process->rawinput_mouse; else if (raw_msg->data.rawinput.type == RIM_TYPEKEYBOARD) device = process->rawinput_kbd; + else if ((entry = find_rawinput_device( process, raw_msg->usage_page, raw_msg->usage ))) + device = &entry->device; if (!device) return 0; @@ -1917,6 +1922,35 @@ static void queue_custom_hardware_message( struct desktop *desktop, user_handle_ queue_hardware_message( desktop, msg, 1 ); } +/* queue a hardware message for an hid event */ +static void queue_hid_message( struct desktop *desktop, user_handle_t win, const hw_input_t *input, + unsigned int origin, struct msg_queue *sender, unsigned int req_flags, + const void *report, data_size_t report_len ) +{ + struct hw_msg_source source = { IMDT_UNAVAILABLE, origin }; + struct hardware_msg_data *msg_data; + struct rawinput_message raw_msg; + + raw_msg.desktop = NULL; /* send to all desktops */ + raw_msg.source = source; + raw_msg.time = get_tick_count(); + raw_msg.usage_page = input->hid.usage_page; + raw_msg.usage = input->hid.usage; + raw_msg.extra = report; + raw_msg.extra_len = report_len; + + msg_data = &raw_msg.data; + msg_data->flags = 0; + msg_data->rawinput.type = RIM_TYPEHID; + msg_data->rawinput.hid.device = input->hid.device; + msg_data->rawinput.hid.length = report_len; + + if (req_flags & SEND_HWMSG_BCAST_RAW) + enum_processes( queue_rawinput_message, &raw_msg ); + else + queue_rawinput_message( current->process, &raw_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 ) @@ -2422,15 +2456,18 @@ DECL_HANDLER(send_hardware_message) switch (req->input.type) { - case INPUT_MOUSE: + case HW_INPUT_MOUSE: reply->wait = queue_mouse_message( desktop, req->win, &req->input, origin, sender, req->flags ); break; - case INPUT_KEYBOARD: + case HW_INPUT_KEYBOARD: reply->wait = queue_keyboard_message( desktop, req->win, &req->input, origin, sender, req->flags ); break; - case INPUT_HARDWARE: + case HW_INPUT_HARDWARE: queue_custom_hardware_message( desktop, req->win, origin, &req->input ); break; + case HW_INPUT_HID: + queue_hid_message( desktop, req->win, &req->input, origin, sender, req->flags, get_req_data(), get_req_data_size() ); + break; default: set_error( STATUS_INVALID_PARAMETER ); } -- 2.24.0.rc0