[RFC PATCH 3/8] server: Implement raw mouse/keyboard input message broadcast.

Rémi Bernon rbernon at codeweavers.com
Wed Sep 11 09:30:06 CDT 2019


This implements broadcast of raw input messages to all listening
processes when the user driver sends raw input with the BCAST flag.

This allows host drivers to listen to raw input events from a unique
thread, avoiding duplicate input events and the induced computation
cost, as well as the possibility to listen to raw events in background.
---
 server/protocol.def |  1 +
 server/queue.c      | 85 ++++++++++++++++++++++++++++++++++-----------
 2 files changed, 65 insertions(+), 21 deletions(-)

diff --git a/server/protocol.def b/server/protocol.def
index f7ce29977a2..7854e31b2b1 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 a02ef10e742..5f8b82c864c 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -1596,12 +1596,54 @@ static int send_hook_ll_message( struct desktop *desktop, struct message *hardwa
     return 1;
 }
 
+struct raw_input_message
+{
+    struct desktop           *desktop;
+    struct hw_msg_source      source;
+    unsigned int              time;
+    struct hardware_msg_data  data;
+};
+
+static int queue_raw_input_message( struct process* process, void* user )
+{
+    const struct raw_input_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 )) || desktop != raw_msg->desktop)
+        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 raw_input_message raw_msg;
     struct message *msg;
     unsigned int i, time, flags;
     struct hw_msg_source source = { IMDT_MOUSE, origin };
@@ -1651,24 +1693,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_raw_input_message, &raw_msg );
+        else
+            queue_raw_input_message( current->process, &raw_msg );
     }
 
     if (req_flags & SEND_HWMSG_ONLY_RAW)
@@ -1708,8 +1750,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 raw_input_message raw_msg;
     struct message *msg;
     unsigned char vkey = input->kbd.vkey;
     unsigned int message_code, time;
@@ -1781,23 +1823,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_raw_input_message, &raw_msg );
+        else
+            queue_raw_input_message( current->process, &raw_msg );
     }
 
     if (req_flags & SEND_HWMSG_ONLY_RAW)
-- 
2.23.0




More information about the wine-devel mailing list