[PATCH 4/4] user32: Implement RegisterRawInputDevices().
Henri Verbeet
hverbeet at codeweavers.com
Sat Sep 8 04:26:26 CDT 2012
---
dlls/user32/input.c | 41 ++++++++++++++++++++++++++++++++++++++---
server/process.c | 7 +++++++
server/process.h | 7 +++++++
server/protocol.def | 14 ++++++++++++++
server/queue.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
server/trace.c | 17 +++++++++++++++++
6 files changed, 129 insertions(+), 3 deletions(-)
diff --git a/dlls/user32/input.c b/dlls/user32/input.c
index 050fb2b..5c53129 100644
--- a/dlls/user32/input.c
+++ b/dlls/user32/input.c
@@ -486,11 +486,46 @@ UINT WINAPI GetRawInputDeviceList(PRAWINPUTDEVICELIST pRawInputDeviceList, PUINT
/******************************************************************
* RegisterRawInputDevices (USER32.@)
*/
-BOOL WINAPI DECLSPEC_HOTPATCH RegisterRawInputDevices(PRAWINPUTDEVICE pRawInputDevices, UINT uiNumDevices, UINT cbSize)
+BOOL WINAPI DECLSPEC_HOTPATCH RegisterRawInputDevices(RAWINPUTDEVICE *devices, UINT device_count, UINT size)
{
- FIXME("(pRawInputDevices=%p, uiNumDevices=%d, cbSize=%d) stub!\n", pRawInputDevices, uiNumDevices, cbSize);
+ struct rawinput_device *d;
+ BOOL ret;
+ UINT i;
- return TRUE;
+ TRACE("devices %p, device_count %u, size %u.\n", devices, device_count, size);
+
+ if (size != sizeof(*devices))
+ {
+ WARN("Invalid structure size %u.\n", size);
+ return FALSE;
+ }
+
+ if (!(d = HeapAlloc( GetProcessHeap(), 0, device_count * sizeof(*d) ))) return FALSE;
+
+ for (i = 0; i < device_count; ++i)
+ {
+ 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)
+ FIXME("Unhandled flags %#x for device %u.\n", devices[i].dwFlags, i);
+
+ d[i].usage_page = devices[i].usUsagePage;
+ d[i].usage = devices[i].usUsage;
+ d[i].flags = devices[i].dwFlags;
+ d[i].target = wine_server_user_handle( devices[i].hwndTarget );
+ }
+
+ SERVER_START_REQ( update_rawinput_devices )
+ {
+ wine_server_add_data( req, d, device_count * sizeof(*d) );
+ ret = !wine_server_call( req );
+ }
+ SERVER_END_REQ;
+
+ HeapFree( GetProcessHeap(), 0, d );
+
+ return ret;
}
diff --git a/server/process.c b/server/process.c
index 6a5f4b1..b8d5474 100644
--- a/server/process.c
+++ b/server/process.c
@@ -337,6 +337,7 @@ struct thread *create_process( int fd, struct thread *parent_thread, int inherit
list_init( &process->locks );
list_init( &process->classes );
list_init( &process->dlls );
+ list_init( &process->rawinput_devices );
process->start_time = current_time;
process->end_time = 0;
@@ -634,6 +635,12 @@ static void process_killed( struct process *process )
/* close the console attached to this process, if any */
free_console( process );
+ while ((ptr = list_head( &process->rawinput_devices )))
+ {
+ struct rawinput_device_entry *entry = LIST_ENTRY( ptr, struct rawinput_device_entry, entry );
+ list_remove( &entry->entry );
+ free( entry );
+ }
while ((ptr = list_head( &process->dlls )))
{
struct process_dll *dll = LIST_ENTRY( ptr, struct process_dll, entry );
diff --git a/server/process.h b/server/process.h
index 976dd38..e9861bb 100644
--- a/server/process.h
+++ b/server/process.h
@@ -45,6 +45,12 @@ struct process_dll
WCHAR *filename; /* dll file name */
};
+struct rawinput_device_entry
+{
+ struct list entry;
+ struct rawinput_device device;
+};
+
struct process
{
struct object obj; /* object header */
@@ -81,6 +87,7 @@ struct process
client_ptr_t peb; /* PEB address in client address space */
client_ptr_t ldt_copy; /* pointer to LDT copy in client addr space */
unsigned int trace_data; /* opaque data used by the process tracing mechanism */
+ struct list rawinput_devices;/* list of registered rawinput devices */
};
struct process_snapshot
diff --git a/server/protocol.def b/server/protocol.def
index 33cbb30..e1ff3e6 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -610,6 +610,14 @@ typedef union
} create_thread;
} apc_result_t;
+struct rawinput_device
+{
+ unsigned short usage_page;
+ unsigned short usage;
+ unsigned int flags;
+ user_handle_t target;
+};
+
/****************************************************************/
/* Request declarations */
@@ -3365,6 +3373,12 @@ enum coords_relative
#define SET_CURSOR_NOCLIP 0x10
+/* Modify the list of registered rawinput devices */
+ at REQ(update_rawinput_devices)
+ VARARG(devices,rawinput_devices);
+ at END
+
+
/* Retrieve the suspended context of a thread */
@REQ(get_suspend_context)
@REPLY
diff --git a/server/queue.c b/server/queue.c
index 4fd32ed..6c61bde 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -1391,6 +1391,40 @@ 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 )
+{
+ struct rawinput_device_entry *e;
+
+ LIST_FOR_EACH_ENTRY( e, ¤t->process->rawinput_devices, struct rawinput_device_entry, entry )
+ {
+ if (e->device.usage_page != usage_page || e->device.usage != usage) continue;
+ return e;
+ }
+
+ return NULL;
+}
+
+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 = mem_alloc( sizeof(*e) ))) return;
+ list_add_tail( ¤t->process->rawinput_devices, &e->entry );
+ }
+
+ if (device->flags & RIDEV_REMOVE)
+ {
+ list_remove( &e->entry );
+ free( e );
+ return;
+ }
+
+ e->device = *device;
+ e->device.target = get_user_full_handle( e->device.target );
+}
+
/* queue a hardware message into a given thread input */
static void queue_hardware_message( struct desktop *desktop, struct message *msg, int always_queue )
{
@@ -2931,3 +2965,15 @@ DECL_HANDLER(set_cursor)
reply->new_clip = input->desktop->cursor.clip;
reply->last_change = input->desktop->cursor.last_change;
}
+
+DECL_HANDLER(update_rawinput_devices)
+{
+ const struct rawinput_device *devices = get_req_data();
+ unsigned int device_count = get_req_data_size() / sizeof (*devices);
+ unsigned int i;
+
+ for (i = 0; i < device_count; ++i)
+ {
+ update_rawinput_device(&devices[i]);
+ }
+}
diff --git a/server/trace.c b/server/trace.c
index 4318a34..9afb94f 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -1004,6 +1004,23 @@ static void dump_varargs_filesystem_event( const char *prefix, data_size_t size
fputc( '}', stderr );
}
+static void dump_varargs_rawinput_devices(const char *prefix, data_size_t size )
+{
+ const struct rawinput_device *device;
+
+ fprintf( stderr, "%s{", prefix );
+ while (size >= sizeof(*device))
+ {
+ device = cur_data;
+ fprintf( stderr, "{usage_page=%#x,usage=%#x,flags=%#x,target=%#x}",
+ device->usage_page, device->usage, device->flags, device->target );
+ size -= sizeof(*device);
+ remove_data( sizeof(*device) );
+ if (size) fputc( ',', stderr );
+ }
+ fputc( '}', stderr );
+}
+
typedef void (*dump_func)( const void *req );
/* Everything below this line is generated automatically by tools/make_requests */
--
1.7.8.6
More information about the wine-patches
mailing list