Commit f7edc328 authored by Arkadiusz Hiler's avatar Arkadiusz Hiler Committed by Alexandre Julliard

user32: Implement GetMouseMovePointsEx().

parent fa409a91
...@@ -1267,22 +1267,64 @@ TrackMouseEvent (TRACKMOUSEEVENT *ptme) ...@@ -1267,22 +1267,64 @@ TrackMouseEvent (TRACKMOUSEEVENT *ptme)
* Success: count of point set in the buffer * Success: count of point set in the buffer
* Failure: -1 * Failure: -1
*/ */
int WINAPI GetMouseMovePointsEx(UINT size, LPMOUSEMOVEPOINT ptin, LPMOUSEMOVEPOINT ptout, int count, DWORD res) { int WINAPI GetMouseMovePointsEx( UINT size, LPMOUSEMOVEPOINT ptin, LPMOUSEMOVEPOINT ptout, int count, DWORD resolution )
{
cursor_pos_t *pos, positions[64];
int copied;
unsigned int i;
if((size != sizeof(MOUSEMOVEPOINT)) || (count < 0) || (count > 64)) {
SetLastError(ERROR_INVALID_PARAMETER); TRACE( "%d, %p, %p, %d, %d\n", size, ptin, ptout, count, resolution );
if ((size != sizeof(MOUSEMOVEPOINT)) || (count < 0) || (count > ARRAY_SIZE( positions )))
{
SetLastError( ERROR_INVALID_PARAMETER );
return -1; return -1;
} }
if(!ptin || (!ptout && count)) { if (!ptin || (!ptout && count))
SetLastError(ERROR_NOACCESS); {
SetLastError( ERROR_NOACCESS );
return -1; return -1;
} }
FIXME("(%d %p %p %d %d) stub\n", size, ptin, ptout, count, res); if (resolution != GMMP_USE_DISPLAY_POINTS)
{
FIXME( "only GMMP_USE_DISPLAY_POINTS is supported for now\n" );
SetLastError( ERROR_POINT_NOT_FOUND );
return -1;
}
SERVER_START_REQ( get_cursor_history )
{
wine_server_set_reply( req, &positions, sizeof(positions) );
if (wine_server_call_err( req )) return -1;
}
SERVER_END_REQ;
for (i = 0; i < ARRAY_SIZE( positions ); i++)
{
pos = &positions[i];
if (ptin->x == pos->x && ptin->y == pos->y && (!ptin->time || ptin->time == pos->time))
break;
}
if (i == ARRAY_SIZE( positions ))
{
SetLastError( ERROR_POINT_NOT_FOUND );
return -1;
}
for (copied = 0; copied < count && i < ARRAY_SIZE( positions ); copied++, i++)
{
pos = &positions[i];
ptout[copied].x = pos->x;
ptout[copied].y = pos->y;
ptout[copied].time = pos->time;
ptout[copied].dwExtraInfo = pos->info;
}
SetLastError(ERROR_POINT_NOT_FOUND); return copied;
return -1;
} }
/*********************************************************************** /***********************************************************************
......
...@@ -771,6 +771,15 @@ struct rawinput_device ...@@ -771,6 +771,15 @@ struct rawinput_device
user_handle_t target; user_handle_t target;
}; };
typedef struct
{
int x;
int y;
unsigned int time;
int __pad;
lparam_t info;
} cursor_pos_t;
...@@ -5158,6 +5167,18 @@ struct set_cursor_reply ...@@ -5158,6 +5167,18 @@ struct set_cursor_reply
#define SET_CURSOR_NOCLIP 0x10 #define SET_CURSOR_NOCLIP 0x10
struct get_cursor_history_request
{
struct request_header __header;
char __pad_12[4];
};
struct get_cursor_history_reply
{
struct reply_header __header;
/* VARARG(history,cursor_positions); */
};
struct get_rawinput_buffer_request struct get_rawinput_buffer_request
{ {
...@@ -5604,6 +5625,7 @@ enum request ...@@ -5604,6 +5625,7 @@ enum request
REQ_alloc_user_handle, REQ_alloc_user_handle,
REQ_free_user_handle, REQ_free_user_handle,
REQ_set_cursor, REQ_set_cursor,
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_get_rawinput_devices,
...@@ -5885,6 +5907,7 @@ union generic_request ...@@ -5885,6 +5907,7 @@ union generic_request
struct alloc_user_handle_request alloc_user_handle_request; struct alloc_user_handle_request alloc_user_handle_request;
struct free_user_handle_request free_user_handle_request; struct free_user_handle_request free_user_handle_request;
struct set_cursor_request set_cursor_request; struct set_cursor_request set_cursor_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 get_rawinput_devices_request get_rawinput_devices_request;
...@@ -6164,6 +6187,7 @@ union generic_reply ...@@ -6164,6 +6187,7 @@ union generic_reply
struct alloc_user_handle_reply alloc_user_handle_reply; struct alloc_user_handle_reply alloc_user_handle_reply;
struct free_user_handle_reply free_user_handle_reply; struct free_user_handle_reply free_user_handle_reply;
struct set_cursor_reply set_cursor_reply; struct set_cursor_reply set_cursor_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 get_rawinput_devices_reply get_rawinput_devices_reply;
...@@ -6181,7 +6205,7 @@ union generic_reply ...@@ -6181,7 +6205,7 @@ union generic_reply
/* ### protocol_version begin ### */ /* ### protocol_version begin ### */
#define SERVER_PROTOCOL_VERSION 650 #define SERVER_PROTOCOL_VERSION 651
/* ### protocol_version end ### */ /* ### protocol_version end ### */
......
...@@ -787,6 +787,15 @@ struct rawinput_device ...@@ -787,6 +787,15 @@ struct rawinput_device
user_handle_t target; user_handle_t target;
}; };
typedef struct
{
int x;
int y;
unsigned int time;
int __pad;
lparam_t info;
} cursor_pos_t;
/****************************************************************/ /****************************************************************/
/* Request declarations */ /* Request declarations */
...@@ -3551,6 +3560,12 @@ struct handle_info ...@@ -3551,6 +3560,12 @@ struct handle_info
#define SET_CURSOR_CLIP 0x08 #define SET_CURSOR_CLIP 0x08
#define SET_CURSOR_NOCLIP 0x10 #define SET_CURSOR_NOCLIP 0x10
/* Get the history of the 64 last cursor positions */
@REQ(get_cursor_history)
@REPLY
VARARG(history,cursor_positions);
@END
/* Batch read rawinput message data */ /* Batch read rawinput message data */
@REQ(get_rawinput_buffer) @REQ(get_rawinput_buffer)
......
...@@ -227,6 +227,9 @@ static const struct object_ops thread_input_ops = ...@@ -227,6 +227,9 @@ static const struct object_ops thread_input_ops =
/* pointer to input structure of foreground thread */ /* pointer to input structure of foreground thread */
static unsigned int last_input_time; static unsigned int last_input_time;
static cursor_pos_t cursor_history[64];
static unsigned int cursor_history_latest;
static void queue_hardware_message( struct desktop *desktop, struct message *msg, int always_queue ); static void queue_hardware_message( struct desktop *desktop, struct message *msg, int always_queue );
static void free_message( struct message *msg ); static void free_message( struct message *msg );
...@@ -1520,12 +1523,23 @@ static void update_rawinput_device(const struct rawinput_device *device) ...@@ -1520,12 +1523,23 @@ static void update_rawinput_device(const struct rawinput_device *device)
e->device.target = get_user_full_handle( e->device.target ); e->device.target = get_user_full_handle( e->device.target );
} }
static void prepend_cursor_history( int x, int y, unsigned int time, lparam_t info )
{
cursor_pos_t *pos = &cursor_history[--cursor_history_latest % ARRAY_SIZE(cursor_history)];
pos->x = x;
pos->y = y;
pos->time = time;
pos->info = info;
}
/* queue a hardware message into a given thread input */ /* queue a hardware message into a given thread input */
static void queue_hardware_message( struct desktop *desktop, struct message *msg, int always_queue ) static void queue_hardware_message( struct desktop *desktop, struct message *msg, int always_queue )
{ {
user_handle_t win; user_handle_t win;
struct thread *thread; struct thread *thread;
struct thread_input *input; struct thread_input *input;
struct hardware_msg_data *msg_data = msg->data;
unsigned int msg_code; unsigned int msg_code;
update_input_key_state( desktop, desktop->keystate, msg->msg, msg->wparam ); update_input_key_state( desktop, desktop->keystate, msg->msg, msg->wparam );
...@@ -1541,7 +1555,11 @@ static void queue_hardware_message( struct desktop *desktop, struct message *msg ...@@ -1541,7 +1555,11 @@ static void queue_hardware_message( struct desktop *desktop, struct message *msg
} }
else if (msg->msg != WM_INPUT) else if (msg->msg != WM_INPUT)
{ {
if (msg->msg == WM_MOUSEMOVE && update_desktop_cursor_pos( desktop, msg->x, msg->y )) always_queue = 1; if (msg->msg == WM_MOUSEMOVE)
{
prepend_cursor_history( msg->x, msg->y, msg->time, msg_data->info );
if (update_desktop_cursor_pos( desktop, msg->x, msg->y )) always_queue = 1;
}
if (desktop->keystate[VK_LBUTTON] & 0x80) msg->wparam |= MK_LBUTTON; if (desktop->keystate[VK_LBUTTON] & 0x80) msg->wparam |= MK_LBUTTON;
if (desktop->keystate[VK_MBUTTON] & 0x80) msg->wparam |= MK_MBUTTON; if (desktop->keystate[VK_MBUTTON] & 0x80) msg->wparam |= MK_MBUTTON;
if (desktop->keystate[VK_RBUTTON] & 0x80) msg->wparam |= MK_RBUTTON; if (desktop->keystate[VK_RBUTTON] & 0x80) msg->wparam |= MK_RBUTTON;
...@@ -3222,6 +3240,17 @@ DECL_HANDLER(set_cursor) ...@@ -3222,6 +3240,17 @@ DECL_HANDLER(set_cursor)
reply->last_change = input->desktop->cursor.last_change; reply->last_change = input->desktop->cursor.last_change;
} }
/* Get the history of the 64 last cursor positions */
DECL_HANDLER(get_cursor_history)
{
cursor_pos_t *pos;
unsigned int i, count = min( 64, get_reply_max_size() / sizeof(*pos) );
if ((pos = set_reply_data_size( count * sizeof(*pos) )))
for (i = 0; i < count; i++)
pos[i] = cursor_history[(i + cursor_history_latest) % ARRAY_SIZE(cursor_history)];
}
DECL_HANDLER(get_rawinput_buffer) DECL_HANDLER(get_rawinput_buffer)
{ {
struct thread_input *input = current->queue->input; struct thread_input *input = current->queue->input;
......
...@@ -380,6 +380,7 @@ DECL_HANDLER(set_window_layered_info); ...@@ -380,6 +380,7 @@ DECL_HANDLER(set_window_layered_info);
DECL_HANDLER(alloc_user_handle); DECL_HANDLER(alloc_user_handle);
DECL_HANDLER(free_user_handle); DECL_HANDLER(free_user_handle);
DECL_HANDLER(set_cursor); DECL_HANDLER(set_cursor);
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(get_rawinput_devices);
...@@ -660,6 +661,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] = ...@@ -660,6 +661,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(req_handler)req_alloc_user_handle, (req_handler)req_alloc_user_handle,
(req_handler)req_free_user_handle, (req_handler)req_free_user_handle,
(req_handler)req_set_cursor, (req_handler)req_set_cursor,
(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_get_rawinput_devices,
...@@ -2191,6 +2193,8 @@ C_ASSERT( FIELD_OFFSET(struct set_cursor_reply, new_y) == 28 ); ...@@ -2191,6 +2193,8 @@ C_ASSERT( FIELD_OFFSET(struct set_cursor_reply, new_y) == 28 );
C_ASSERT( FIELD_OFFSET(struct set_cursor_reply, new_clip) == 32 ); C_ASSERT( FIELD_OFFSET(struct set_cursor_reply, new_clip) == 32 );
C_ASSERT( FIELD_OFFSET(struct set_cursor_reply, last_change) == 48 ); C_ASSERT( FIELD_OFFSET(struct set_cursor_reply, last_change) == 48 );
C_ASSERT( sizeof(struct set_cursor_reply) == 56 ); C_ASSERT( sizeof(struct set_cursor_reply) == 56 );
C_ASSERT( sizeof(struct get_cursor_history_request) == 16 );
C_ASSERT( sizeof(struct get_cursor_history_reply) == 8 );
C_ASSERT( FIELD_OFFSET(struct get_rawinput_buffer_request, rawinput_size) == 12 ); C_ASSERT( FIELD_OFFSET(struct get_rawinput_buffer_request, rawinput_size) == 12 );
C_ASSERT( FIELD_OFFSET(struct get_rawinput_buffer_request, buffer_size) == 16 ); C_ASSERT( FIELD_OFFSET(struct get_rawinput_buffer_request, buffer_size) == 16 );
C_ASSERT( sizeof(struct get_rawinput_buffer_request) == 24 ); C_ASSERT( sizeof(struct get_rawinput_buffer_request) == 24 );
......
...@@ -893,6 +893,24 @@ static void dump_varargs_rectangles( const char *prefix, data_size_t size ) ...@@ -893,6 +893,24 @@ static void dump_varargs_rectangles( const char *prefix, data_size_t size )
remove_data( size ); remove_data( size );
} }
static void dump_varargs_cursor_positions( const char *prefix, data_size_t size )
{
const cursor_pos_t *pos = cur_data;
data_size_t len = size / sizeof(*pos);
fprintf( stderr, "%s{", prefix );
while (len > 0)
{
fprintf( stderr, "{x=%d,y=%d,time=%u", pos->x, pos->y, pos->time );
dump_uint64( ",info=", &pos->info );
fputc( '}', stderr );
pos++;
if (--len) fputc( ',', stderr );
}
fputc( '}', stderr );
remove_data( size );
}
static void dump_varargs_message_data( const char *prefix, data_size_t size ) static void dump_varargs_message_data( const char *prefix, data_size_t size )
{ {
/* FIXME: dump the structured data */ /* FIXME: dump the structured data */
...@@ -4261,6 +4279,15 @@ static void dump_set_cursor_reply( const struct set_cursor_reply *req ) ...@@ -4261,6 +4279,15 @@ static void dump_set_cursor_reply( const struct set_cursor_reply *req )
fprintf( stderr, ", last_change=%08x", req->last_change ); fprintf( stderr, ", last_change=%08x", req->last_change );
} }
static void dump_get_cursor_history_request( const struct get_cursor_history_request *req )
{
}
static void dump_get_cursor_history_reply( const struct get_cursor_history_reply *req )
{
dump_varargs_cursor_positions( " history=", cur_size );
}
static void dump_get_rawinput_buffer_request( const struct get_rawinput_buffer_request *req ) static void dump_get_rawinput_buffer_request( const struct get_rawinput_buffer_request *req )
{ {
fprintf( stderr, " rawinput_size=%u", req->rawinput_size ); fprintf( stderr, " rawinput_size=%u", req->rawinput_size );
...@@ -4627,6 +4654,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = { ...@@ -4627,6 +4654,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_alloc_user_handle_request, (dump_func)dump_alloc_user_handle_request,
(dump_func)dump_free_user_handle_request, (dump_func)dump_free_user_handle_request,
(dump_func)dump_set_cursor_request, (dump_func)dump_set_cursor_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_get_rawinput_devices_request,
...@@ -4904,6 +4932,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = { ...@@ -4904,6 +4932,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_alloc_user_handle_reply, (dump_func)dump_alloc_user_handle_reply,
NULL, NULL,
(dump_func)dump_set_cursor_reply, (dump_func)dump_set_cursor_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_get_rawinput_devices_reply,
...@@ -5181,6 +5210,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = { ...@@ -5181,6 +5210,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"alloc_user_handle", "alloc_user_handle",
"free_user_handle", "free_user_handle",
"set_cursor", "set_cursor",
"get_cursor_history",
"get_rawinput_buffer", "get_rawinput_buffer",
"update_rawinput_devices", "update_rawinput_devices",
"get_rawinput_devices", "get_rawinput_devices",
...@@ -5248,6 +5278,7 @@ static const struct ...@@ -5248,6 +5278,7 @@ static const struct
{ "INFO_LENGTH_MISMATCH", STATUS_INFO_LENGTH_MISMATCH }, { "INFO_LENGTH_MISMATCH", STATUS_INFO_LENGTH_MISMATCH },
{ "INSTANCE_NOT_AVAILABLE", STATUS_INSTANCE_NOT_AVAILABLE }, { "INSTANCE_NOT_AVAILABLE", STATUS_INSTANCE_NOT_AVAILABLE },
{ "INSUFFICIENT_RESOURCES", STATUS_INSUFFICIENT_RESOURCES }, { "INSUFFICIENT_RESOURCES", STATUS_INSUFFICIENT_RESOURCES },
{ "INVALID_BUFFER_SIZE", STATUS_INVALID_BUFFER_SIZE },
{ "INVALID_CID", STATUS_INVALID_CID }, { "INVALID_CID", STATUS_INVALID_CID },
{ "INVALID_DEVICE_REQUEST", STATUS_INVALID_DEVICE_REQUEST }, { "INVALID_DEVICE_REQUEST", STATUS_INVALID_DEVICE_REQUEST },
{ "INVALID_FILE_FOR_SECTION", STATUS_INVALID_FILE_FOR_SECTION }, { "INVALID_FILE_FOR_SECTION", STATUS_INVALID_FILE_FOR_SECTION },
......
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