[PATCH 2/9] server: Implement rawinput hardware message broadcast.

Rémi Bernon rbernon at codeweavers.com
Wed Sep 25 04:35:38 CDT 2019


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 <rbernon at codeweavers.com>
---
 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




More information about the wine-devel mailing list