diff --git a/dlls/user32/message.c b/dlls/user32/message.c index be178072e6f..886c10e36bd 100644 --- a/dlls/user32/message.c +++ b/dlls/user32/message.c @@ -3255,6 +3255,14 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, const RAWINPUT *r hid_usage_page = ((USAGE *)rawinput->data.hid.bRawData)[0]; hid_usage = ((USAGE *)rawinput->data.hid.bRawData)[1]; } + if (input->u.hi.uMsg == WM_INPUT) + { + if (!rawinput_device_get_usages( rawinput->header.hDevice, &hid_usage_page, &hid_usage )) + { + WARN( "unable to get HID usages for device %p\n", rawinput->header.hDevice ); + return STATUS_INVALID_HANDLE; + } + } } SERVER_START_REQ( send_hardware_message ) @@ -3284,6 +3292,7 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, const RAWINPUT *r req->input.hw.lparam = MAKELONG( input->u.hi.wParamL, input->u.hi.wParamH ); switch (input->u.hi.uMsg) { + case WM_INPUT: case WM_INPUT_DEVICE_CHANGE: req->input.hw.rawinput.type = rawinput->header.dwType; switch (rawinput->header.dwType) diff --git a/dlls/user32/rawinput.c b/dlls/user32/rawinput.c index efc736625d5..87f7175a6c1 100644 --- a/dlls/user32/rawinput.c +++ b/dlls/user32/rawinput.c @@ -267,6 +267,21 @@ static struct device *find_device_from_handle(HANDLE handle) } +BOOL rawinput_device_get_usages(HANDLE handle, USAGE *usage_page, USAGE *usage) +{ + struct device *device; + + *usage_page = *usage = 0; + + if (!(device = find_device_from_handle(handle))) return FALSE; + if (device->info.dwType != RIM_TYPEHID) return FALSE; + + *usage_page = device->info.u.hid.usUsagePage; + *usage = device->info.u.hid.usUsage; + return TRUE; +} + + struct rawinput_thread_data *rawinput_thread_data(void) { struct user_thread_info *thread_info = get_user_thread_info(); @@ -280,6 +295,8 @@ struct rawinput_thread_data *rawinput_thread_data(void) BOOL rawinput_from_hardware_message(RAWINPUT *rawinput, const struct hardware_msg_data *msg_data) { + SIZE_T size; + rawinput->header.dwType = msg_data->rawinput.type; if (msg_data->rawinput.type == RIM_TYPEMOUSE) { @@ -371,6 +388,19 @@ BOOL rawinput_from_hardware_message(RAWINPUT *rawinput, const struct hardware_ms rawinput->data.keyboard.Message = msg_data->rawinput.kbd.message; rawinput->data.keyboard.ExtraInformation = msg_data->info; } + else if (msg_data->rawinput.type == RIM_TYPEHID) + { + size = msg_data->size - sizeof(*msg_data); + if (size > rawinput->header.dwSize - sizeof(*rawinput)) return FALSE; + + rawinput->header.dwSize = FIELD_OFFSET( RAWINPUT, data.hid.bRawData ) + size; + rawinput->header.hDevice = ULongToHandle( msg_data->rawinput.hid.device ); + rawinput->header.wParam = 0; + + rawinput->data.hid.dwCount = 0; + rawinput->data.hid.dwSizeHid = 0; + memcpy( rawinput->data.hid.bRawData, msg_data + 1, size ); + } else { FIXME("Unhandled rawinput type %#x.\n", msg_data->rawinput.type); diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h index cb780f0c963..0838ba28b32 100644 --- a/dlls/user32/user_private.h +++ b/dlls/user32/user_private.h @@ -28,6 +28,7 @@ #include "winuser.h" #include "winreg.h" #include "winternl.h" +#include "hidusage.h" #include "wine/heap.h" #define GET_WORD(ptr) (*(const WORD *)(ptr)) @@ -239,6 +240,7 @@ struct tagWND; struct hardware_msg_data; extern BOOL rawinput_from_hardware_message(RAWINPUT *rawinput, const struct hardware_msg_data *msg_data); +extern BOOL rawinput_device_get_usages(HANDLE handle, USAGE *usage_page, USAGE *usage); extern struct rawinput_thread_data *rawinput_thread_data(void); extern void keyboard_init(void) DECLSPEC_HIDDEN; diff --git a/server/queue.c b/server/queue.c index 07d4c7e0885..6c59b02a9b6 100644 --- a/server/queue.c +++ b/server/queue.c @@ -1990,6 +1990,7 @@ static void queue_custom_hardware_message( struct desktop *desktop, user_handle_ switch (input->hw.msg) { + case WM_INPUT: case WM_INPUT_DEVICE_CHANGE: raw_msg.foreground = NULL; raw_msg.desktop = NULL; diff --git a/server/trace.c b/server/trace.c index 7125c6f4370..cebcc217e3a 100644 --- a/server/trace.c +++ b/server/trace.c @@ -436,6 +436,7 @@ static void dump_hw_input( const char *prefix, const hw_input_t *input ) dump_uint64( ",lparam=", &input->hw.lparam ); switch (input->hw.msg) { + case WM_INPUT: case WM_INPUT_DEVICE_CHANGE: dump_rawinput( ",rawinput=", &input->hw.rawinput ); }