[PATCH v2 5/9] server: Implement rawinput cross-process message dispatch.
Rémi Bernon
rbernon at codeweavers.com
Mon Jun 15 05:05:44 CDT 2020
This delivers the rawinput messages to the correct process, regardless
of where the input was received.
For now the RIDEV_INPUTSINK flag is not implemented, so the listening
process has to be the foreground process, but iterating the process list
will make it easier to implement later.
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
dlls/user32/tests/input.c | 2 +-
server/queue.c | 118 +++++++++++++++++++++++++++-----------
2 files changed, 86 insertions(+), 34 deletions(-)
diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c
index 9ec829860af..eb5fcf7c812 100644
--- a/dlls/user32/tests/input.c
+++ b/dlls/user32/tests/input.c
@@ -1882,7 +1882,7 @@ struct rawinput_test rawinput_tests[] =
/* cross-process foreground tests */
{ TRUE, TRUE, 0, FALSE, FALSE, FALSE, /* todos: */ FALSE, FALSE, FALSE },
{ TRUE, TRUE, RIDEV_INPUTSINK, FALSE, TRUE, FALSE, /* todos: */ FALSE, TRUE, FALSE },
- { TRUE, TRUE, 0, FALSE, FALSE, FALSE, /* todos: */ FALSE, TRUE, TRUE },
+ { TRUE, TRUE, 0, FALSE, FALSE, FALSE, /* todos: */ FALSE, FALSE, FALSE },
/* multi-process rawinput tests */
{ TRUE, TRUE, 0, FALSE, FALSE, FALSE, /* todos: */ FALSE, FALSE, FALSE },
diff --git a/server/queue.c b/server/queue.c
index 84ee0f9a4ea..94b9d555183 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -1596,12 +1596,73 @@ 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, *foreground = 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;
+
+ /* skip if no device registered in process */
+ if (!device) goto done;
+
+ /* skip if event is from another desktop */
+ if (!(desktop = get_desktop_obj( process, process->desktop, 0 )) ||
+ (raw_msg->desktop && desktop != raw_msg->desktop))
+ goto done;
+
+ /* skip if there is no target window */
+ if (!device->target && !desktop->foreground_input)
+ goto done;
+
+ /* skip if target window is from a thread in another process */
+ if (!(thread = get_window_thread( device->target ? device->target : desktop->foreground_input->active )) ||
+ process != thread->process)
+ goto done;
+
+ /* FIXME: Implement RIDEV_INPUTSINK */
+ if (!desktop->foreground_input || !(foreground = get_window_thread( desktop->foreground_input->active )) ||
+ thread->process != foreground->process)
+ 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 (foreground) release_object( foreground );
+ 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 )
{
- 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 +1712,19 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons
y = desktop->cursor.y;
}
- if ((device = current->process->rawinput_mouse))
- {
- 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->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;
+ 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 );
- }
+ enum_processes( queue_rawinput_message, &raw_msg );
for (i = 0; i < ARRAY_SIZE( messages ); i++)
{
@@ -1704,8 +1760,8 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c
unsigned int origin, struct msg_queue *sender )
{
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;
@@ -1777,23 +1833,19 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c
break;
}
- if ((device = current->process->rawinput_kbd))
- {
- 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->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;
+ 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 );
- }
+ enum_processes( queue_rawinput_message, &raw_msg );
if (!(msg = alloc_hardware_message( input->kbd.info, source, time ))) return 0;
msg_data = msg->data;
--
2.27.0
More information about the wine-devel
mailing list