server: Implement RegisterRawInputDevices RIDEV_INPUTSINK flag.
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> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
8cf7fe3b7c
commit
27a52d0414
|
@ -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;
|
||||
|
|
|
@ -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 },
|
||||
|
|
|
@ -1656,7 +1656,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 thread *target_thread = NULL;
|
||||
struct message *msg;
|
||||
int wparam = RIM_INPUT;
|
||||
|
||||
if (raw_msg->data.rawinput.type == RIM_TYPEMOUSE)
|
||||
device = process->rawinput_mouse;
|
||||
|
@ -1664,16 +1667,29 @@ static int queue_rawinput_message( struct process* process, void *arg )
|
|||
device = process->rawinput_kbd;
|
||||
if (!device) return 0;
|
||||
|
||||
if (process != raw_msg->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;
|
||||
wparam = RIM_INPUTSINK;
|
||||
}
|
||||
|
||||
if (!(msg = alloc_hardware_message( raw_msg->data.info, raw_msg->source, raw_msg->time )))
|
||||
return 0;
|
||||
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) );
|
||||
|
||||
queue_hardware_message( raw_msg->desktop, msg, 1 );
|
||||
|
||||
done:
|
||||
if (target_thread) release_object( target_thread );
|
||||
if (target_desktop) release_object( target_desktop );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1749,7 +1765,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 );
|
||||
}
|
||||
|
||||
|
@ -1883,7 +1899,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 );
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue