You've already forked wine-staging
mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2025-09-12 18:50:20 -07:00
Updated rawinput patchsets
This is a completely updated rawinput patchsets from Rémi Bernon, replacing the current user32-rawinput.
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
From 694ff514bfce59c2590668e3e812d501b713acdb Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Thu, 12 Sep 2019 14:14:08 +0200
|
||||
Subject: [PATCH 1/5] server: Add process argument to find_rawinput_device.
|
||||
|
||||
We need to be able to iterate all registered rawinput devices for
|
||||
foreign processes, not only the current one.
|
||||
---
|
||||
server/queue.c | 10 +++++-----
|
||||
1 file changed, 5 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/server/queue.c b/server/queue.c
|
||||
index f5dc06100d1..3ed7e82a906 100644
|
||||
--- a/server/queue.c
|
||||
+++ b/server/queue.c
|
||||
@@ -1576,11 +1576,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;
|
||||
@@ -1593,7 +1593,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 );
|
||||
@@ -3375,9 +3375,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;
|
||||
}
|
||||
|
||||
--
|
||||
2.24.1
|
||||
|
@@ -0,0 +1,150 @@
|
||||
From 56609fdaab139ec8718cf0c4963e6990c9b88003 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Thu, 19 Sep 2019 09:20:44 +0200
|
||||
Subject: [PATCH 2/5] server: Allow extra data for hardware_msg_data message.
|
||||
|
||||
The RIM_TYPEHID messages will have to carry the variable length HID
|
||||
report.
|
||||
---
|
||||
server/queue.c | 43 +++++++++++++++++++++++++++----------------
|
||||
1 file changed, 27 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/server/queue.c b/server/queue.c
|
||||
index 3ed7e82a906..feff00e2b9f 100644
|
||||
--- a/server/queue.c
|
||||
+++ b/server/queue.c
|
||||
@@ -398,13 +398,13 @@ static int assign_thread_input( struct thread *thread, struct thread_input *new_
|
||||
|
||||
/* allocate a hardware message and its data */
|
||||
static struct message *alloc_hardware_message( lparam_t info, struct hw_msg_source source,
|
||||
- unsigned int time )
|
||||
+ unsigned int time, data_size_t extra_len )
|
||||
{
|
||||
struct hardware_msg_data *msg_data;
|
||||
struct message *msg;
|
||||
|
||||
if (!(msg = mem_alloc( sizeof(*msg) ))) return NULL;
|
||||
- if (!(msg_data = mem_alloc( sizeof(*msg_data) )))
|
||||
+ if (!(msg_data = mem_alloc( sizeof(*msg_data) + extra_len )))
|
||||
{
|
||||
free( msg );
|
||||
return NULL;
|
||||
@@ -413,9 +413,9 @@ static struct message *alloc_hardware_message( lparam_t info, struct hw_msg_sour
|
||||
msg->type = MSG_HARDWARE;
|
||||
msg->time = time;
|
||||
msg->data = msg_data;
|
||||
- msg->data_size = sizeof(*msg_data);
|
||||
+ msg->data_size = sizeof(*msg_data) + extra_len;
|
||||
|
||||
- memset( msg_data, 0, sizeof(*msg_data) );
|
||||
+ memset( msg_data, 0, sizeof(*msg_data) + extra_len );
|
||||
msg_data->info = info;
|
||||
msg_data->source = source;
|
||||
return msg;
|
||||
@@ -430,7 +430,7 @@ static void set_cursor_pos( struct desktop *desktop, int x, int y )
|
||||
if (current->process->rawinput_mouse &&
|
||||
current->process->rawinput_mouse->flags & RIDEV_NOLEGACY) return;
|
||||
|
||||
- if (!(msg = alloc_hardware_message( 0, source, get_tick_count() ))) return;
|
||||
+ if (!(msg = alloc_hardware_message( 0, source, get_tick_count(), 0 ))) return;
|
||||
|
||||
msg->msg = WM_MOUSEMOVE;
|
||||
msg->x = x;
|
||||
@@ -1743,6 +1743,8 @@ struct rawinput_message
|
||||
struct hw_msg_source source;
|
||||
unsigned int time;
|
||||
struct hardware_msg_data data;
|
||||
+ const void *extra;
|
||||
+ data_size_t extra_len;
|
||||
};
|
||||
|
||||
static int queue_rawinput_message( struct process* process, void* user )
|
||||
@@ -1752,6 +1754,7 @@ static int queue_rawinput_message( struct process* process, void* user )
|
||||
struct desktop *desktop = NULL;
|
||||
struct thread *thread = NULL, *foreground = NULL;
|
||||
struct message *msg;
|
||||
+ struct hardware_msg_data *msg_data;
|
||||
|
||||
if (raw_msg->data.rawinput.type == RIM_TYPEMOUSE)
|
||||
device = process->rawinput_mouse;
|
||||
@@ -1774,14 +1777,18 @@ static int queue_rawinput_message( struct process* process, void* user )
|
||||
thread->process != foreground->process)
|
||||
goto done;
|
||||
|
||||
- if (!(msg = alloc_hardware_message( raw_msg->data.info, raw_msg->source, raw_msg->time )))
|
||||
+ if (!(msg = alloc_hardware_message( raw_msg->data.info, raw_msg->source, raw_msg->time, raw_msg->extra_len )))
|
||||
goto done;
|
||||
+ msg_data = msg->data;
|
||||
|
||||
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) );
|
||||
+
|
||||
+ memcpy( msg_data, &raw_msg->data, sizeof(*msg_data) );
|
||||
+ if (raw_msg->extra_len && raw_msg->extra)
|
||||
+ memcpy( msg_data + 1, raw_msg->extra, raw_msg->extra_len );
|
||||
|
||||
queue_hardware_message( desktop, msg, 0 );
|
||||
|
||||
@@ -1850,9 +1857,11 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons
|
||||
|
||||
if (req_flags & SEND_HWMSG_RAWINPUT)
|
||||
{
|
||||
- raw_msg.desktop = desktop;
|
||||
- raw_msg.source = source;
|
||||
- raw_msg.time = time;
|
||||
+ raw_msg.desktop = desktop;
|
||||
+ raw_msg.source = source;
|
||||
+ raw_msg.time = time;
|
||||
+ raw_msg.extra = NULL;
|
||||
+ raw_msg.extra_len = 0;
|
||||
|
||||
msg_data = &raw_msg.data;
|
||||
msg_data->info = input->mouse.info;
|
||||
@@ -1879,7 +1888,7 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons
|
||||
if (!(flags & (1 << i))) continue;
|
||||
flags &= ~(1 << i);
|
||||
|
||||
- if (!(msg = alloc_hardware_message( input->mouse.info, source, time ))) return 0;
|
||||
+ if (!(msg = alloc_hardware_message( input->mouse.info, source, time, 0 ))) return 0;
|
||||
msg_data = msg->data;
|
||||
|
||||
msg->win = get_user_full_handle( win );
|
||||
@@ -1983,9 +1992,11 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c
|
||||
|
||||
if (req_flags & SEND_HWMSG_RAWINPUT)
|
||||
{
|
||||
- raw_msg.desktop = desktop;
|
||||
- raw_msg.source = source;
|
||||
- raw_msg.time = time;
|
||||
+ raw_msg.desktop = desktop;
|
||||
+ raw_msg.source = source;
|
||||
+ raw_msg.time = time;
|
||||
+ raw_msg.extra = NULL;
|
||||
+ raw_msg.extra_len = 0;
|
||||
|
||||
msg_data = &raw_msg.data;
|
||||
msg_data->info = input->kbd.info;
|
||||
@@ -2006,7 +2017,7 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c
|
||||
if ((device = current->process->rawinput_kbd) && (device->flags & RIDEV_NOLEGACY))
|
||||
return 0;
|
||||
|
||||
- if (!(msg = alloc_hardware_message( input->kbd.info, source, time ))) return 0;
|
||||
+ if (!(msg = alloc_hardware_message( input->kbd.info, source, time, 0 ))) return 0;
|
||||
msg_data = msg->data;
|
||||
|
||||
msg->win = get_user_full_handle( win );
|
||||
@@ -2044,7 +2055,7 @@ static void queue_custom_hardware_message( struct desktop *desktop, user_handle_
|
||||
struct hw_msg_source source = { IMDT_UNAVAILABLE, origin };
|
||||
struct message *msg;
|
||||
|
||||
- if (!(msg = alloc_hardware_message( 0, source, get_tick_count() ))) return;
|
||||
+ if (!(msg = alloc_hardware_message( 0, source, get_tick_count(), 0 ))) return;
|
||||
|
||||
msg->win = get_user_full_handle( win );
|
||||
msg->msg = input->hw.msg;
|
||||
--
|
||||
2.24.1
|
||||
|
@@ -0,0 +1,262 @@
|
||||
From d0347613c7149144d4339109b641901537c4c326 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Mon, 11 Nov 2019 18:35:18 +0100
|
||||
Subject: [PATCH 3/5] server: Add HID input message type to
|
||||
send_hardware_message request.
|
||||
|
||||
---
|
||||
dlls/user32/message.c | 4 +++-
|
||||
server/protocol.def | 26 +++++++++++++++++++---
|
||||
server/queue.c | 50 ++++++++++++++++++++++++++++++++++++++-----
|
||||
server/trace.c | 10 ++++++---
|
||||
4 files changed, 78 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/dlls/user32/message.c b/dlls/user32/message.c
|
||||
index cc25d2f6c2f..55bbe409c9e 100644
|
||||
--- a/dlls/user32/message.c
|
||||
+++ b/dlls/user32/message.c
|
||||
@@ -3354,10 +3354,10 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, UINT flags )
|
||||
{
|
||||
req->win = wine_server_user_handle( hwnd );
|
||||
req->flags = flags;
|
||||
- req->input.type = input->type;
|
||||
switch (input->type)
|
||||
{
|
||||
case INPUT_MOUSE:
|
||||
+ req->input.type = HW_INPUT_MOUSE;
|
||||
req->input.mouse.x = input->u.mi.dx;
|
||||
req->input.mouse.y = input->u.mi.dy;
|
||||
req->input.mouse.data = input->u.mi.mouseData;
|
||||
@@ -3366,6 +3366,7 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, UINT flags )
|
||||
req->input.mouse.info = input->u.mi.dwExtraInfo;
|
||||
break;
|
||||
case INPUT_KEYBOARD:
|
||||
+ req->input.type = HW_INPUT_KEYBOARD;
|
||||
req->input.kbd.vkey = input->u.ki.wVk;
|
||||
req->input.kbd.scan = input->u.ki.wScan;
|
||||
req->input.kbd.flags = input->u.ki.dwFlags;
|
||||
@@ -3373,6 +3374,7 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, UINT flags )
|
||||
req->input.kbd.info = input->u.ki.dwExtraInfo;
|
||||
break;
|
||||
case INPUT_HARDWARE:
|
||||
+ req->input.type = HW_INPUT_HARDWARE;
|
||||
req->input.hw.msg = input->u.hi.uMsg;
|
||||
req->input.hw.lparam = MAKELONG( input->u.hi.wParamL, input->u.hi.wParamH );
|
||||
break;
|
||||
diff --git a/server/protocol.def b/server/protocol.def
|
||||
index d37dceba40c..85cc2ac6937 100644
|
||||
--- a/server/protocol.def
|
||||
+++ b/server/protocol.def
|
||||
@@ -321,6 +321,13 @@ struct hardware_msg_data
|
||||
int y; /* y coordinate */
|
||||
unsigned int data; /* mouse data */
|
||||
} mouse;
|
||||
+ struct
|
||||
+ {
|
||||
+ int type; /* RIM_TYPEHID */
|
||||
+ obj_handle_t device;
|
||||
+ unsigned int length; /* HID report length */
|
||||
+ /* followed by length bytes of HID report data */
|
||||
+ } hid;
|
||||
} rawinput;
|
||||
};
|
||||
|
||||
@@ -344,7 +351,7 @@ typedef union
|
||||
int type;
|
||||
struct
|
||||
{
|
||||
- int type; /* INPUT_KEYBOARD */
|
||||
+ int type; /* HW_INPUT_KEYBOARD */
|
||||
unsigned short vkey; /* virtual key code */
|
||||
unsigned short scan; /* scan code */
|
||||
unsigned int flags; /* event flags */
|
||||
@@ -353,7 +360,7 @@ typedef union
|
||||
} kbd;
|
||||
struct
|
||||
{
|
||||
- int type; /* INPUT_MOUSE */
|
||||
+ int type; /* HW_INPUT_MOUSE */
|
||||
int x; /* coordinates */
|
||||
int y;
|
||||
unsigned int data; /* mouse data */
|
||||
@@ -363,11 +370,23 @@ typedef union
|
||||
} mouse;
|
||||
struct
|
||||
{
|
||||
- int type; /* INPUT_HARDWARE */
|
||||
+ int type; /* HW_INPUT_HARDWARE */
|
||||
unsigned int msg; /* message code */
|
||||
lparam_t lparam; /* message param */
|
||||
} hw;
|
||||
+ struct
|
||||
+ {
|
||||
+ int type; /* HW_INPUT_HID */
|
||||
+ obj_handle_t device;
|
||||
+ unsigned char usage_page;
|
||||
+ unsigned char usage;
|
||||
+ unsigned int length;
|
||||
+ } hid;
|
||||
} hw_input_t;
|
||||
+#define HW_INPUT_MOUSE 0
|
||||
+#define HW_INPUT_KEYBOARD 1
|
||||
+#define HW_INPUT_HARDWARE 2
|
||||
+#define HW_INPUT_HID 3
|
||||
|
||||
typedef union
|
||||
{
|
||||
@@ -2361,6 +2380,7 @@ enum message_type
|
||||
user_handle_t win; /* window handle */
|
||||
hw_input_t input; /* input data */
|
||||
unsigned int flags; /* flags (see below) */
|
||||
+ VARARG(data,bytes); /* hid report data */
|
||||
@REPLY
|
||||
int wait; /* do we need to wait for a reply? */
|
||||
int prev_x; /* previous cursor position */
|
||||
diff --git a/server/queue.c b/server/queue.c
|
||||
index feff00e2b9f..85aa896c7bd 100644
|
||||
--- a/server/queue.c
|
||||
+++ b/server/queue.c
|
||||
@@ -1698,7 +1698,7 @@ static int send_hook_ll_message( struct desktop *desktop, struct message *hardwa
|
||||
struct msg_queue *queue;
|
||||
struct message *msg;
|
||||
timeout_t timeout = 2000 * -10000; /* FIXME: load from registry */
|
||||
- int id = (input->type == INPUT_MOUSE) ? WH_MOUSE_LL : WH_KEYBOARD_LL;
|
||||
+ int id = (input->type == HW_INPUT_MOUSE) ? WH_MOUSE_LL : WH_KEYBOARD_LL;
|
||||
|
||||
if (!(hook_thread = get_first_global_hook( id ))) return 0;
|
||||
if (!(queue = hook_thread->queue)) return 0;
|
||||
@@ -1716,7 +1716,7 @@ static int send_hook_ll_message( struct desktop *desktop, struct message *hardwa
|
||||
msg->data_size = hardware_msg->data_size;
|
||||
msg->result = NULL;
|
||||
|
||||
- if (input->type == INPUT_KEYBOARD)
|
||||
+ if (input->type == HW_INPUT_KEYBOARD)
|
||||
{
|
||||
unsigned short vkey = input->kbd.vkey;
|
||||
if (input->kbd.flags & KEYEVENTF_UNICODE) vkey = VK_PACKET;
|
||||
@@ -1742,6 +1742,8 @@ struct rawinput_message
|
||||
struct desktop *desktop;
|
||||
struct hw_msg_source source;
|
||||
unsigned int time;
|
||||
+ unsigned char usage_page;
|
||||
+ unsigned char usage;
|
||||
struct hardware_msg_data data;
|
||||
const void *extra;
|
||||
data_size_t extra_len;
|
||||
@@ -1750,6 +1752,7 @@ struct rawinput_message
|
||||
static int queue_rawinput_message( struct process* process, void* user )
|
||||
{
|
||||
const struct rawinput_message* raw_msg = user;
|
||||
+ const struct rawinput_device_entry *entry;
|
||||
const struct rawinput_device *device = NULL;
|
||||
struct desktop *desktop = NULL;
|
||||
struct thread *thread = NULL, *foreground = NULL;
|
||||
@@ -1760,6 +1763,8 @@ static int queue_rawinput_message( struct process* process, void* user )
|
||||
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->usage_page, raw_msg->usage )))
|
||||
+ device = &entry->device;
|
||||
|
||||
if (!device)
|
||||
goto done;
|
||||
@@ -2067,6 +2072,38 @@ static void queue_custom_hardware_message( struct desktop *desktop, user_handle_
|
||||
queue_hardware_message( desktop, msg, 1 );
|
||||
}
|
||||
|
||||
+/* queue a hardware message for an hid event */
|
||||
+static void queue_hid_message( struct desktop *desktop, user_handle_t win, const hw_input_t *input,
|
||||
+ unsigned int origin, struct msg_queue *sender, unsigned int req_flags,
|
||||
+ const void *report, data_size_t report_len )
|
||||
+{
|
||||
+ struct hw_msg_source source = { IMDT_UNAVAILABLE, origin };
|
||||
+ struct hardware_msg_data *msg_data;
|
||||
+ struct rawinput_message raw_msg;
|
||||
+
|
||||
+ if (!(req_flags & SEND_HWMSG_RAWINPUT))
|
||||
+ return;
|
||||
+
|
||||
+ raw_msg.desktop = NULL; /* send to all desktops */
|
||||
+ raw_msg.source = source;
|
||||
+ raw_msg.time = get_tick_count();
|
||||
+ raw_msg.usage_page = input->hid.usage_page;
|
||||
+ raw_msg.usage = input->hid.usage;
|
||||
+ raw_msg.extra = report;
|
||||
+ raw_msg.extra_len = report_len;
|
||||
+
|
||||
+ msg_data = &raw_msg.data;
|
||||
+ msg_data->flags = 0;
|
||||
+ msg_data->rawinput.type = RIM_TYPEHID;
|
||||
+ msg_data->rawinput.hid.device = input->hid.device;
|
||||
+ msg_data->rawinput.hid.length = report_len;
|
||||
+
|
||||
+ if (req_flags == SEND_HWMSG_RAWINPUT)
|
||||
+ enum_processes( queue_rawinput_message, &raw_msg );
|
||||
+ else
|
||||
+ queue_rawinput_message( current->process, &raw_msg );
|
||||
+}
|
||||
+
|
||||
/* check message filter for a hardware message */
|
||||
static int check_hw_message_filter( user_handle_t win, unsigned int msg_code,
|
||||
user_handle_t filter_win, unsigned int first, unsigned int last )
|
||||
@@ -2577,15 +2614,18 @@ DECL_HANDLER(send_hardware_message)
|
||||
|
||||
switch (req->input.type)
|
||||
{
|
||||
- case INPUT_MOUSE:
|
||||
+ case HW_INPUT_MOUSE:
|
||||
reply->wait = queue_mouse_message( desktop, req->win, &req->input, origin, sender, req->flags );
|
||||
break;
|
||||
- case INPUT_KEYBOARD:
|
||||
+ case HW_INPUT_KEYBOARD:
|
||||
reply->wait = queue_keyboard_message( desktop, req->win, &req->input, origin, sender, req->flags );
|
||||
break;
|
||||
- case INPUT_HARDWARE:
|
||||
+ case HW_INPUT_HARDWARE:
|
||||
queue_custom_hardware_message( desktop, req->win, origin, &req->input );
|
||||
break;
|
||||
+ case HW_INPUT_HID:
|
||||
+ queue_hid_message( desktop, req->win, &req->input, origin, sender, req->flags, get_req_data(), get_req_data_size() );
|
||||
+ break;
|
||||
default:
|
||||
set_error( STATUS_INVALID_PARAMETER );
|
||||
}
|
||||
diff --git a/server/trace.c b/server/trace.c
|
||||
index 18b56c729e4..c39c56087c1 100644
|
||||
--- a/server/trace.c
|
||||
+++ b/server/trace.c
|
||||
@@ -381,24 +381,28 @@ static void dump_hw_input( const char *prefix, const hw_input_t *input )
|
||||
{
|
||||
switch (input->type)
|
||||
{
|
||||
- case INPUT_MOUSE:
|
||||
+ case HW_INPUT_MOUSE:
|
||||
fprintf( stderr, "%s{type=MOUSE,x=%d,y=%d,data=%08x,flags=%08x,time=%u",
|
||||
prefix, input->mouse.x, input->mouse.y, input->mouse.data, input->mouse.flags,
|
||||
input->mouse.time );
|
||||
dump_uint64( ",info=", &input->mouse.info );
|
||||
fputc( '}', stderr );
|
||||
break;
|
||||
- case INPUT_KEYBOARD:
|
||||
+ case HW_INPUT_KEYBOARD:
|
||||
fprintf( stderr, "%s{type=KEYBOARD,vkey=%04hx,scan=%04hx,flags=%08x,time=%u",
|
||||
prefix, input->kbd.vkey, input->kbd.scan, input->kbd.flags, input->kbd.time );
|
||||
dump_uint64( ",info=", &input->kbd.info );
|
||||
fputc( '}', stderr );
|
||||
break;
|
||||
- case INPUT_HARDWARE:
|
||||
+ case HW_INPUT_HARDWARE:
|
||||
fprintf( stderr, "%s{type=HARDWARE,msg=%04x", prefix, input->hw.msg );
|
||||
dump_uint64( ",lparam=", &input->hw.lparam );
|
||||
fputc( '}', stderr );
|
||||
break;
|
||||
+ case HW_INPUT_HID:
|
||||
+ fprintf( stderr, "%s{type=HID,device=%04x,usage_page=%02x,usage=%02x,length=%04x}",
|
||||
+ prefix, input->hid.device, input->hid.usage_page, input->hid.usage, input->hid.length );
|
||||
+ break;
|
||||
default:
|
||||
fprintf( stderr, "%s{type=%04x}", prefix, input->type );
|
||||
break;
|
||||
--
|
||||
2.24.1
|
||||
|
@@ -0,0 +1,138 @@
|
||||
From bbb38b3c009d47aced1ba746549fdc51e34cbaf4 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Thu, 12 Sep 2019 14:48:23 +0200
|
||||
Subject: [PATCH 4/5] user32: Implement WM_INPUT/RIM_TYPEHID message handling.
|
||||
|
||||
---
|
||||
dlls/user32/message.c | 19 ++++++++++++++++++-
|
||||
dlls/user32/rawinput.c | 37 +++++++++++++++++++++++++++++++++++++
|
||||
dlls/user32/user_private.h | 2 ++
|
||||
3 files changed, 57 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/user32/message.c b/dlls/user32/message.c
|
||||
index 55bbe409c9e..ae081cd6eb1 100644
|
||||
--- a/dlls/user32/message.c
|
||||
+++ b/dlls/user32/message.c
|
||||
@@ -2285,10 +2285,17 @@ static BOOL process_rawinput_message( MSG *msg, const struct hardware_msg_data *
|
||||
{
|
||||
struct user_thread_info *thread_info = get_user_thread_info();
|
||||
RAWINPUT *rawinput = thread_info->rawinput;
|
||||
+ SIZE_T data_len = 0;
|
||||
+
|
||||
+ if (msg_data->rawinput.type == RIM_TYPEHID)
|
||||
+ {
|
||||
+ data_len = msg_data->rawinput.hid.length;
|
||||
+ rawinput = thread_info->rawinput = HeapReAlloc( GetProcessHeap(), 0, rawinput, sizeof(*rawinput) + data_len );
|
||||
+ }
|
||||
|
||||
if (!rawinput)
|
||||
{
|
||||
- thread_info->rawinput = HeapAlloc( GetProcessHeap(), 0, sizeof(*rawinput) );
|
||||
+ thread_info->rawinput = HeapAlloc( GetProcessHeap(), 0, sizeof(*rawinput) + data_len );
|
||||
if (!(rawinput = thread_info->rawinput)) return FALSE;
|
||||
}
|
||||
|
||||
@@ -2383,6 +2390,16 @@ static BOOL process_rawinput_message( MSG *msg, const struct hardware_msg_data *
|
||||
rawinput->data.keyboard.Message = msg_data->rawinput.kbd.message;
|
||||
rawinput->data.keyboard.ExtraInformation = msg_data->info;
|
||||
}
|
||||
+ else if (msg_data->rawinput.type == RIM_TYPEHID)
|
||||
+ {
|
||||
+ rawinput->header.dwSize = FIELD_OFFSET(RAWINPUT, data.hid.bRawData) + data_len;
|
||||
+ rawinput->header.hDevice = rawinput_handle_from_device_handle(wine_server_ptr_handle(msg_data->rawinput.hid.device));
|
||||
+ rawinput->header.wParam = 0;
|
||||
+
|
||||
+ rawinput->data.hid.dwSizeHid = data_len;
|
||||
+ rawinput->data.hid.dwCount = 1;
|
||||
+ memcpy(rawinput->data.hid.bRawData, msg_data + 1, data_len);
|
||||
+ }
|
||||
else
|
||||
{
|
||||
FIXME("Unhandled rawinput type %#x.\n", msg_data->rawinput.type);
|
||||
diff --git a/dlls/user32/rawinput.c b/dlls/user32/rawinput.c
|
||||
index 8cf9f8ebf62..72ae91cfcb5 100644
|
||||
--- a/dlls/user32/rawinput.c
|
||||
+++ b/dlls/user32/rawinput.c
|
||||
@@ -43,6 +43,7 @@ struct hid_device
|
||||
{
|
||||
WCHAR *path;
|
||||
HANDLE file;
|
||||
+ HANDLE handle;
|
||||
RID_DEVICE_INFO_HID info;
|
||||
PHIDP_PREPARSED_DATA data;
|
||||
};
|
||||
@@ -59,6 +60,8 @@ static CRITICAL_SECTION_DEBUG hid_devices_cs_debug =
|
||||
};
|
||||
static CRITICAL_SECTION hid_devices_cs = { &hid_devices_cs_debug, -1, 0, 0, 0, 0 };
|
||||
|
||||
+extern DWORD WINAPI GetFinalPathNameByHandleW(HANDLE file, LPWSTR path, DWORD charcount, DWORD flags);
|
||||
+
|
||||
static BOOL array_reserve(void **elements, unsigned int *capacity, unsigned int count, unsigned int size)
|
||||
{
|
||||
unsigned int new_capacity, max_capacity;
|
||||
@@ -138,10 +141,43 @@ static struct hid_device *add_device(HDEVINFO set, SP_DEVICE_INTERFACE_DATA *ifa
|
||||
device = &hid_devices[hid_devices_count++];
|
||||
device->path = path;
|
||||
device->file = file;
|
||||
+ device->handle = INVALID_HANDLE_VALUE;
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
+HANDLE rawinput_handle_from_device_handle(HANDLE device)
|
||||
+{
|
||||
+ WCHAR buffer[sizeof(OBJECT_NAME_INFORMATION) + MAX_PATH + 1];
|
||||
+ OBJECT_NAME_INFORMATION *info = (OBJECT_NAME_INFORMATION*)&buffer;
|
||||
+ ULONG dummy;
|
||||
+ unsigned int i;
|
||||
+
|
||||
+ for (i = 0; i < hid_devices_count; ++i)
|
||||
+ {
|
||||
+ if (hid_devices[i].handle == device)
|
||||
+ return &hid_devices[i];
|
||||
+ }
|
||||
+
|
||||
+ if (NtQueryObject( device, ObjectNameInformation, &buffer, sizeof(buffer) - sizeof(WCHAR), &dummy ) || !info->Name.Buffer)
|
||||
+ return NULL;
|
||||
+
|
||||
+ /* replace \??\ with \\?\ to match hid_devices paths */
|
||||
+ if (info->Name.Length > 1 && info->Name.Buffer[0] == '\\' && info->Name.Buffer[1] == '?')
|
||||
+ info->Name.Buffer[1] = '\\';
|
||||
+
|
||||
+ for (i = 0; i < hid_devices_count; ++i)
|
||||
+ {
|
||||
+ if (strcmpW(hid_devices[i].path, info->Name.Buffer) == 0)
|
||||
+ {
|
||||
+ hid_devices[i].handle = device;
|
||||
+ return &hid_devices[i];
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
static void find_hid_devices(void)
|
||||
{
|
||||
static ULONGLONG last_check;
|
||||
@@ -415,6 +451,7 @@ UINT WINAPI GetRawInputDeviceInfoW(HANDLE device, UINT command, void *data, UINT
|
||||
device, command, data, data_size);
|
||||
|
||||
if (!data_size) return ~0U;
|
||||
+ if (!device) return ~0U;
|
||||
|
||||
/* each case below must set:
|
||||
* *data_size: length (meaning defined by command) of data we want to copy
|
||||
diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h
|
||||
index e8f6abb6813..0c3d52fca5b 100644
|
||||
--- a/dlls/user32/user_private.h
|
||||
+++ b/dlls/user32/user_private.h
|
||||
@@ -378,4 +378,6 @@ static inline WCHAR *heap_strdupW(const WCHAR *src)
|
||||
return dst;
|
||||
}
|
||||
|
||||
+extern HANDLE rawinput_handle_from_device_handle(HANDLE device);
|
||||
+
|
||||
#endif /* __WINE_USER_PRIVATE_H */
|
||||
--
|
||||
2.24.1
|
||||
|
@@ -0,0 +1,139 @@
|
||||
From 249548cff4ae17da6731e28a5fafe277a7b3d6ea Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Wed, 18 Sep 2019 21:04:25 +0200
|
||||
Subject: [PATCH 5/5] hidclass.sys: Send input message to server when HID
|
||||
report is received.
|
||||
|
||||
---
|
||||
dlls/hidclass.sys/device.c | 30 ++++++++++++++++++++++++++++++
|
||||
dlls/hidclass.sys/hid.h | 1 +
|
||||
dlls/hidclass.sys/pnp.c | 16 ++++++++++++++++
|
||||
3 files changed, 47 insertions(+)
|
||||
|
||||
diff --git a/dlls/hidclass.sys/device.c b/dlls/hidclass.sys/device.c
|
||||
index 0e905c8322f..369d847e3c1 100644
|
||||
--- a/dlls/hidclass.sys/device.c
|
||||
+++ b/dlls/hidclass.sys/device.c
|
||||
@@ -26,9 +26,11 @@
|
||||
#include "winuser.h"
|
||||
#include "setupapi.h"
|
||||
|
||||
+#include "wine/server.h"
|
||||
#include "wine/debug.h"
|
||||
#include "ddk/hidsdi.h"
|
||||
#include "ddk/hidtypes.h"
|
||||
+#include "ddk/ntifs.h"
|
||||
#include "ddk/wdm.h"
|
||||
|
||||
#include "initguid.h"
|
||||
@@ -123,6 +125,8 @@ NTSTATUS HID_LinkDevice(DEVICE_OBJECT *device)
|
||||
return status;
|
||||
}
|
||||
|
||||
+ ext->link_handle = INVALID_HANDLE_VALUE;
|
||||
+
|
||||
/* FIXME: This should probably be done in mouhid.sys. */
|
||||
if (ext->preparseData->caps.UsagePage == HID_USAGE_PAGE_GENERIC
|
||||
&& ext->preparseData->caps.Usage == HID_USAGE_GENERIC_MOUSE)
|
||||
@@ -207,6 +211,8 @@ void HID_DeleteDevice(DEVICE_OBJECT *device)
|
||||
IoCompleteRequest(irp, IO_NO_INCREMENT);
|
||||
}
|
||||
|
||||
+ CloseHandle(ext->link_handle);
|
||||
+
|
||||
TRACE("Delete device(%p) %s\n", device, debugstr_w(ext->device_name));
|
||||
HeapFree(GetProcessHeap(), 0, ext->device_name);
|
||||
RtlFreeUnicodeString(&ext->link_name);
|
||||
@@ -241,6 +247,28 @@ static NTSTATUS copy_packet_into_buffer(HID_XFER_PACKET *packet, BYTE* buffer, U
|
||||
return STATUS_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
+static void HID_Device_sendRawInput(DEVICE_OBJECT *device, HID_XFER_PACKET *packet)
|
||||
+{
|
||||
+ BASE_DEVICE_EXTENSION *ext = device->DeviceExtension;
|
||||
+
|
||||
+ if (ext->link_handle == INVALID_HANDLE_VALUE)
|
||||
+ return;
|
||||
+
|
||||
+ SERVER_START_REQ(send_hardware_message)
|
||||
+ {
|
||||
+ req->win = 0;
|
||||
+ req->flags = SEND_HWMSG_RAWINPUT;
|
||||
+ req->input.type = HW_INPUT_HID;
|
||||
+ req->input.hid.device = wine_server_obj_handle(ext->link_handle);
|
||||
+ req->input.hid.usage_page = ext->preparseData->caps.UsagePage;
|
||||
+ req->input.hid.usage = ext->preparseData->caps.Usage;
|
||||
+ req->input.hid.length = packet->reportBufferLen;
|
||||
+ wine_server_add_data(req, packet->reportBuffer, packet->reportBufferLen);
|
||||
+ wine_server_call(req);
|
||||
+ }
|
||||
+ SERVER_END_REQ;
|
||||
+}
|
||||
+
|
||||
static void HID_Device_processQueue(DEVICE_OBJECT *device)
|
||||
{
|
||||
IRP *irp;
|
||||
@@ -324,6 +352,7 @@ static DWORD CALLBACK hid_device_thread(void *args)
|
||||
if (irp->IoStatus.u.Status == STATUS_SUCCESS)
|
||||
{
|
||||
RingBuffer_Write(ext->ring_buffer, packet);
|
||||
+ HID_Device_sendRawInput(device, packet);
|
||||
HID_Device_processQueue(device);
|
||||
}
|
||||
|
||||
@@ -370,6 +399,7 @@ static DWORD CALLBACK hid_device_thread(void *args)
|
||||
else
|
||||
packet->reportId = 0;
|
||||
RingBuffer_Write(ext->ring_buffer, packet);
|
||||
+ HID_Device_sendRawInput(device, packet);
|
||||
HID_Device_processQueue(device);
|
||||
}
|
||||
|
||||
diff --git a/dlls/hidclass.sys/hid.h b/dlls/hidclass.sys/hid.h
|
||||
index 36d13c009d7..f12e04d7898 100644
|
||||
--- a/dlls/hidclass.sys/hid.h
|
||||
+++ b/dlls/hidclass.sys/hid.h
|
||||
@@ -46,6 +46,7 @@ typedef struct _BASE_DEVICE_EXTENSION {
|
||||
ULONG poll_interval;
|
||||
WCHAR *device_name;
|
||||
UNICODE_STRING link_name;
|
||||
+ HANDLE link_handle;
|
||||
WCHAR device_id[MAX_DEVICE_ID_LEN];
|
||||
WCHAR instance_id[MAX_DEVICE_ID_LEN];
|
||||
struct ReportRingBuffer *ring_buffer;
|
||||
diff --git a/dlls/hidclass.sys/pnp.c b/dlls/hidclass.sys/pnp.c
|
||||
index 1c130e8dd80..b84a358dba4 100644
|
||||
--- a/dlls/hidclass.sys/pnp.c
|
||||
+++ b/dlls/hidclass.sys/pnp.c
|
||||
@@ -299,12 +299,28 @@ NTSTATUS WINAPI HID_PNP_Dispatch(DEVICE_OBJECT *device, IRP *irp)
|
||||
case IRP_MN_START_DEVICE:
|
||||
{
|
||||
BASE_DEVICE_EXTENSION *ext = device->DeviceExtension;
|
||||
+ OBJECT_ATTRIBUTES attr;
|
||||
|
||||
rc = minidriver->PNPDispatch(device, irp);
|
||||
|
||||
IoSetDeviceInterfaceState(&ext->link_name, TRUE);
|
||||
if (ext->is_mouse)
|
||||
IoSetDeviceInterfaceState(&ext->mouse_link_name, TRUE);
|
||||
+
|
||||
+ attr.Length = sizeof(attr);
|
||||
+ attr.RootDirectory = 0;
|
||||
+ attr.Attributes = OBJ_CASE_INSENSITIVE;
|
||||
+ attr.ObjectName = &ext->link_name;
|
||||
+ attr.SecurityDescriptor = NULL;
|
||||
+ attr.SecurityQualityOfService = NULL;
|
||||
+ NtOpenSymbolicLinkObject(&ext->link_handle, SYMBOLIC_LINK_QUERY, &attr);
|
||||
+ ext->link_handle = ConvertToGlobalHandle(ext->link_handle);
|
||||
+
|
||||
+ if (ext->link_handle == INVALID_HANDLE_VALUE)
|
||||
+ ERR("Failed to open link %s, error %u.\n", debugstr_w(ext->link_name.Buffer), GetLastError());
|
||||
+ else
|
||||
+ TRACE("Opened link handle: %p for %s\n", ext->link_handle, debugstr_w(ext->link_name.Buffer));
|
||||
+
|
||||
return rc;
|
||||
}
|
||||
case IRP_MN_REMOVE_DEVICE:
|
||||
--
|
||||
2.24.1
|
||||
|
1
patches/user32-rawinput-hid/definition
Normal file
1
patches/user32-rawinput-hid/definition
Normal file
@@ -0,0 +1 @@
|
||||
Depends: user32-rawinput-nolegacy
|
Reference in New Issue
Block a user