mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-29 03:32:44 +00:00
server: Create a thread input shared mapping.
This commit is contained in:
parent
94fd0561b7
commit
953ee0714c
|
@ -553,7 +553,7 @@ HWND WINAPI NtUserGetForegroundWindow(void)
|
|||
{
|
||||
HWND ret = 0;
|
||||
|
||||
SERVER_START_REQ( get_thread_input )
|
||||
SERVER_START_REQ( get_thread_input_data )
|
||||
{
|
||||
req->tid = 0;
|
||||
if (!wine_server_call_err( req )) ret = wine_server_ptr_handle( reply->foreground );
|
||||
|
@ -775,7 +775,7 @@ BOOL WINAPI NtUserGetCursorInfo( CURSORINFO *info )
|
|||
|
||||
if (!info) return FALSE;
|
||||
|
||||
SERVER_START_REQ( get_thread_input )
|
||||
SERVER_START_REQ( get_thread_input_data )
|
||||
{
|
||||
req->tid = 0;
|
||||
if ((ret = !wine_server_call( req )))
|
||||
|
|
|
@ -2140,7 +2140,7 @@ BOOL WINAPI NtUserGetGUIThreadInfo( DWORD id, GUITHREADINFO *info )
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
SERVER_START_REQ( get_thread_input )
|
||||
SERVER_START_REQ( get_thread_input_data )
|
||||
{
|
||||
req->tid = id;
|
||||
if ((ret = !wine_server_call_err( req )))
|
||||
|
|
|
@ -907,10 +907,16 @@ typedef volatile struct
|
|||
unsigned int changed_bits;
|
||||
} queue_shm_t;
|
||||
|
||||
typedef volatile struct
|
||||
{
|
||||
int placeholder;
|
||||
} input_shm_t;
|
||||
|
||||
typedef volatile union
|
||||
{
|
||||
desktop_shm_t desktop;
|
||||
queue_shm_t queue;
|
||||
input_shm_t input;
|
||||
} object_shm_t;
|
||||
|
||||
typedef volatile struct
|
||||
|
@ -4040,12 +4046,12 @@ struct attach_thread_input_reply
|
|||
|
||||
|
||||
|
||||
struct get_thread_input_request
|
||||
struct get_thread_input_data_request
|
||||
{
|
||||
struct request_header __header;
|
||||
thread_id_t tid;
|
||||
};
|
||||
struct get_thread_input_reply
|
||||
struct get_thread_input_data_reply
|
||||
{
|
||||
struct reply_header __header;
|
||||
user_handle_t focus;
|
||||
|
@ -4063,6 +4069,19 @@ struct get_thread_input_reply
|
|||
|
||||
|
||||
|
||||
struct get_thread_input_request
|
||||
{
|
||||
struct request_header __header;
|
||||
thread_id_t tid;
|
||||
};
|
||||
struct get_thread_input_reply
|
||||
{
|
||||
struct reply_header __header;
|
||||
obj_locator_t locator;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct get_last_input_time_request
|
||||
{
|
||||
struct request_header __header;
|
||||
|
@ -5902,6 +5921,7 @@ enum request
|
|||
REQ_register_hotkey,
|
||||
REQ_unregister_hotkey,
|
||||
REQ_attach_thread_input,
|
||||
REQ_get_thread_input_data,
|
||||
REQ_get_thread_input,
|
||||
REQ_get_last_input_time,
|
||||
REQ_get_key_state,
|
||||
|
@ -6195,6 +6215,7 @@ union generic_request
|
|||
struct register_hotkey_request register_hotkey_request;
|
||||
struct unregister_hotkey_request unregister_hotkey_request;
|
||||
struct attach_thread_input_request attach_thread_input_request;
|
||||
struct get_thread_input_data_request get_thread_input_data_request;
|
||||
struct get_thread_input_request get_thread_input_request;
|
||||
struct get_last_input_time_request get_last_input_time_request;
|
||||
struct get_key_state_request get_key_state_request;
|
||||
|
@ -6486,6 +6507,7 @@ union generic_reply
|
|||
struct register_hotkey_reply register_hotkey_reply;
|
||||
struct unregister_hotkey_reply unregister_hotkey_reply;
|
||||
struct attach_thread_input_reply attach_thread_input_reply;
|
||||
struct get_thread_input_data_reply get_thread_input_data_reply;
|
||||
struct get_thread_input_reply get_thread_input_reply;
|
||||
struct get_last_input_time_reply get_last_input_time_reply;
|
||||
struct get_key_state_reply get_key_state_reply;
|
||||
|
@ -6592,7 +6614,7 @@ union generic_reply
|
|||
|
||||
/* ### protocol_version begin ### */
|
||||
|
||||
#define SERVER_PROTOCOL_VERSION 822
|
||||
#define SERVER_PROTOCOL_VERSION 823
|
||||
|
||||
/* ### protocol_version end ### */
|
||||
|
||||
|
|
|
@ -194,6 +194,7 @@ extern void set_session_mapping( struct mapping *mapping );
|
|||
|
||||
extern const volatile void *alloc_shared_object(void);
|
||||
extern void free_shared_object( const volatile void *object_shm );
|
||||
extern void invalidate_shared_object( const volatile void *object_shm );
|
||||
extern obj_locator_t get_shared_object_locator( const volatile void *object_shm );
|
||||
|
||||
#define SHARED_WRITE_BEGIN( object_shm, type ) \
|
||||
|
|
|
@ -1407,6 +1407,18 @@ void free_shared_object( const volatile void *object_shm )
|
|||
list_add_tail( &session.free_objects, &object->entry );
|
||||
}
|
||||
|
||||
/* invalidate client caches for a shared object by giving it a new id */
|
||||
void invalidate_shared_object( const volatile void *object_shm )
|
||||
{
|
||||
struct session_object *object = CONTAINING_RECORD( object_shm, struct session_object, obj.shm );
|
||||
|
||||
SHARED_WRITE_BEGIN( &object->obj.shm, object_shm_t )
|
||||
{
|
||||
CONTAINING_RECORD( shared, shared_object_t, shm )->id = ++session.last_object_id;
|
||||
}
|
||||
SHARED_WRITE_END;
|
||||
}
|
||||
|
||||
obj_locator_t get_shared_object_locator( const volatile void *object_shm )
|
||||
{
|
||||
struct session_object *object = CONTAINING_RECORD( object_shm, struct session_object, obj.shm );
|
||||
|
|
|
@ -923,10 +923,16 @@ typedef volatile struct
|
|||
unsigned int changed_bits; /* changed wakeup bits */
|
||||
} queue_shm_t;
|
||||
|
||||
typedef volatile struct
|
||||
{
|
||||
int placeholder;
|
||||
} input_shm_t;
|
||||
|
||||
typedef volatile union
|
||||
{
|
||||
desktop_shm_t desktop;
|
||||
queue_shm_t queue;
|
||||
input_shm_t input;
|
||||
} object_shm_t;
|
||||
|
||||
typedef volatile struct
|
||||
|
@ -2914,7 +2920,7 @@ enum coords_relative
|
|||
|
||||
|
||||
/* Get input data for a given thread */
|
||||
@REQ(get_thread_input)
|
||||
@REQ(get_thread_input_data)
|
||||
thread_id_t tid; /* id of thread */
|
||||
@REPLY
|
||||
user_handle_t focus; /* handle to the focus window */
|
||||
|
@ -2930,6 +2936,14 @@ enum coords_relative
|
|||
@END
|
||||
|
||||
|
||||
/* Get the thread input of the given thread */
|
||||
@REQ(get_thread_input)
|
||||
thread_id_t tid; /* id of thread */
|
||||
@REPLY
|
||||
obj_locator_t locator; /* locator for the shared session object */
|
||||
@END
|
||||
|
||||
|
||||
/* Get the time of the last input event */
|
||||
@REQ(get_last_input_time)
|
||||
@REPLY
|
||||
|
|
|
@ -119,6 +119,7 @@ struct thread_input
|
|||
unsigned char keystate[256]; /* state of each key */
|
||||
unsigned char desktop_keystate[256]; /* desktop keystate when keystate was synced */
|
||||
int keystate_lock; /* keystate is locked */
|
||||
const input_shm_t *shared; /* thread input in session shared memory */
|
||||
};
|
||||
|
||||
struct msg_queue
|
||||
|
@ -269,6 +270,7 @@ static struct thread_input *create_thread_input( struct thread *thread )
|
|||
set_caret_window( input, 0 );
|
||||
memset( input->keystate, 0, sizeof(input->keystate) );
|
||||
input->keystate_lock = 0;
|
||||
input->shared = NULL;
|
||||
|
||||
if (!(input->desktop = get_thread_desktop( thread, 0 /* FIXME: access rights */ )))
|
||||
{
|
||||
|
@ -277,6 +279,12 @@ static struct thread_input *create_thread_input( struct thread *thread )
|
|||
}
|
||||
memcpy( input->desktop_keystate, (const void *)input->desktop->shared->keystate,
|
||||
sizeof(input->desktop_keystate) );
|
||||
|
||||
if (!(input->shared = alloc_shared_object()))
|
||||
{
|
||||
release_object( input );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return input;
|
||||
}
|
||||
|
@ -395,6 +403,9 @@ static int assign_thread_input( struct thread *thread, struct thread_input *new_
|
|||
{
|
||||
queue->input->cursor_count -= queue->cursor_count;
|
||||
if (queue->keystate_lock) unlock_input_keystate( queue->input );
|
||||
|
||||
/* invalidate the old object to force clients to refresh their cached thread input */
|
||||
invalidate_shared_object( queue->input->shared );
|
||||
release_object( queue->input );
|
||||
}
|
||||
queue->input = (struct thread_input *)grab_object( new_input );
|
||||
|
@ -1295,6 +1306,7 @@ static void thread_input_destroy( struct object *obj )
|
|||
if (desktop->foreground_input == input) desktop->foreground_input = NULL;
|
||||
release_object( desktop );
|
||||
}
|
||||
if (input->shared) free_shared_object( input->shared );
|
||||
}
|
||||
|
||||
/* fix the thread input data when a window is destroyed */
|
||||
|
@ -3579,7 +3591,7 @@ DECL_HANDLER(attach_thread_input)
|
|||
|
||||
|
||||
/* get thread input data */
|
||||
DECL_HANDLER(get_thread_input)
|
||||
DECL_HANDLER(get_thread_input_data)
|
||||
{
|
||||
struct thread *thread = NULL;
|
||||
struct desktop *desktop;
|
||||
|
@ -3621,6 +3633,30 @@ DECL_HANDLER(get_thread_input)
|
|||
}
|
||||
|
||||
|
||||
/* get the thread input of the given thread */
|
||||
DECL_HANDLER(get_thread_input)
|
||||
{
|
||||
struct thread_input *input;
|
||||
|
||||
if (req->tid)
|
||||
{
|
||||
struct thread *thread;
|
||||
if (!(thread = get_thread_from_id( req->tid ))) return;
|
||||
input = thread->queue ? thread->queue->input : NULL;
|
||||
release_object( thread );
|
||||
}
|
||||
else
|
||||
{
|
||||
struct desktop *desktop;
|
||||
if (!(desktop = get_thread_desktop( current, 0 ))) return;
|
||||
input = desktop->foreground_input; /* get the foreground thread info */
|
||||
release_object( desktop );
|
||||
}
|
||||
|
||||
if (input && input->shared) reply->locator = get_shared_object_locator( input->shared );
|
||||
}
|
||||
|
||||
|
||||
/* retrieve queue keyboard state for current thread or global async state */
|
||||
DECL_HANDLER(get_key_state)
|
||||
{
|
||||
|
|
|
@ -303,6 +303,7 @@ DECL_HANDLER(set_user_object_info);
|
|||
DECL_HANDLER(register_hotkey);
|
||||
DECL_HANDLER(unregister_hotkey);
|
||||
DECL_HANDLER(attach_thread_input);
|
||||
DECL_HANDLER(get_thread_input_data);
|
||||
DECL_HANDLER(get_thread_input);
|
||||
DECL_HANDLER(get_last_input_time);
|
||||
DECL_HANDLER(get_key_state);
|
||||
|
@ -595,6 +596,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
|
|||
(req_handler)req_register_hotkey,
|
||||
(req_handler)req_unregister_hotkey,
|
||||
(req_handler)req_attach_thread_input,
|
||||
(req_handler)req_get_thread_input_data,
|
||||
(req_handler)req_get_thread_input,
|
||||
(req_handler)req_get_last_input_time,
|
||||
(req_handler)req_get_key_state,
|
||||
|
@ -1788,19 +1790,23 @@ C_ASSERT( FIELD_OFFSET(struct attach_thread_input_request, tid_from) == 12 );
|
|||
C_ASSERT( FIELD_OFFSET(struct attach_thread_input_request, tid_to) == 16 );
|
||||
C_ASSERT( FIELD_OFFSET(struct attach_thread_input_request, attach) == 20 );
|
||||
C_ASSERT( sizeof(struct attach_thread_input_request) == 24 );
|
||||
C_ASSERT( FIELD_OFFSET(struct get_thread_input_data_request, tid) == 12 );
|
||||
C_ASSERT( sizeof(struct get_thread_input_data_request) == 16 );
|
||||
C_ASSERT( FIELD_OFFSET(struct get_thread_input_data_reply, focus) == 8 );
|
||||
C_ASSERT( FIELD_OFFSET(struct get_thread_input_data_reply, capture) == 12 );
|
||||
C_ASSERT( FIELD_OFFSET(struct get_thread_input_data_reply, active) == 16 );
|
||||
C_ASSERT( FIELD_OFFSET(struct get_thread_input_data_reply, foreground) == 20 );
|
||||
C_ASSERT( FIELD_OFFSET(struct get_thread_input_data_reply, menu_owner) == 24 );
|
||||
C_ASSERT( FIELD_OFFSET(struct get_thread_input_data_reply, move_size) == 28 );
|
||||
C_ASSERT( FIELD_OFFSET(struct get_thread_input_data_reply, caret) == 32 );
|
||||
C_ASSERT( FIELD_OFFSET(struct get_thread_input_data_reply, cursor) == 36 );
|
||||
C_ASSERT( FIELD_OFFSET(struct get_thread_input_data_reply, show_count) == 40 );
|
||||
C_ASSERT( FIELD_OFFSET(struct get_thread_input_data_reply, rect) == 44 );
|
||||
C_ASSERT( sizeof(struct get_thread_input_data_reply) == 64 );
|
||||
C_ASSERT( FIELD_OFFSET(struct get_thread_input_request, tid) == 12 );
|
||||
C_ASSERT( sizeof(struct get_thread_input_request) == 16 );
|
||||
C_ASSERT( FIELD_OFFSET(struct get_thread_input_reply, focus) == 8 );
|
||||
C_ASSERT( FIELD_OFFSET(struct get_thread_input_reply, capture) == 12 );
|
||||
C_ASSERT( FIELD_OFFSET(struct get_thread_input_reply, active) == 16 );
|
||||
C_ASSERT( FIELD_OFFSET(struct get_thread_input_reply, foreground) == 20 );
|
||||
C_ASSERT( FIELD_OFFSET(struct get_thread_input_reply, menu_owner) == 24 );
|
||||
C_ASSERT( FIELD_OFFSET(struct get_thread_input_reply, move_size) == 28 );
|
||||
C_ASSERT( FIELD_OFFSET(struct get_thread_input_reply, caret) == 32 );
|
||||
C_ASSERT( FIELD_OFFSET(struct get_thread_input_reply, cursor) == 36 );
|
||||
C_ASSERT( FIELD_OFFSET(struct get_thread_input_reply, show_count) == 40 );
|
||||
C_ASSERT( FIELD_OFFSET(struct get_thread_input_reply, rect) == 44 );
|
||||
C_ASSERT( sizeof(struct get_thread_input_reply) == 64 );
|
||||
C_ASSERT( FIELD_OFFSET(struct get_thread_input_reply, locator) == 8 );
|
||||
C_ASSERT( sizeof(struct get_thread_input_reply) == 24 );
|
||||
C_ASSERT( sizeof(struct get_last_input_time_request) == 16 );
|
||||
C_ASSERT( FIELD_OFFSET(struct get_last_input_time_reply, time) == 8 );
|
||||
C_ASSERT( sizeof(struct get_last_input_time_reply) == 16 );
|
||||
|
|
|
@ -3516,12 +3516,12 @@ static void dump_attach_thread_input_request( const struct attach_thread_input_r
|
|||
fprintf( stderr, ", attach=%d", req->attach );
|
||||
}
|
||||
|
||||
static void dump_get_thread_input_request( const struct get_thread_input_request *req )
|
||||
static void dump_get_thread_input_data_request( const struct get_thread_input_data_request *req )
|
||||
{
|
||||
fprintf( stderr, " tid=%04x", req->tid );
|
||||
}
|
||||
|
||||
static void dump_get_thread_input_reply( const struct get_thread_input_reply *req )
|
||||
static void dump_get_thread_input_data_reply( const struct get_thread_input_data_reply *req )
|
||||
{
|
||||
fprintf( stderr, " focus=%08x", req->focus );
|
||||
fprintf( stderr, ", capture=%08x", req->capture );
|
||||
|
@ -3535,6 +3535,16 @@ static void dump_get_thread_input_reply( const struct get_thread_input_reply *re
|
|||
dump_rectangle( ", rect=", &req->rect );
|
||||
}
|
||||
|
||||
static void dump_get_thread_input_request( const struct get_thread_input_request *req )
|
||||
{
|
||||
fprintf( stderr, " tid=%04x", req->tid );
|
||||
}
|
||||
|
||||
static void dump_get_thread_input_reply( const struct get_thread_input_reply *req )
|
||||
{
|
||||
dump_obj_locator( " locator=", &req->locator );
|
||||
}
|
||||
|
||||
static void dump_get_last_input_time_request( const struct get_last_input_time_request *req )
|
||||
{
|
||||
}
|
||||
|
@ -4835,6 +4845,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
|
|||
(dump_func)dump_register_hotkey_request,
|
||||
(dump_func)dump_unregister_hotkey_request,
|
||||
(dump_func)dump_attach_thread_input_request,
|
||||
(dump_func)dump_get_thread_input_data_request,
|
||||
(dump_func)dump_get_thread_input_request,
|
||||
(dump_func)dump_get_last_input_time_request,
|
||||
(dump_func)dump_get_key_state_request,
|
||||
|
@ -5124,6 +5135,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
|
|||
(dump_func)dump_register_hotkey_reply,
|
||||
(dump_func)dump_unregister_hotkey_reply,
|
||||
NULL,
|
||||
(dump_func)dump_get_thread_input_data_reply,
|
||||
(dump_func)dump_get_thread_input_reply,
|
||||
(dump_func)dump_get_last_input_time_reply,
|
||||
(dump_func)dump_get_key_state_reply,
|
||||
|
@ -5413,6 +5425,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
|
|||
"register_hotkey",
|
||||
"unregister_hotkey",
|
||||
"attach_thread_input",
|
||||
"get_thread_input_data",
|
||||
"get_thread_input",
|
||||
"get_last_input_time",
|
||||
"get_key_state",
|
||||
|
|
Loading…
Reference in a new issue