And use it to find registered HID rawinput devices.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50506 Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- server/queue.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/server/queue.c b/server/queue.c index b026c03e13d..3a37dd96385 100644 --- a/server/queue.c +++ b/server/queue.c @@ -1489,11 +1489,11 @@ static user_handle_t find_hardware_message_window( struct desktop *desktop, stru return win; }
-static struct rawinput_device_entry *find_rawinput_device( unsigned short usage_page, unsigned short usage ) +static struct rawinput_device_entry *find_rawinput_device( struct process *process, unsigned short usage_page, unsigned short usage ) { struct rawinput_device_entry *e;
- LIST_FOR_EACH_ENTRY( e, ¤t->process->rawinput_devices, struct rawinput_device_entry, entry ) + LIST_FOR_EACH_ENTRY( e, &process->rawinput_devices, struct rawinput_device_entry, entry ) { if (e->device.usage_page != usage_page || e->device.usage != usage) continue; return e; @@ -1506,7 +1506,7 @@ static void update_rawinput_device(const struct rawinput_device *device) { struct rawinput_device_entry *e;
- if (!(e = find_rawinput_device( device->usage_page, device->usage ))) + if (!(e = find_rawinput_device( current->process, device->usage_page, device->usage ))) { if (!(e = mem_alloc( sizeof(*e) ))) return; list_add_tail( ¤t->process->rawinput_devices, &e->entry ); @@ -1669,6 +1669,7 @@ struct rawinput_message 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; @@ -1679,6 +1680,8 @@ static int queue_rawinput_message( struct process* process, void *arg ) device = process->rawinput_mouse; else if (raw_msg->data.rawinput.type == RIM_TYPEKEYBOARD) device = process->rawinput_kbd; + else if ((entry = find_rawinput_device( process, raw_msg->data.rawinput.hid.usage_page, raw_msg->data.rawinput.hid.usage ))) + device = &entry->device; if (!device) return 0;
if (process != raw_msg->foreground->process) @@ -3296,9 +3299,9 @@ DECL_HANDLER(update_rawinput_devices) update_rawinput_device(&devices[i]); }
- e = find_rawinput_device( 1, 2 ); + e = find_rawinput_device( current->process, 1, 2 ); current->process->rawinput_mouse = e ? &e->device : NULL; - e = find_rawinput_device( 1, 6 ); + e = find_rawinput_device( current->process, 1, 6 ); current->process->rawinput_kbd = e ? &e->device : NULL; }
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50506 Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- server/queue.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/server/queue.c b/server/queue.c index 3a37dd96385..a0d46d75cf5 100644 --- a/server/queue.c +++ b/server/queue.c @@ -1662,6 +1662,7 @@ struct rawinput_message struct desktop *desktop; struct hw_msg_source source; unsigned int time; + unsigned int message; struct hardware_msg_data data; };
@@ -1697,7 +1698,7 @@ static int queue_rawinput_message( struct process* process, void *arg ) goto done;
msg->win = device->target; - msg->msg = WM_INPUT; + msg->msg = raw_msg->message; msg->wparam = wparam; msg->lparam = 0; memcpy( msg->data, &raw_msg->data, sizeof(raw_msg->data) ); @@ -1773,6 +1774,7 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons raw_msg.desktop = desktop; raw_msg.source = source; raw_msg.time = time; + raw_msg.message = WM_INPUT;
msg_data = &raw_msg.data; msg_data->info = input->mouse.info; @@ -1907,6 +1909,7 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c raw_msg.desktop = desktop; raw_msg.source = source; raw_msg.time = time; + raw_msg.message = WM_INPUT;
msg_data = &raw_msg.data; msg_data->info = input->kbd.info;
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50506 Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/user32/rawinput.c | 2 +- server/queue.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/dlls/user32/rawinput.c b/dlls/user32/rawinput.c index f2d64ccc23b..d95d29d7656 100644 --- a/dlls/user32/rawinput.c +++ b/dlls/user32/rawinput.c @@ -468,7 +468,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|RIDEV_INPUTSINK)) + if (devices[i].dwFlags & ~(RIDEV_REMOVE|RIDEV_NOLEGACY|RIDEV_INPUTSINK|RIDEV_DEVNOTIFY)) FIXME("Unhandled flags %#x for device %u.\n", devices[i].dwFlags, i);
d[i].usage_page = devices[i].usUsagePage; diff --git a/server/queue.c b/server/queue.c index a0d46d75cf5..ef5aa02bdb3 100644 --- a/server/queue.c +++ b/server/queue.c @@ -1685,6 +1685,8 @@ static int queue_rawinput_message( struct process* process, void *arg ) device = &entry->device; if (!device) return 0;
+ if (raw_msg->message == WM_INPUT_DEVICE_CHANGE && !(device->flags & RIDEV_DEVNOTIFY)) return 0; + if (process != raw_msg->foreground->process) { if (!(device->flags & RIDEV_INPUTSINK)) goto done;
HID rawinput hardware messages are sent from winedevice.exe, which is attached to the services desktop. We need to broadcast its messages to all (interactive) desktops instead.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50506 Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- server/queue.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/server/queue.c b/server/queue.c index ef5aa02bdb3..73828fafbe6 100644 --- a/server/queue.c +++ b/server/queue.c @@ -1672,8 +1672,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; int wparam = RIM_INPUT;
@@ -1687,12 +1687,18 @@ static int queue_rawinput_message( struct process* process, void *arg )
if (raw_msg->message == WM_INPUT_DEVICE_CHANGE && !(device->flags & RIDEV_DEVNOTIFY)) 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; }
@@ -1705,11 +1711,13 @@ static int queue_rawinput_message( struct process* process, void *arg ) msg->lparam = 0; memcpy( msg->data, &raw_msg->data, sizeof(raw_msg->data) );
- 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; }
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50506 Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/user32/message.c | 13 ++++++++----- server/queue.c | 36 ++++++++++++++++++++++++++++++++---- 2 files changed, 40 insertions(+), 9 deletions(-)
diff --git a/dlls/user32/message.c b/dlls/user32/message.c index 148b35f8caf..9af33c3291e 100644 --- a/dlls/user32/message.c +++ b/dlls/user32/message.c @@ -2289,11 +2289,14 @@ static void accept_hardware_message( UINT hw_id ) static BOOL process_rawinput_message( MSG *msg, UINT hw_id, const struct hardware_msg_data *msg_data ) { struct rawinput_thread_data *thread_data = rawinput_thread_data(); - if (!rawinput_from_hardware_message( thread_data->buffer, msg_data )) - return FALSE;
- thread_data->hw_id = hw_id; - msg->lParam = (LPARAM)hw_id; + if (msg->message == WM_INPUT) + { + if (!rawinput_from_hardware_message( thread_data->buffer, msg_data )) return FALSE; + thread_data->hw_id = hw_id; + msg->lParam = (LPARAM)hw_id; + } + msg->pt = point_phys_to_win_dpi( msg->hwnd, msg->pt ); return TRUE; } @@ -2613,7 +2616,7 @@ static BOOL process_hardware_message( MSG *msg, UINT hw_id, const struct hardwar /* hardware messages are always in physical coords */ context = SetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE );
- if (msg->message == WM_INPUT) + if (msg->message == WM_INPUT || msg->message == WM_INPUT_DEVICE_CHANGE) ret = process_rawinput_message( msg, hw_id, msg_data ); else if (is_keyboard_message( msg->message )) ret = process_keyboard_message( msg, hw_id, hwnd_filter, first, last, remove ); diff --git a/server/queue.c b/server/queue.c index 73828fafbe6..5d65e030112 100644 --- a/server/queue.c +++ b/server/queue.c @@ -1464,7 +1464,7 @@ static user_handle_t find_hardware_message_window( struct desktop *desktop, stru
*thread = NULL; *msg_code = msg->msg; - if (msg->msg == WM_INPUT) + if (msg->msg == WM_INPUT || msg->msg == WM_INPUT_DEVICE_CHANGE) { if (!(win = msg->win) && input) win = input->focus; } @@ -1553,7 +1553,7 @@ static void queue_hardware_message( struct desktop *desktop, struct message *msg if (msg->wparam == VK_SHIFT || msg->wparam == VK_LSHIFT || msg->wparam == VK_RSHIFT) msg->lparam &= ~(KF_EXTENDED << 16); } - else if (msg->msg != WM_INPUT) + else if (msg->msg != WM_INPUT && msg->msg != WM_INPUT_DEVICE_CHANGE) { if (msg->msg == WM_MOUSEMOVE) { @@ -1695,7 +1695,7 @@ static int queue_rawinput_message( struct process* process, void *arg )
if (process != foreground->process) { - if (!(device->flags & RIDEV_INPUTSINK)) goto done; + if (raw_msg->message == WM_INPUT && !(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 != desktop) goto done; @@ -1711,6 +1711,12 @@ static int queue_rawinput_message( struct process* process, void *arg ) msg->lparam = 0; memcpy( msg->data, &raw_msg->data, sizeof(raw_msg->data) );
+ if (raw_msg->message == WM_INPUT_DEVICE_CHANGE && raw_msg->data.rawinput.type == RIM_TYPEHID) + { + msg->wparam = raw_msg->data.rawinput.hid.param; + msg->lparam = raw_msg->data.rawinput.hid.device; + } + queue_hardware_message( desktop, msg, 1 );
done: @@ -1975,8 +1981,30 @@ static void queue_custom_hardware_message( struct desktop *desktop, user_handle_ unsigned int origin, const hw_input_t *input ) { struct hw_msg_source source = { IMDT_UNAVAILABLE, origin }; + struct hardware_msg_data *msg_data; + struct rawinput_message raw_msg; struct message *msg;
+ switch (input->hw.msg) + { + case WM_INPUT_DEVICE_CHANGE: + raw_msg.foreground = NULL; + raw_msg.desktop = NULL; + raw_msg.source = source; + raw_msg.time = get_tick_count(); + raw_msg.message = input->hw.msg; + + msg_data = &raw_msg.data; + msg_data->info = 0; + msg_data->flags = 0; + msg_data->rawinput = input->hw.rawinput; + + enum_processes( queue_rawinput_message, &raw_msg ); + + if (raw_msg.foreground) release_object( raw_msg.foreground ); + return; + } + if (!(msg = alloc_hardware_message( 0, source, get_tick_count() ))) return;
msg->win = get_user_full_handle( win ); @@ -2109,7 +2137,7 @@ static int get_hardware_message( struct thread *thread, unsigned int hw_id, user
data->hw_id = msg->unique_id; set_reply_data( msg->data, msg->data_size ); - if (msg->msg == WM_INPUT && (flags & PM_REMOVE)) + if ((msg->msg == WM_INPUT || msg->msg == WM_INPUT_DEVICE_CHANGE) && (flags & PM_REMOVE)) release_hardware_message( current->queue, data->hw_id ); return 1; }