From: "Rémi Bernon" Subject: [PATCH 2/7] server: Implement rawinput hardware message broadcast. Message-Id: <20190919120721.31604-3-rbernon@codeweavers.com> Date: Thu, 19 Sep 2019 14:07:16 +0200 In-Reply-To: <20190919120721.31604-1-rbernon@codeweavers.com> References: <20190919120721.31604-1-rbernon@codeweavers.com> We now broadcast rawinput messages to all listening processes when a driver sends input with the SEND_HWMSG_BCAST_RAW flag, instead of looking for registered rawdevices in the current process. For now, only the foreground window thread will receive the rawinput messages. Signed-off-by: Rémi Bernon --- server/protocol.def | 1 + server/queue.c | 95 +++++++++++++++++++++++++++++++++++---------- 2 files changed, 75 insertions(+), 21 deletions(-) diff --git a/server/protocol.def b/server/protocol.def index ab3af90545b..3b5da8dcaed 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -2317,6 +2317,7 @@ enum message_type #define SEND_HWMSG_INJECTED 0x01 #define SEND_HWMSG_ONLY_RAW 0x02 #define SEND_HWMSG_SKIP_RAW 0x04 +#define SEND_HWMSG_BCAST_RAW 0x08 /* Get a message from the current queue */ diff --git a/server/queue.c b/server/queue.c index a18f3cdea00..d883811449e 100644 --- a/server/queue.c +++ b/server/queue.c @@ -1596,12 +1596,64 @@ static int send_hook_ll_message( struct desktop *desktop, struct message *hardwa return 1; } +struct rawinput_message +{ + struct desktop *desktop; + struct hw_msg_source source; + unsigned int time; + struct hardware_msg_data data; +}; + +static int queue_rawinput_message( struct process* process, void* user ) +{ + const struct rawinput_message* raw_msg = user; + const struct rawinput_device *device = NULL; + struct desktop *desktop = NULL; + struct thread *thread = NULL; + struct message *msg; + + if (raw_msg->data.rawinput.type == RIM_TYPEMOUSE) + device = process->rawinput_mouse; + else if (raw_msg->data.rawinput.type == RIM_TYPEKEYBOARD) + device = process->rawinput_kbd; + + if (!device) + return 0; + + if (!(desktop = get_desktop_obj( process, process->desktop, 0 )) || + (raw_msg->desktop && desktop != raw_msg->desktop)) + goto done; + + if (!(thread = get_window_thread( device->target ? device->target : desktop->foreground_input->active )) || + process != thread->process) + goto done; + + if (thread->queue->input != desktop->foreground_input) + goto done; + + if (!(msg = alloc_hardware_message( raw_msg->data.info, raw_msg->source, raw_msg->time ))) + goto done; + + msg->win = device->target; + msg->msg = WM_INPUT; + msg->wparam = RIM_INPUT; + msg->lparam = 0; + memcpy( msg->data, &raw_msg->data, sizeof(raw_msg->data) ); + + queue_hardware_message( desktop, msg, 0 ); + +done: + if (thread) release_object( thread ); + if (desktop) release_object( desktop ); + return 0; +} + /* queue a hardware message for a mouse event */ static int queue_mouse_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 struct rawinput_device *device; struct hardware_msg_data *msg_data; + struct rawinput_message raw_msg; struct message *msg; unsigned int i, time, flags; struct hw_msg_source source = { IMDT_MOUSE, origin }; @@ -1651,24 +1703,24 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons y = desktop->cursor.y; } - if ((device = current->process->rawinput_mouse) && - !(req_flags & SEND_HWMSG_SKIP_RAW)) + if (!(req_flags & SEND_HWMSG_SKIP_RAW)) { - if (!(msg = alloc_hardware_message( input->mouse.info, source, time ))) return 0; - msg_data = msg->data; - - msg->win = device->target; - msg->msg = WM_INPUT; - msg->wparam = RIM_INPUT; - msg->lparam = 0; + raw_msg.desktop = desktop; + raw_msg.source = source; + raw_msg.time = time; + msg_data = &raw_msg.data; + msg_data->info = input->mouse.info; msg_data->flags = flags; msg_data->rawinput.type = RIM_TYPEMOUSE; msg_data->rawinput.mouse.x = x - desktop->cursor.x; msg_data->rawinput.mouse.y = y - desktop->cursor.y; msg_data->rawinput.mouse.data = input->mouse.data; - queue_hardware_message( desktop, msg, 0 ); + if (req_flags & SEND_HWMSG_BCAST_RAW) + enum_processes( queue_rawinput_message, &raw_msg ); + else + queue_rawinput_message( current->process, &raw_msg ); } if (req_flags & SEND_HWMSG_ONLY_RAW) @@ -1708,8 +1760,8 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c unsigned int origin, struct msg_queue *sender, unsigned int req_flags ) { struct hw_msg_source source = { IMDT_KEYBOARD, origin }; - const struct rawinput_device *device; struct hardware_msg_data *msg_data; + struct rawinput_message raw_msg; struct message *msg; unsigned char vkey = input->kbd.vkey; unsigned int message_code, time; @@ -1781,23 +1833,24 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c break; } - if ((device = current->process->rawinput_kbd) && - !(req_flags & SEND_HWMSG_SKIP_RAW)) + if (!(req_flags & SEND_HWMSG_SKIP_RAW)) { - if (!(msg = alloc_hardware_message( input->kbd.info, source, time ))) return 0; - msg_data = msg->data; - - msg->win = device->target; - msg->msg = WM_INPUT; - msg->wparam = RIM_INPUT; + raw_msg.desktop = desktop; + raw_msg.source = source; + raw_msg.time = time; + msg_data = &raw_msg.data; + msg_data->info = input->kbd.info; msg_data->flags = input->kbd.flags; msg_data->rawinput.type = RIM_TYPEKEYBOARD; msg_data->rawinput.kbd.message = message_code; msg_data->rawinput.kbd.vkey = vkey; msg_data->rawinput.kbd.scan = input->kbd.scan; - queue_hardware_message( desktop, msg, 0 ); + if (req_flags & SEND_HWMSG_BCAST_RAW) + enum_processes( queue_rawinput_message, &raw_msg ); + else + queue_rawinput_message( current->process, &raw_msg ); } if (req_flags & SEND_HWMSG_ONLY_RAW) -- 2.23.0