This flag allows applications to receive rawinput messages while in background. They have to specify a target hwnd, which will receive them, and the messages will carry a RIM_INPUTSINK wparam if the process wasn't foreground.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/user32/rawinput.c | 9 ++++++++- dlls/user32/tests/input.c | 8 +++----- server/queue.c | 18 ++++++++++++++---- 3 files changed, 25 insertions(+), 10 deletions(-)
diff --git a/dlls/user32/rawinput.c b/dlls/user32/rawinput.c index 7a9eb6ced17..103835e0e33 100644 --- a/dlls/user32/rawinput.c +++ b/dlls/user32/rawinput.c @@ -291,6 +291,13 @@ BOOL WINAPI DECLSPEC_HOTPATCH RegisterRawInputDevices(RAWINPUTDEVICE *devices, U
for (i = 0; i < device_count; ++i) { + if ((devices[i].dwFlags & RIDEV_INPUTSINK) && + (devices[i].hwndTarget == NULL)) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + if ((devices[i].dwFlags & RIDEV_REMOVE) && (devices[i].hwndTarget != NULL)) { @@ -306,7 +313,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH RegisterRawInputDevices(RAWINPUTDEVICE *devices, U TRACE("device %u: page %#x, usage %#x, flags %#x, target %p.\n", i, devices[i].usUsagePage, devices[i].usUsage, devices[i].dwFlags, devices[i].hwndTarget); - if (devices[i].dwFlags & ~(RIDEV_REMOVE|RIDEV_NOLEGACY)) + if (devices[i].dwFlags & ~(RIDEV_REMOVE|RIDEV_NOLEGACY|RIDEV_INPUTSINK)) FIXME("Unhandled flags %#x for device %u.\n", devices[i].dwFlags, i);
d[i].usage_page = devices[i].usUsagePage; diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c index 8ae44e4ab92..51b18242444 100644 --- a/dlls/user32/tests/input.c +++ b/dlls/user32/tests/input.c @@ -1807,9 +1807,7 @@ static void test_RegisterRawInputDevices(void)
SetLastError(0xdeadbeef); res = RegisterRawInputDevices(raw_devices, ARRAY_SIZE(raw_devices), sizeof(RAWINPUTDEVICE)); - todo_wine ok(res == FALSE, "RegisterRawInputDevices failed\n"); - todo_wine ok(GetLastError() == ERROR_INVALID_PARAMETER, "RegisterRawInputDevices returned %08x\n", GetLastError());
raw_devices[0].hwndTarget = hwnd; @@ -1884,13 +1882,13 @@ 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, RIDEV_INPUTSINK, FALSE, TRUE, FALSE, /* todos: */ FALSE, FALSE, FALSE }, { TRUE, TRUE, 0, FALSE, FALSE, FALSE, /* todos: */ FALSE, FALSE, FALSE },
/* multi-process rawinput tests */ { TRUE, TRUE, 0, FALSE, FALSE, FALSE, /* todos: */ FALSE, FALSE, FALSE }, - { TRUE, TRUE, RIDEV_INPUTSINK, FALSE, TRUE, FALSE, /* todos: */ FALSE, TRUE, FALSE }, - { TRUE, TRUE, RIDEV_INPUTSINK, FALSE, TRUE, FALSE, /* todos: */ FALSE, TRUE, FALSE }, + { TRUE, TRUE, RIDEV_INPUTSINK, FALSE, TRUE, FALSE, /* todos: */ FALSE, FALSE, FALSE }, + { TRUE, TRUE, RIDEV_INPUTSINK, FALSE, TRUE, FALSE, /* todos: */ FALSE, FALSE, FALSE },
{ TRUE, TRUE, RIDEV_EXINPUTSINK, FALSE, FALSE, FALSE, /* todos: */ FALSE, FALSE, FALSE }, { TRUE, TRUE, RIDEV_EXINPUTSINK, FALSE, TRUE, FALSE, /* todos: */ FALSE, TRUE, FALSE }, diff --git a/server/queue.c b/server/queue.c index 8d8eea21120..5114b9cd242 100644 --- a/server/queue.c +++ b/server/queue.c @@ -1654,9 +1654,10 @@ static int queue_rawinput_message( struct process* process, void *arg ) { const struct rawinput_message* raw_msg = arg; const struct rawinput_device *device = NULL; - struct desktop *target_desktop = NULL; + struct desktop *target_desktop = NULL, *input_desktop = NULL; struct thread *target_thread = NULL; struct message *msg; + int wparam = RIM_INPUT;
if (raw_msg->data.rawinput.type == RIM_TYPEMOUSE) device = process->rawinput_mouse; @@ -1670,12 +1671,20 @@ static int queue_rawinput_message( struct process* process, void *arg ) if (!target_thread || target_thread->process != process) goto done; if (!(target_desktop = get_thread_desktop( target_thread, 0 ))) goto done;
+ if (process != raw_msg->foreground->process) + { + if (!(device->flags & RIDEV_INPUTSINK)) goto done; + if (!(input_desktop = get_thread_desktop( raw_msg->foreground, 0 ))) goto done; + if (target_desktop != input_desktop) goto done; + wparam = RIM_INPUTSINK; + } + 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->wparam = wparam; msg->lparam = 0; memcpy( msg->data, &raw_msg->data, sizeof(raw_msg->data) );
@@ -1684,6 +1693,7 @@ static int queue_rawinput_message( struct process* process, void *arg ) done: if (target_thread) release_object( target_thread ); if (target_desktop) release_object( target_desktop ); + if (input_desktop) release_object( input_desktop ); return 0; }
@@ -1758,7 +1768,7 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons msg_data->rawinput.mouse.y = y - desktop->cursor.y; msg_data->rawinput.mouse.data = input->mouse.data;
- queue_rawinput_message( foreground->process, &raw_msg ); + enum_processes( queue_rawinput_message, &raw_msg ); release_object( foreground ); }
@@ -1891,7 +1901,7 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c msg_data->rawinput.kbd.vkey = vkey; msg_data->rawinput.kbd.scan = input->kbd.scan;
- queue_rawinput_message( foreground->process, &raw_msg ); + enum_processes( queue_rawinput_message, &raw_msg ); release_object( foreground ); }