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

win32u: Implement NtUserGetRegisteredRawInputDevices on the client side.

parent c484e4b8
......@@ -204,6 +204,8 @@ struct device
struct hid_preparsed_data *data;
};
static RAWINPUTDEVICE *registered_devices;
static unsigned int registered_device_count;
static struct list devices = LIST_INIT( devices );
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
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.@)
*/
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;
SIZE_T size;
BOOL ret;
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 );
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_INPUTSINK) && !devices[i].hwndTarget)
{
SetLastError( ERROR_INVALID_PARAMETER );
......@@ -814,17 +849,29 @@ BOOL WINAPI NtUserRegisterRawInputDevices( const RAWINPUTDEVICE *devices, UINT d
SetLastError( ERROR_INVALID_PARAMETER );
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;
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 = devices[i].usUsage;
......@@ -844,61 +891,37 @@ BOOL WINAPI NtUserRegisterRawInputDevices( const RAWINPUTDEVICE *devices, UINT d
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.@)
*/
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;
unsigned int i, status, buffer_size;
SIZE_T size, capacity;
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 );
return ~0u;
}
buffer_size = *device_count * sizeof(*buffer);
if (devices && !(buffer = malloc( buffer_size )))
return ~0u;
pthread_mutex_lock( &rawinput_mutex );
SERVER_START_REQ(get_rawinput_devices)
{
if (buffer) wine_server_set_reply( req, buffer, buffer_size );
status = wine_server_call_err(req);
*device_count = reply->device_count;
}
SERVER_END_REQ;
if (status)
{
free( buffer );
return ~0u;
}
capacity = *device_count * device_size;
*device_count = registered_device_count;
size = (SIZE_T)device_size * *device_count;
if (devices && capacity >= size) memcpy( devices, registered_devices, size );
pthread_mutex_unlock( &rawinput_mutex );
if (!devices) return 0;
for (i = 0; i < *device_count; ++i)
if (capacity < size)
{
devices[i].usUsagePage = buffer[i].usage_page;
devices[i].usUsage = buffer[i].usage;
devices[i].dwFlags = buffer[i].flags;
devices[i].hwndTarget = wine_server_ptr_handle(buffer[i].target);
SetLastError( ERROR_INSUFFICIENT_BUFFER );
return ~0u;
}
qsort( devices, *device_count, sizeof(*devices), compare_raw_input_devices );
free( buffer );
return *device_count;
}
......@@ -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 request_header __header;
......@@ -5757,7 +5743,6 @@ enum request
REQ_get_cursor_history,
REQ_get_rawinput_buffer,
REQ_update_rawinput_devices,
REQ_get_rawinput_devices,
REQ_create_job,
REQ_open_job,
REQ_assign_job,
......@@ -6042,7 +6027,6 @@ union generic_request
struct get_cursor_history_request get_cursor_history_request;
struct get_rawinput_buffer_request get_rawinput_buffer_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 open_job_request open_job_request;
struct assign_job_request assign_job_request;
......@@ -6325,7 +6309,6 @@ union generic_reply
struct get_cursor_history_reply get_cursor_history_reply;
struct get_rawinput_buffer_reply get_rawinput_buffer_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 open_job_reply open_job_reply;
struct assign_job_reply assign_job_reply;
......@@ -6341,7 +6324,7 @@ union generic_reply
/* ### protocol_version begin ### */
#define SERVER_PROTOCOL_VERSION 754
#define SERVER_PROTOCOL_VERSION 755
/* ### protocol_version end ### */
......
......@@ -3676,13 +3676,6 @@ struct handle_info
VARARG(devices,rawinput_devices);
@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 */
@REQ(create_job)
unsigned int access; /* wanted access rights */
......
......@@ -3412,24 +3412,3 @@ DECL_HANDLER(update_rawinput_devices)
e = find_rawinput_device( current->process, 1, 6 );
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);
DECL_HANDLER(get_cursor_history);
DECL_HANDLER(get_rawinput_buffer);
DECL_HANDLER(update_rawinput_devices);
DECL_HANDLER(get_rawinput_devices);
DECL_HANDLER(create_job);
DECL_HANDLER(open_job);
DECL_HANDLER(assign_job);
......@@ -669,7 +668,6 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(req_handler)req_get_cursor_history,
(req_handler)req_get_rawinput_buffer,
(req_handler)req_update_rawinput_devices,
(req_handler)req_get_rawinput_devices,
(req_handler)req_create_job,
(req_handler)req_open_job,
(req_handler)req_assign_job,
......@@ -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( sizeof(struct get_rawinput_buffer_reply) == 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( sizeof(struct create_job_request) == 16 );
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
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 )
{
fprintf( stderr, " access=%08x", req->access );
......@@ -4776,7 +4766,6 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_get_cursor_history_request,
(dump_func)dump_get_rawinput_buffer_request,
(dump_func)dump_update_rawinput_devices_request,
(dump_func)dump_get_rawinput_devices_request,
(dump_func)dump_create_job_request,
(dump_func)dump_open_job_request,
(dump_func)dump_assign_job_request,
......@@ -5057,7 +5046,6 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_get_cursor_history_reply,
(dump_func)dump_get_rawinput_buffer_reply,
NULL,
(dump_func)dump_get_rawinput_devices_reply,
(dump_func)dump_create_job_reply,
(dump_func)dump_open_job_reply,
NULL,
......@@ -5338,7 +5326,6 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"get_cursor_history",
"get_rawinput_buffer",
"update_rawinput_devices",
"get_rawinput_devices",
"create_job",
"open_job",
"assign_job",
......
Markdown is supported
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