[PATCH v2 6/6] server: Implement desktop broadcast in queue_rawinput_message.

Rémi Bernon rbernon at codeweavers.com
Fri Mar 5 04:49:25 CST 2021


HID rawinput messages are sent from winedevice.exe, which is not
attached to any desktop. We need to broadcast the messages to all
desktops in that case.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50506
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 server/queue.c | 45 +++++++++++++++++++++++++++++++--------------
 1 file changed, 31 insertions(+), 14 deletions(-)

diff --git a/server/queue.c b/server/queue.c
index 8b8bb41baf2..e8b6211ec1a 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -1675,8 +1675,8 @@ static int queue_rawinput_message( struct process* process, void *arg )
     const struct rawinput_message* raw_msg = arg;
     const struct rawinput_device_entry *entry;
     const struct rawinput_device *device = NULL;
-    struct desktop *target_desktop = NULL;
-    struct thread *target_thread = NULL;
+    struct desktop *target_desktop = NULL, *desktop = NULL;
+    struct thread *target_thread = NULL, *foreground = NULL;
     struct message *msg;
     struct hardware_msg_data *msg_data;
     int wparam = RIM_INPUT;
@@ -1689,12 +1689,18 @@ static int queue_rawinput_message( struct process* process, void *arg )
         device = &entry->device;
     if (!device) return 0;
 
-    if (process != raw_msg->foreground->process)
+    if (raw_msg->desktop) desktop = (struct desktop *)grab_object( raw_msg->desktop );
+    else if (!(desktop = get_desktop_obj( process, process->desktop, 0 ))) goto done;
+
+    if (raw_msg->foreground) foreground = (struct thread *)grab_object( raw_msg->foreground );
+    else if (!(foreground = get_foreground_thread( desktop, 0 ))) goto done;
+
+    if (process != foreground->process)
     {
         if (!(device->flags & RIDEV_INPUTSINK)) goto done;
         if (!(target_thread = get_window_thread( device->target ))) goto done;
         if (!(target_desktop = get_thread_desktop( target_thread, 0 ))) goto done;
-        if (target_desktop != raw_msg->desktop) goto done;
+        if (target_desktop != desktop) goto done;
         wparam = RIM_INPUTSINK;
     }
 
@@ -1711,11 +1717,13 @@ static int queue_rawinput_message( struct process* process, void *arg )
     if (raw_msg->extra_len && raw_msg->extra)
         memcpy( msg_data + 1, raw_msg->extra, raw_msg->extra_len );
 
-    queue_hardware_message( raw_msg->desktop, msg, 1 );
+    queue_hardware_message( desktop, msg, 1 );
 
 done:
     if (target_thread) release_object( target_thread );
     if (target_desktop) release_object( target_desktop );
+    if (foreground) release_object( foreground );
+    if (desktop) release_object( desktop );
     return 0;
 }
 
@@ -2498,15 +2506,14 @@ DECL_HANDLER(send_message)
 DECL_HANDLER(send_hardware_message)
 {
     struct thread *thread = NULL;
-    struct desktop *desktop;
+    struct desktop *desktop = get_thread_desktop( current, 0 );
     unsigned int origin = (req->flags & SEND_HWMSG_INJECTED ? IMO_INJECTED : IMO_HARDWARE);
     struct msg_queue *sender = get_current_queue();
     data_size_t size = min( 256, get_reply_max_size() );
 
-    if (!(desktop = get_thread_desktop( current, 0 ))) return;
-
     if (req->win)
     {
+        if (!desktop) return;
         if (!(thread = get_window_thread( req->win ))) return;
         if (desktop != thread->queue->input->desktop)
         {
@@ -2516,21 +2523,28 @@ DECL_HANDLER(send_hardware_message)
         }
     }
 
-    reply->prev_x = desktop->cursor.x;
-    reply->prev_y = desktop->cursor.y;
+    if (desktop)
+    {
+        reply->prev_x = desktop->cursor.x;
+        reply->prev_y = desktop->cursor.y;
+    }
 
     switch (req->input.type)
     {
     case HW_INPUT_MOUSE:
+        if (!desktop) return;
         reply->wait = queue_mouse_message( desktop, req->win, &req->input, origin, sender );
         break;
     case HW_INPUT_KEYBOARD:
+        if (!desktop) return;
         reply->wait = queue_keyboard_message( desktop, req->win, &req->input, origin, sender );
         break;
     case HW_INPUT_HARDWARE:
+        if (!desktop) return;
         queue_custom_hardware_message( desktop, req->win, origin, &req->input );
         break;
     case HW_INPUT_HID:
+        if (!desktop) set_error( STATUS_SUCCESS );
         queue_hid_message( req->win, &req->input, origin, sender, get_req_data(), get_req_data_size() );
         break;
     default:
@@ -2538,10 +2552,13 @@ DECL_HANDLER(send_hardware_message)
     }
     if (thread) release_object( thread );
 
-    reply->new_x = desktop->cursor.x;
-    reply->new_y = desktop->cursor.y;
-    set_reply_data( desktop->keystate, size );
-    release_object( desktop );
+    if (desktop)
+    {
+        reply->new_x = desktop->cursor.x;
+        reply->new_y = desktop->cursor.y;
+        set_reply_data( desktop->keystate, size );
+        release_object( desktop );
+    }
 }
 
 /* post a quit message to the current queue */
-- 
2.30.0




More information about the wine-devel mailing list