Commit 1587e9db authored by Rémi Bernon's avatar Rémi Bernon 💬 Committed by Alexandre Julliard
Browse files

win32u: Implement NtUserGetRegisteredRawInputDevices on the client side.

parent c484e4b8
...@@ -204,6 +204,8 @@ struct device ...@@ -204,6 +204,8 @@ struct device
struct hid_preparsed_data *data; struct hid_preparsed_data *data;
}; };
static RAWINPUTDEVICE *registered_devices;
static unsigned int registered_device_count;
static struct list devices = LIST_INIT( devices ); static struct list devices = LIST_INIT( devices );
static pthread_mutex_t rawinput_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t rawinput_mutex = PTHREAD_MUTEX_INITIALIZER;
...@@ -783,26 +785,59 @@ BOOL process_rawinput_message( MSG *msg, UINT hw_id, const struct hardware_msg_d ...@@ -783,26 +785,59 @@ BOOL process_rawinput_message( MSG *msg, UINT hw_id, const struct hardware_msg_d
return TRUE; return TRUE;
} }
static void register_rawinput_device( const RAWINPUTDEVICE *device )
{
RAWINPUTDEVICE *pos, *end;
for (pos = registered_devices, end = pos + registered_device_count; pos != end; pos++)
{
if (pos->usUsagePage < device->usUsagePage) continue;
if (pos->usUsagePage > device->usUsagePage) break;
if (pos->usUsage >= device->usUsage) break;
}
if (device->dwFlags & RIDEV_REMOVE)
{
if (pos != end && pos->usUsagePage == device->usUsagePage && pos->usUsage == device->usUsage)
{
memmove( pos, pos + 1, (char *)end - (char *)(pos + 1) );
registered_device_count--;
}
}
else
{
if (pos == end || pos->usUsagePage != device->usUsagePage || pos->usUsage != device->usUsage)
{
memmove( pos + 1, pos, (char *)end - (char *)pos );
registered_device_count++;
}
*pos = *device;
}
}
/********************************************************************** /**********************************************************************
* NtUserRegisterRawInputDevices (win32u.@) * NtUserRegisterRawInputDevices (win32u.@)
*/ */
BOOL WINAPI NtUserRegisterRawInputDevices( const RAWINPUTDEVICE *devices, UINT device_count, UINT size ) BOOL WINAPI NtUserRegisterRawInputDevices( const RAWINPUTDEVICE *devices, UINT device_count, UINT device_size )
{ {
struct rawinput_device *server_devices; struct rawinput_device *server_devices;
SIZE_T size;
BOOL ret; BOOL ret;
UINT i; UINT i;
TRACE( "devices %p, device_count %u, size %u.\n", devices, device_count, size ); TRACE( "devices %p, device_count %u, device_size %u.\n", devices, device_count, device_size );
if (size != sizeof(*devices)) if (device_size != sizeof(RAWINPUTDEVICE))
{ {
WARN( "Invalid structure size %u.\n", size );
SetLastError( ERROR_INVALID_PARAMETER ); SetLastError( ERROR_INVALID_PARAMETER );
return FALSE; return FALSE;
} }
for (i = 0; i < device_count; ++i) 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_INPUTSINK) && !devices[i].hwndTarget) if ((devices[i].dwFlags & RIDEV_INPUTSINK) && !devices[i].hwndTarget)
{ {
SetLastError( ERROR_INVALID_PARAMETER ); SetLastError( ERROR_INVALID_PARAMETER );
...@@ -814,17 +849,29 @@ BOOL WINAPI NtUserRegisterRawInputDevices( const RAWINPUTDEVICE *devices, UINT d ...@@ -814,17 +849,29 @@ BOOL WINAPI NtUserRegisterRawInputDevices( const RAWINPUTDEVICE *devices, UINT d
SetLastError( ERROR_INVALID_PARAMETER ); SetLastError( ERROR_INVALID_PARAMETER );
return FALSE; return FALSE;
} }
if (devices[i].dwFlags & ~(RIDEV_REMOVE|RIDEV_NOLEGACY|RIDEV_INPUTSINK|RIDEV_DEVNOTIFY))
FIXME( "Unhandled flags %#x for device %u.\n", devices[i].dwFlags, i );
}
pthread_mutex_lock( &rawinput_mutex );
size = (SIZE_T)device_size * (registered_device_count + device_count);
registered_devices = realloc( registered_devices, size );
if (registered_devices) for (i = 0; i < device_count; ++i) register_rawinput_device( devices + i );
pthread_mutex_unlock( &rawinput_mutex );
if (!registered_devices)
{
SetLastError( ERROR_OUTOFMEMORY );
return FALSE;
} }
if (!(server_devices = malloc( device_count * sizeof(*server_devices) ))) return FALSE; if (!(server_devices = malloc( device_count * sizeof(*server_devices) ))) return FALSE;
for (i = 0; i < device_count; ++i) 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|RIDEV_NOLEGACY|RIDEV_INPUTSINK|RIDEV_DEVNOTIFY))
FIXME( "Unhandled flags %#x for device %u.\n", devices[i].dwFlags, i );
server_devices[i].usage_page = devices[i].usUsagePage; server_devices[i].usage_page = devices[i].usUsagePage;
server_devices[i].usage = devices[i].usUsage; server_devices[i].usage = devices[i].usUsage;
...@@ -844,61 +891,37 @@ BOOL WINAPI NtUserRegisterRawInputDevices( const RAWINPUTDEVICE *devices, UINT d ...@@ -844,61 +891,37 @@ BOOL WINAPI NtUserRegisterRawInputDevices( const RAWINPUTDEVICE *devices, UINT d
return ret; return ret;
} }
static int compare_raw_input_devices( const void *ap, const void *bp )
{
const RAWINPUTDEVICE a = *(const RAWINPUTDEVICE *)ap;
const RAWINPUTDEVICE b = *(const RAWINPUTDEVICE *)bp;
if (a.usUsagePage != b.usUsagePage) return a.usUsagePage - b.usUsagePage;
if (a.usUsage != b.usUsage) return a.usUsage - b.usUsage;
return 0;
}
/********************************************************************** /**********************************************************************
* NtUserGetRegisteredRawInputDevices (win32u.@) * NtUserGetRegisteredRawInputDevices (win32u.@)
*/ */
UINT WINAPI NtUserGetRegisteredRawInputDevices( RAWINPUTDEVICE *devices, UINT *device_count, UINT size ) UINT WINAPI NtUserGetRegisteredRawInputDevices( RAWINPUTDEVICE *devices, UINT *device_count, UINT device_size )
{ {
struct rawinput_device *buffer = NULL; SIZE_T size, capacity;
unsigned int i, status, buffer_size;
TRACE("devices %p, device_count %p, size %u\n", devices, device_count, size); TRACE( "devices %p, device_count %p, device_size %u\n", devices, device_count, device_size );
if (size != sizeof(RAWINPUTDEVICE) || !device_count || (devices && !*device_count)) if (device_size != sizeof(RAWINPUTDEVICE) || !device_count || (devices && !*device_count))
{ {
SetLastError( ERROR_INVALID_PARAMETER ); SetLastError( ERROR_INVALID_PARAMETER );
return ~0u; return ~0u;
} }
buffer_size = *device_count * sizeof(*buffer); pthread_mutex_lock( &rawinput_mutex );
if (devices && !(buffer = malloc( buffer_size )))
return ~0u;
SERVER_START_REQ(get_rawinput_devices) capacity = *device_count * device_size;
{ *device_count = registered_device_count;
if (buffer) wine_server_set_reply( req, buffer, buffer_size ); size = (SIZE_T)device_size * *device_count;
status = wine_server_call_err(req); if (devices && capacity >= size) memcpy( devices, registered_devices, size );
*device_count = reply->device_count;
} pthread_mutex_unlock( &rawinput_mutex );
SERVER_END_REQ;
if (status)
{
free( buffer );
return ~0u;
}
if (!devices) return 0; if (!devices) return 0;
for (i = 0; i < *device_count; ++i) if (capacity < size)
{ {
devices[i].usUsagePage = buffer[i].usage_page; SetLastError( ERROR_INSUFFICIENT_BUFFER );
devices[i].usUsage = buffer[i].usage; return ~0u;
devices[i].dwFlags = buffer[i].flags;
devices[i].hwndTarget = wine_server_ptr_handle(buffer[i].target);
} }
qsort( devices, *device_count, sizeof(*devices), compare_raw_input_devices );
free( buffer );
return *device_count; return *device_count;
} }
...@@ -5316,20 +5316,6 @@ struct update_rawinput_devices_reply ...@@ -5316,20 +5316,6 @@ struct update_rawinput_devices_reply
}; };
struct get_rawinput_devices_request
{
struct request_header __header;
char __pad_12[4];
};
struct get_rawinput_devices_reply
{
struct reply_header __header;
unsigned int device_count;
/* VARARG(devices,rawinput_devices); */
char __pad_12[4];
};
struct create_job_request struct create_job_request
{ {
struct request_header __header; struct request_header __header;
...@@ -5757,7 +5743,6 @@ enum request ...@@ -5757,7 +5743,6 @@ enum request
REQ_get_cursor_history, REQ_get_cursor_history,
REQ_get_rawinput_buffer, REQ_get_rawinput_buffer,
REQ_update_rawinput_devices, REQ_update_rawinput_devices,
REQ_get_rawinput_devices,
REQ_create_job, REQ_create_job,
REQ_open_job, REQ_open_job,
REQ_assign_job, REQ_assign_job,
...@@ -6042,7 +6027,6 @@ union generic_request ...@@ -6042,7 +6027,6 @@ union generic_request
struct get_cursor_history_request get_cursor_history_request; struct get_cursor_history_request get_cursor_history_request;
struct get_rawinput_buffer_request get_rawinput_buffer_request; struct get_rawinput_buffer_request get_rawinput_buffer_request;
struct update_rawinput_devices_request update_rawinput_devices_request; struct update_rawinput_devices_request update_rawinput_devices_request;
struct get_rawinput_devices_request get_rawinput_devices_request;
struct create_job_request create_job_request; struct create_job_request create_job_request;
struct open_job_request open_job_request; struct open_job_request open_job_request;
struct assign_job_request assign_job_request; struct assign_job_request assign_job_request;
...@@ -6325,7 +6309,6 @@ union generic_reply ...@@ -6325,7 +6309,6 @@ union generic_reply
struct get_cursor_history_reply get_cursor_history_reply; struct get_cursor_history_reply get_cursor_history_reply;
struct get_rawinput_buffer_reply get_rawinput_buffer_reply; struct get_rawinput_buffer_reply get_rawinput_buffer_reply;
struct update_rawinput_devices_reply update_rawinput_devices_reply; struct update_rawinput_devices_reply update_rawinput_devices_reply;
struct get_rawinput_devices_reply get_rawinput_devices_reply;
struct create_job_reply create_job_reply; struct create_job_reply create_job_reply;
struct open_job_reply open_job_reply; struct open_job_reply open_job_reply;
struct assign_job_reply assign_job_reply; struct assign_job_reply assign_job_reply;
...@@ -6341,7 +6324,7 @@ union generic_reply ...@@ -6341,7 +6324,7 @@ union generic_reply
/* ### protocol_version begin ### */ /* ### protocol_version begin ### */
#define SERVER_PROTOCOL_VERSION 754 #define SERVER_PROTOCOL_VERSION 755
/* ### protocol_version end ### */ /* ### protocol_version end ### */
......
...@@ -3676,13 +3676,6 @@ struct handle_info ...@@ -3676,13 +3676,6 @@ struct handle_info
VARARG(devices,rawinput_devices); VARARG(devices,rawinput_devices);
@END @END
/* Retrieve the list of registered rawinput devices */
@REQ(get_rawinput_devices)
@REPLY
unsigned int device_count;
VARARG(devices,rawinput_devices);
@END
/* Create a new job object */ /* Create a new job object */
@REQ(create_job) @REQ(create_job)
unsigned int access; /* wanted access rights */ unsigned int access; /* wanted access rights */
......
...@@ -3412,24 +3412,3 @@ DECL_HANDLER(update_rawinput_devices) ...@@ -3412,24 +3412,3 @@ DECL_HANDLER(update_rawinput_devices)
e = find_rawinput_device( current->process, 1, 6 ); e = find_rawinput_device( current->process, 1, 6 );
current->process->rawinput_kbd = e ? &e->device : NULL; current->process->rawinput_kbd = e ? &e->device : NULL;
} }
DECL_HANDLER(get_rawinput_devices)
{
struct rawinput_device_entry *e;
struct rawinput_device *devices;
unsigned int i = 0, device_count = list_count( &current->process->rawinput_devices );
unsigned int size = device_count * sizeof(*devices);
reply->device_count = device_count;
/* no buffer provided, nothing else to do */
if (!get_reply_max_size()) return;
if (size > get_reply_max_size())
set_error( STATUS_BUFFER_TOO_SMALL );
else if ((devices = set_reply_data_size( size )))
{
LIST_FOR_EACH_ENTRY( e, &current->process->rawinput_devices, struct rawinput_device_entry, entry )
devices[i++] = e->device;
}
}
...@@ -385,7 +385,6 @@ DECL_HANDLER(set_cursor); ...@@ -385,7 +385,6 @@ DECL_HANDLER(set_cursor);
DECL_HANDLER(get_cursor_history); DECL_HANDLER(get_cursor_history);
DECL_HANDLER(get_rawinput_buffer); DECL_HANDLER(get_rawinput_buffer);
DECL_HANDLER(update_rawinput_devices); DECL_HANDLER(update_rawinput_devices);
DECL_HANDLER(get_rawinput_devices);
DECL_HANDLER(create_job); DECL_HANDLER(create_job);
DECL_HANDLER(open_job); DECL_HANDLER(open_job);
DECL_HANDLER(assign_job); DECL_HANDLER(assign_job);
...@@ -669,7 +668,6 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] = ...@@ -669,7 +668,6 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(req_handler)req_get_cursor_history, (req_handler)req_get_cursor_history,
(req_handler)req_get_rawinput_buffer, (req_handler)req_get_rawinput_buffer,
(req_handler)req_update_rawinput_devices, (req_handler)req_update_rawinput_devices,
(req_handler)req_get_rawinput_devices,
(req_handler)req_create_job, (req_handler)req_create_job,
(req_handler)req_open_job, (req_handler)req_open_job,
(req_handler)req_assign_job, (req_handler)req_assign_job,
...@@ -2226,9 +2224,6 @@ C_ASSERT( FIELD_OFFSET(struct get_rawinput_buffer_reply, next_size) == 8 ); ...@@ -2226,9 +2224,6 @@ C_ASSERT( FIELD_OFFSET(struct get_rawinput_buffer_reply, next_size) == 8 );
C_ASSERT( FIELD_OFFSET(struct get_rawinput_buffer_reply, count) == 12 ); C_ASSERT( FIELD_OFFSET(struct get_rawinput_buffer_reply, count) == 12 );
C_ASSERT( sizeof(struct get_rawinput_buffer_reply) == 16 ); C_ASSERT( sizeof(struct get_rawinput_buffer_reply) == 16 );
C_ASSERT( sizeof(struct update_rawinput_devices_request) == 16 ); C_ASSERT( sizeof(struct update_rawinput_devices_request) == 16 );
C_ASSERT( sizeof(struct get_rawinput_devices_request) == 16 );
C_ASSERT( FIELD_OFFSET(struct get_rawinput_devices_reply, device_count) == 8 );
C_ASSERT( sizeof(struct get_rawinput_devices_reply) == 16 );
C_ASSERT( FIELD_OFFSET(struct create_job_request, access) == 12 ); C_ASSERT( FIELD_OFFSET(struct create_job_request, access) == 12 );
C_ASSERT( sizeof(struct create_job_request) == 16 ); C_ASSERT( sizeof(struct create_job_request) == 16 );
C_ASSERT( FIELD_OFFSET(struct create_job_reply, handle) == 8 ); C_ASSERT( FIELD_OFFSET(struct create_job_reply, handle) == 8 );
......
...@@ -4408,16 +4408,6 @@ static void dump_update_rawinput_devices_request( const struct update_rawinput_d ...@@ -4408,16 +4408,6 @@ static void dump_update_rawinput_devices_request( const struct update_rawinput_d
dump_varargs_rawinput_devices( " devices=", cur_size ); dump_varargs_rawinput_devices( " devices=", cur_size );
} }
static void dump_get_rawinput_devices_request( const struct get_rawinput_devices_request *req )
{
}
static void dump_get_rawinput_devices_reply( const struct get_rawinput_devices_reply *req )
{
fprintf( stderr, " device_count=%08x", req->device_count );
dump_varargs_rawinput_devices( ", devices=", cur_size );
}
static void dump_create_job_request( const struct create_job_request *req ) static void dump_create_job_request( const struct create_job_request *req )
{ {
fprintf( stderr, " access=%08x", req->access ); fprintf( stderr, " access=%08x", req->access );
...@@ -4776,7 +4766,6 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = { ...@@ -4776,7 +4766,6 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_get_cursor_history_request, (dump_func)dump_get_cursor_history_request,
(dump_func)dump_get_rawinput_buffer_request, (dump_func)dump_get_rawinput_buffer_request,
(dump_func)dump_update_rawinput_devices_request, (dump_func)dump_update_rawinput_devices_request,
(dump_func)dump_get_rawinput_devices_request,
(dump_func)dump_create_job_request, (dump_func)dump_create_job_request,
(dump_func)dump_open_job_request, (dump_func)dump_open_job_request,
(dump_func)dump_assign_job_request, (dump_func)dump_assign_job_request,
...@@ -5057,7 +5046,6 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = { ...@@ -5057,7 +5046,6 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_get_cursor_history_reply, (dump_func)dump_get_cursor_history_reply,
(dump_func)dump_get_rawinput_buffer_reply, (dump_func)dump_get_rawinput_buffer_reply,
NULL, NULL,
(dump_func)dump_get_rawinput_devices_reply,
(dump_func)dump_create_job_reply, (dump_func)dump_create_job_reply,
(dump_func)dump_open_job_reply, (dump_func)dump_open_job_reply,
NULL, NULL,
...@@ -5338,7 +5326,6 @@ static const char * const req_names[REQ_NB_REQUESTS] = { ...@@ -5338,7 +5326,6 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"get_cursor_history", "get_cursor_history",
"get_rawinput_buffer", "get_rawinput_buffer",
"update_rawinput_devices", "update_rawinput_devices",
"get_rawinput_devices",
"create_job", "create_job",
"open_job", "open_job",
"assign_job", "assign_job",
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment