mirror of
https://gitlab.winehq.org/wine/wine.git
synced 2024-11-21 17:09:06 -07:00
server: Keep track of the winstation input desktop.
This commit is contained in:
parent
c77261dd5c
commit
a1d63d109d
Notes:
Alexandre Julliard
2024-09-23 23:03:29 +02:00
Approved-by: Alexandre Julliard (@julliard) Merge-Request: https://gitlab.winehq.org/wine/wine/-/merge_requests/5066
9 changed files with 92 additions and 6 deletions
|
@ -9806,7 +9806,6 @@ static DWORD WINAPI run_in_temp_desktop_thread_func(LPVOID param)
|
|||
curr_desktop_name, sizeof(curr_desktop_name), &length );
|
||||
ok_(file, line)( result, "GetUserObjectInformationA(post_inp_desktop=%p) error %lu [rl = %lu]\n",
|
||||
post_inp_desktop, GetLastError(), length );
|
||||
todo_wine
|
||||
ok_(file, line)( strcmp( curr_desktop_name, temp_desktop_name ) == 0,
|
||||
"different desktop name: %s != %s (no switch or concurrent WineTest run?)\n",
|
||||
debugstr_a( curr_desktop_name ), debugstr_a( temp_desktop_name ) );
|
||||
|
|
|
@ -693,7 +693,6 @@ static void test_inputdesktop(void)
|
|||
memset(name, 0, sizeof(name));
|
||||
ret = GetUserObjectInformationA(input_desk, UOI_NAME, name, 1024, NULL);
|
||||
ok(ret, "GetUserObjectInformation failed!\n");
|
||||
todo_wine
|
||||
ok(!strcmp(name, "new_desk"), "unexpected desktop %s\n", name);
|
||||
ret = CloseDesktop(input_desk);
|
||||
ok(ret, "CloseDesktop failed!\n");
|
||||
|
@ -798,7 +797,6 @@ static void test_inputdesktop2(void)
|
|||
ok(hdesk != NULL, "OpenDesktop failed!\n");
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = SwitchDesktop(hdesk);
|
||||
todo_wine
|
||||
ok(!ret, "Switch to desktop belong to non default winstation should fail!\n");
|
||||
todo_wine
|
||||
ok(GetLastError() == ERROR_ACCESS_DENIED || broken(GetLastError() == 0xdeadbeef), "last error %08lx\n", GetLastError());
|
||||
|
|
|
@ -295,7 +295,15 @@ HDESK WINAPI NtUserOpenInputDesktop( DWORD flags, BOOL inherit, ACCESS_MASK acce
|
|||
|
||||
BOOL WINAPI NtUserSwitchDesktop( HDESK desktop )
|
||||
{
|
||||
FIXME( "desktop %p stub!\n", desktop );
|
||||
TRACE( "desktop %p\n", desktop );
|
||||
|
||||
SERVER_START_REQ( set_input_desktop )
|
||||
{
|
||||
req->handle = wine_server_obj_handle( desktop );
|
||||
if (wine_server_call_err( req )) return FALSE;
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -3835,6 +3835,18 @@ struct open_input_desktop_reply
|
|||
|
||||
|
||||
|
||||
struct set_input_desktop_request
|
||||
{
|
||||
struct request_header __header;
|
||||
obj_handle_t handle;
|
||||
};
|
||||
struct set_input_desktop_reply
|
||||
{
|
||||
struct reply_header __header;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct close_desktop_request
|
||||
{
|
||||
struct request_header __header;
|
||||
|
@ -5799,6 +5811,7 @@ enum request
|
|||
REQ_create_desktop,
|
||||
REQ_open_desktop,
|
||||
REQ_open_input_desktop,
|
||||
REQ_set_input_desktop,
|
||||
REQ_close_desktop,
|
||||
REQ_get_thread_desktop,
|
||||
REQ_set_thread_desktop,
|
||||
|
@ -6090,6 +6103,7 @@ union generic_request
|
|||
struct create_desktop_request create_desktop_request;
|
||||
struct open_desktop_request open_desktop_request;
|
||||
struct open_input_desktop_request open_input_desktop_request;
|
||||
struct set_input_desktop_request set_input_desktop_request;
|
||||
struct close_desktop_request close_desktop_request;
|
||||
struct get_thread_desktop_request get_thread_desktop_request;
|
||||
struct set_thread_desktop_request set_thread_desktop_request;
|
||||
|
@ -6379,6 +6393,7 @@ union generic_reply
|
|||
struct create_desktop_reply create_desktop_reply;
|
||||
struct open_desktop_reply open_desktop_reply;
|
||||
struct open_input_desktop_reply open_input_desktop_reply;
|
||||
struct set_input_desktop_reply set_input_desktop_reply;
|
||||
struct close_desktop_reply close_desktop_reply;
|
||||
struct get_thread_desktop_reply get_thread_desktop_reply;
|
||||
struct set_thread_desktop_reply set_thread_desktop_reply;
|
||||
|
@ -6492,7 +6507,7 @@ union generic_reply
|
|||
|
||||
/* ### protocol_version begin ### */
|
||||
|
||||
#define SERVER_PROTOCOL_VERSION 793
|
||||
#define SERVER_PROTOCOL_VERSION 794
|
||||
|
||||
/* ### protocol_version end ### */
|
||||
|
||||
|
|
|
@ -2769,6 +2769,12 @@ enum coords_relative
|
|||
@END
|
||||
|
||||
|
||||
/* Changes the current input desktop */
|
||||
@REQ(set_input_desktop)
|
||||
obj_handle_t handle; /* handle to the desktop */
|
||||
@END
|
||||
|
||||
|
||||
/* Close a desktop */
|
||||
@REQ(close_desktop)
|
||||
obj_handle_t handle; /* handle to the desktop */
|
||||
|
|
|
@ -294,6 +294,7 @@ DECL_HANDLER(enum_winstation);
|
|||
DECL_HANDLER(create_desktop);
|
||||
DECL_HANDLER(open_desktop);
|
||||
DECL_HANDLER(open_input_desktop);
|
||||
DECL_HANDLER(set_input_desktop);
|
||||
DECL_HANDLER(close_desktop);
|
||||
DECL_HANDLER(get_thread_desktop);
|
||||
DECL_HANDLER(set_thread_desktop);
|
||||
|
@ -584,6 +585,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
|
|||
(req_handler)req_create_desktop,
|
||||
(req_handler)req_open_desktop,
|
||||
(req_handler)req_open_input_desktop,
|
||||
(req_handler)req_set_input_desktop,
|
||||
(req_handler)req_close_desktop,
|
||||
(req_handler)req_get_thread_desktop,
|
||||
(req_handler)req_set_thread_desktop,
|
||||
|
@ -1740,6 +1742,8 @@ C_ASSERT( FIELD_OFFSET(struct open_input_desktop_request, attributes) == 20 );
|
|||
C_ASSERT( sizeof(struct open_input_desktop_request) == 24 );
|
||||
C_ASSERT( FIELD_OFFSET(struct open_input_desktop_reply, handle) == 8 );
|
||||
C_ASSERT( sizeof(struct open_input_desktop_reply) == 16 );
|
||||
C_ASSERT( FIELD_OFFSET(struct set_input_desktop_request, handle) == 12 );
|
||||
C_ASSERT( sizeof(struct set_input_desktop_request) == 16 );
|
||||
C_ASSERT( FIELD_OFFSET(struct close_desktop_request, handle) == 12 );
|
||||
C_ASSERT( sizeof(struct close_desktop_request) == 16 );
|
||||
C_ASSERT( FIELD_OFFSET(struct get_thread_desktop_request, tid) == 12 );
|
||||
|
|
|
@ -3381,6 +3381,11 @@ static void dump_open_input_desktop_reply( const struct open_input_desktop_reply
|
|||
fprintf( stderr, " handle=%04x", req->handle );
|
||||
}
|
||||
|
||||
static void dump_set_input_desktop_request( const struct set_input_desktop_request *req )
|
||||
{
|
||||
fprintf( stderr, " handle=%04x", req->handle );
|
||||
}
|
||||
|
||||
static void dump_close_desktop_request( const struct close_desktop_request *req )
|
||||
{
|
||||
fprintf( stderr, " handle=%04x", req->handle );
|
||||
|
@ -4765,6 +4770,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
|
|||
(dump_func)dump_create_desktop_request,
|
||||
(dump_func)dump_open_desktop_request,
|
||||
(dump_func)dump_open_input_desktop_request,
|
||||
(dump_func)dump_set_input_desktop_request,
|
||||
(dump_func)dump_close_desktop_request,
|
||||
(dump_func)dump_get_thread_desktop_request,
|
||||
(dump_func)dump_set_thread_desktop_request,
|
||||
|
@ -5053,6 +5059,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
|
|||
(dump_func)dump_open_desktop_reply,
|
||||
(dump_func)dump_open_input_desktop_reply,
|
||||
NULL,
|
||||
NULL,
|
||||
(dump_func)dump_get_thread_desktop_reply,
|
||||
NULL,
|
||||
(dump_func)dump_enum_desktop_reply,
|
||||
|
@ -5339,6 +5346,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
|
|||
"create_desktop",
|
||||
"open_desktop",
|
||||
"open_input_desktop",
|
||||
"set_input_desktop",
|
||||
"close_desktop",
|
||||
"get_thread_desktop",
|
||||
"set_thread_desktop",
|
||||
|
|
|
@ -48,6 +48,7 @@ struct winstation
|
|||
unsigned int flags; /* winstation flags */
|
||||
struct list entry; /* entry in global winstation list */
|
||||
struct list desktops; /* list of desktops of this winstation */
|
||||
struct desktop *input_desktop; /* desktop receiving user input */
|
||||
struct clipboard *clipboard; /* clipboard information */
|
||||
struct atom_table *atom_table; /* global atom table */
|
||||
struct namespace *desktop_names; /* namespace for desktops of this winstation */
|
||||
|
@ -67,6 +68,7 @@ struct desktop
|
|||
struct object obj; /* object header */
|
||||
unsigned int flags; /* desktop flags */
|
||||
struct winstation *winstation; /* winstation this desktop belongs to */
|
||||
timeout_t input_time; /* last time this desktop had the input */
|
||||
struct list entry; /* entry in winstation list of desktops */
|
||||
struct window *top_window; /* desktop window for this desktop */
|
||||
struct window *msg_window; /* HWND_MESSAGE top window */
|
||||
|
|
|
@ -144,6 +144,7 @@ static struct winstation *create_winstation( struct object *root, const struct u
|
|||
{
|
||||
/* initialize it if it didn't already exist */
|
||||
winstation->flags = flags;
|
||||
winstation->input_desktop = NULL;
|
||||
winstation->clipboard = NULL;
|
||||
winstation->atom_table = NULL;
|
||||
list_add_tail( &winstation_list, &winstation->entry );
|
||||
|
@ -211,6 +212,23 @@ struct winstation *get_process_winstation( struct process *process, unsigned int
|
|||
access, &winstation_ops );
|
||||
}
|
||||
|
||||
/* retrieve the winstation current input desktop */
|
||||
static struct desktop *get_input_desktop( struct winstation *winstation )
|
||||
{
|
||||
struct desktop *desktop;
|
||||
if (!(desktop = winstation->input_desktop)) return NULL;
|
||||
return (struct desktop *)grab_object( desktop );
|
||||
}
|
||||
|
||||
/* changes the winstation current input desktop and update its input time */
|
||||
static int set_input_desktop( struct winstation *winstation, struct desktop *new_desktop )
|
||||
{
|
||||
if (!(winstation->flags & WSF_VISIBLE)) return 0;
|
||||
if (new_desktop) new_desktop->input_time = current_time;
|
||||
winstation->input_desktop = new_desktop;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* retrieve a pointer to a desktop object */
|
||||
struct desktop *get_desktop_obj( struct process *process, obj_handle_t handle, unsigned int access )
|
||||
{
|
||||
|
@ -300,6 +318,15 @@ static int desktop_close_handle( struct object *obj, struct process *process, ob
|
|||
static void desktop_destroy( struct object *obj )
|
||||
{
|
||||
struct desktop *desktop = (struct desktop *)obj;
|
||||
struct winstation *winstation = desktop->winstation;
|
||||
|
||||
if (desktop == winstation->input_desktop)
|
||||
{
|
||||
struct desktop *other, *found = NULL;
|
||||
LIST_FOR_EACH_ENTRY(other, &winstation->desktops, struct desktop, entry)
|
||||
if (!found || other->input_time > found->input_time) found = other;
|
||||
set_input_desktop( winstation, found );
|
||||
}
|
||||
|
||||
free_hotkeys( desktop, 0 );
|
||||
if (desktop->top_window) free_window_handle( desktop->top_window );
|
||||
|
@ -561,6 +588,7 @@ DECL_HANDLER(create_desktop)
|
|||
{
|
||||
if ((desktop = create_desktop( &name, req->attributes, req->flags, winstation )))
|
||||
{
|
||||
if (!winstation->input_desktop) set_input_desktop( winstation, desktop );
|
||||
reply->handle = alloc_handle( current->process, desktop, req->access, req->attributes );
|
||||
release_object( desktop );
|
||||
}
|
||||
|
@ -608,7 +636,7 @@ DECL_HANDLER(open_input_desktop)
|
|||
return;
|
||||
}
|
||||
|
||||
if ((desktop = get_desktop_obj( current->process, current->process->desktop, 0 )))
|
||||
if ((desktop = get_input_desktop( winstation )))
|
||||
{
|
||||
reply->handle = alloc_handle( current->process, desktop, req->access, req->attributes );
|
||||
release_object( desktop );
|
||||
|
@ -616,6 +644,24 @@ DECL_HANDLER(open_input_desktop)
|
|||
release_object( winstation );
|
||||
}
|
||||
|
||||
/* changes the current input desktop */
|
||||
DECL_HANDLER(set_input_desktop)
|
||||
{
|
||||
/* FIXME: check access rights */
|
||||
struct winstation *winstation;
|
||||
struct desktop *desktop;
|
||||
|
||||
if (!(winstation = get_process_winstation( current->process, 0 ))) return;
|
||||
|
||||
if ((desktop = (struct desktop *)get_handle_obj( current->process, req->handle, 0, &desktop_ops )))
|
||||
{
|
||||
if (!set_input_desktop( winstation, desktop )) set_error( STATUS_ILLEGAL_FUNCTION );
|
||||
release_object( desktop );
|
||||
}
|
||||
|
||||
release_object( winstation );
|
||||
}
|
||||
|
||||
/* close a desktop */
|
||||
DECL_HANDLER(close_desktop)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue