Commit a09da0cb authored by Alexandre Julliard's avatar Alexandre Julliard

Added proper support for storing window parents in the server.

Added a few requests to query the window hierarchy.
parent 9c89290e
...@@ -1563,17 +1563,11 @@ struct get_named_pipe_info_request ...@@ -1563,17 +1563,11 @@ struct get_named_pipe_info_request
struct create_desktop_window_request
{
struct request_header __header;
user_handle_t handle;
};
struct create_window_request struct create_window_request
{ {
struct request_header __header; struct request_header __header;
user_handle_t parent;
user_handle_t owner;
user_handle_t handle; user_handle_t handle;
}; };
...@@ -1607,6 +1601,42 @@ struct get_window_info_request ...@@ -1607,6 +1601,42 @@ struct get_window_info_request
}; };
struct get_window_parents_request
{
struct request_header __header;
user_handle_t handle;
int count;
/* VARARG(parents,user_handles); */
};
struct get_window_children_request
{
struct request_header __header;
user_handle_t parent;
int count;
/* VARARG(parents,user_handles); */
};
struct get_window_tree_request
{
struct request_header __header;
user_handle_t handle;
user_handle_t parent;
user_handle_t owner;
user_handle_t next_sibling;
user_handle_t prev_sibling;
user_handle_t first_sibling;
user_handle_t last_sibling;
user_handle_t first_child;
user_handle_t last_child;
};
enum request enum request
{ {
REQ_new_process, REQ_new_process,
...@@ -1732,11 +1762,13 @@ enum request ...@@ -1732,11 +1762,13 @@ enum request
REQ_wait_named_pipe, REQ_wait_named_pipe,
REQ_disconnect_named_pipe, REQ_disconnect_named_pipe,
REQ_get_named_pipe_info, REQ_get_named_pipe_info,
REQ_create_desktop_window,
REQ_create_window, REQ_create_window,
REQ_link_window, REQ_link_window,
REQ_destroy_window, REQ_destroy_window,
REQ_get_window_info, REQ_get_window_info,
REQ_get_window_parents,
REQ_get_window_children,
REQ_get_window_tree,
REQ_NB_REQUESTS REQ_NB_REQUESTS
}; };
...@@ -1867,13 +1899,15 @@ union generic_request ...@@ -1867,13 +1899,15 @@ union generic_request
struct wait_named_pipe_request wait_named_pipe; struct wait_named_pipe_request wait_named_pipe;
struct disconnect_named_pipe_request disconnect_named_pipe; struct disconnect_named_pipe_request disconnect_named_pipe;
struct get_named_pipe_info_request get_named_pipe_info; struct get_named_pipe_info_request get_named_pipe_info;
struct create_desktop_window_request create_desktop_window;
struct create_window_request create_window; struct create_window_request create_window;
struct link_window_request link_window; struct link_window_request link_window;
struct destroy_window_request destroy_window; struct destroy_window_request destroy_window;
struct get_window_info_request get_window_info; struct get_window_info_request get_window_info;
struct get_window_parents_request get_window_parents;
struct get_window_children_request get_window_children;
struct get_window_tree_request get_window_tree;
}; };
#define SERVER_PROTOCOL_VERSION 52 #define SERVER_PROTOCOL_VERSION 53
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */ #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
...@@ -3602,8 +3602,8 @@ INT WINAPI GetUpdateRgn(HWND,HRGN,BOOL); ...@@ -3602,8 +3602,8 @@ INT WINAPI GetUpdateRgn(HWND,HRGN,BOOL);
BOOL WINAPI GetUserObjectInformationA(HANDLE,INT,LPVOID,DWORD,LPDWORD); BOOL WINAPI GetUserObjectInformationA(HANDLE,INT,LPVOID,DWORD,LPDWORD);
BOOL WINAPI GetUserObjectInformationW(HANDLE,INT,LPVOID,DWORD,LPDWORD); BOOL WINAPI GetUserObjectInformationW(HANDLE,INT,LPVOID,DWORD,LPDWORD);
#define GetUserObjectInformation WINELIB_NAME_AW(GetUserObjectInformation) #define GetUserObjectInformation WINELIB_NAME_AW(GetUserObjectInformation)
HWND WINAPI GetWindow(HWND,WORD); HWND WINAPI GetWindow(HWND,UINT);
HDC WINAPI GetWindowDC(HWND); HDC WINAPI GetWindowDC(HWND);
LONG WINAPI GetWindowLongA(HWND,INT); LONG WINAPI GetWindowLongA(HWND,INT);
LONG WINAPI GetWindowLongW(HWND,INT); LONG WINAPI GetWindowLongW(HWND,INT);
#define GetWindowLong WINELIB_NAME_AW(GetWindowLong) #define GetWindowLong WINELIB_NAME_AW(GetWindowLong)
......
...@@ -1395,17 +1395,12 @@ enum message_type ...@@ -1395,17 +1395,12 @@ enum message_type
@END @END
/* Create the desktop window */
@REQ(create_desktop_window)
@REPLY
user_handle_t handle; /* handle to the window */
@END
/* Create a window */ /* Create a window */
@REQ(create_window) @REQ(create_window)
user_handle_t parent; /* parent window */
user_handle_t owner; /* owner window */
@REPLY @REPLY
user_handle_t handle; /* handle to the window */ user_handle_t handle; /* created window */
@END @END
...@@ -1432,3 +1427,36 @@ enum message_type ...@@ -1432,3 +1427,36 @@ enum message_type
void* pid; /* process owning the window */ void* pid; /* process owning the window */
void* tid; /* thread owning the window */ void* tid; /* thread owning the window */
@END @END
/* Get a list of the window parents, up to the root of the tree */
@REQ(get_window_parents)
user_handle_t handle; /* handle to the window */
@REPLY
int count; /* total count of parents */
VARARG(parents,user_handles); /* parent handles */
@END
/* Get a list of the window children */
@REQ(get_window_children)
user_handle_t parent; /* parent window */
@REPLY
int count; /* total count of children */
VARARG(parents,user_handles); /* children handles */
@END
/* Get window tree information from a window handle */
@REQ(get_window_tree)
user_handle_t handle; /* handle to the window */
@REPLY
user_handle_t parent; /* parent window */
user_handle_t owner; /* owner window */
user_handle_t next_sibling; /* next sibling in Z-order */
user_handle_t prev_sibling; /* prev sibling in Z-order */
user_handle_t first_sibling; /* first sibling in Z-order */
user_handle_t last_sibling; /* last sibling in Z-order */
user_handle_t first_child; /* first child */
user_handle_t last_child; /* last child */
@END
...@@ -833,7 +833,7 @@ inline static struct message *find_matching_message( const struct message_list * ...@@ -833,7 +833,7 @@ inline static struct message *find_matching_message( const struct message_list *
{ {
/* check against the filters */ /* check against the filters */
if (msg->msg == WM_QUIT) break; /* WM_QUIT is never filtered */ if (msg->msg == WM_QUIT) break; /* WM_QUIT is never filtered */
if (win && msg->win && msg->win != win) continue; if (win && msg->win && msg->win != win && !is_child_window( win, msg->win )) continue;
if (msg->msg < first) continue; if (msg->msg < first) continue;
if (msg->msg > last) continue; if (msg->msg > last) continue;
break; /* found one */ break; /* found one */
......
...@@ -188,11 +188,13 @@ DECL_HANDLER(connect_named_pipe); ...@@ -188,11 +188,13 @@ DECL_HANDLER(connect_named_pipe);
DECL_HANDLER(wait_named_pipe); DECL_HANDLER(wait_named_pipe);
DECL_HANDLER(disconnect_named_pipe); DECL_HANDLER(disconnect_named_pipe);
DECL_HANDLER(get_named_pipe_info); DECL_HANDLER(get_named_pipe_info);
DECL_HANDLER(create_desktop_window);
DECL_HANDLER(create_window); DECL_HANDLER(create_window);
DECL_HANDLER(link_window); DECL_HANDLER(link_window);
DECL_HANDLER(destroy_window); DECL_HANDLER(destroy_window);
DECL_HANDLER(get_window_info); DECL_HANDLER(get_window_info);
DECL_HANDLER(get_window_parents);
DECL_HANDLER(get_window_children);
DECL_HANDLER(get_window_tree);
#ifdef WANT_REQUEST_HANDLERS #ifdef WANT_REQUEST_HANDLERS
...@@ -322,11 +324,13 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] = ...@@ -322,11 +324,13 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(req_handler)req_wait_named_pipe, (req_handler)req_wait_named_pipe,
(req_handler)req_disconnect_named_pipe, (req_handler)req_disconnect_named_pipe,
(req_handler)req_get_named_pipe_info, (req_handler)req_get_named_pipe_info,
(req_handler)req_create_desktop_window,
(req_handler)req_create_window, (req_handler)req_create_window,
(req_handler)req_link_window, (req_handler)req_link_window,
(req_handler)req_destroy_window, (req_handler)req_destroy_window,
(req_handler)req_get_window_info, (req_handler)req_get_window_info,
(req_handler)req_get_window_parents,
(req_handler)req_get_window_children,
(req_handler)req_get_window_tree,
}; };
#endif /* WANT_REQUEST_HANDLERS */ #endif /* WANT_REQUEST_HANDLERS */
......
...@@ -119,6 +119,21 @@ static size_t dump_varargs_ptrs( const void *req ) ...@@ -119,6 +119,21 @@ static size_t dump_varargs_ptrs( const void *req )
return get_size(req); return get_size(req);
} }
static size_t dump_varargs_user_handles( const void *req )
{
const user_handle_t *data = get_data(req);
size_t len = get_size(req) / sizeof(*data);
fputc( '{', stderr );
while (len > 0)
{
fprintf( stderr, "%08x", *data++ );
if (--len) fputc( ',', stderr );
}
fputc( '}', stderr );
return get_size(req);
}
static size_t dump_varargs_bytes( const void *req ) static size_t dump_varargs_bytes( const void *req )
{ {
const unsigned char *data = get_data(req); const unsigned char *data = get_data(req);
...@@ -1652,17 +1667,10 @@ static void dump_get_named_pipe_info_reply( const struct get_named_pipe_info_req ...@@ -1652,17 +1667,10 @@ static void dump_get_named_pipe_info_reply( const struct get_named_pipe_info_req
fprintf( stderr, " insize=%08x", req->insize ); fprintf( stderr, " insize=%08x", req->insize );
} }
static void dump_create_desktop_window_request( const struct create_desktop_window_request *req )
{
}
static void dump_create_desktop_window_reply( const struct create_desktop_window_request *req )
{
fprintf( stderr, " handle=%08x", req->handle );
}
static void dump_create_window_request( const struct create_window_request *req ) static void dump_create_window_request( const struct create_window_request *req )
{ {
fprintf( stderr, " parent=%08x,", req->parent );
fprintf( stderr, " owner=%08x", req->owner );
} }
static void dump_create_window_reply( const struct create_window_request *req ) static void dump_create_window_reply( const struct create_window_request *req )
...@@ -1694,6 +1702,47 @@ static void dump_get_window_info_reply( const struct get_window_info_request *re ...@@ -1694,6 +1702,47 @@ static void dump_get_window_info_reply( const struct get_window_info_request *re
fprintf( stderr, " tid=%p", req->tid ); fprintf( stderr, " tid=%p", req->tid );
} }
static void dump_get_window_parents_request( const struct get_window_parents_request *req )
{
fprintf( stderr, " handle=%08x", req->handle );
}
static void dump_get_window_parents_reply( const struct get_window_parents_request *req )
{
fprintf( stderr, " count=%d,", req->count );
fprintf( stderr, " parents=" );
cur_pos += dump_varargs_user_handles( req );
}
static void dump_get_window_children_request( const struct get_window_children_request *req )
{
fprintf( stderr, " parent=%08x", req->parent );
}
static void dump_get_window_children_reply( const struct get_window_children_request *req )
{
fprintf( stderr, " count=%d,", req->count );
fprintf( stderr, " parents=" );
cur_pos += dump_varargs_user_handles( req );
}
static void dump_get_window_tree_request( const struct get_window_tree_request *req )
{
fprintf( stderr, " handle=%08x", req->handle );
}
static void dump_get_window_tree_reply( const struct get_window_tree_request *req )
{
fprintf( stderr, " parent=%08x,", req->parent );
fprintf( stderr, " owner=%08x,", req->owner );
fprintf( stderr, " next_sibling=%08x,", req->next_sibling );
fprintf( stderr, " prev_sibling=%08x,", req->prev_sibling );
fprintf( stderr, " first_sibling=%08x,", req->first_sibling );
fprintf( stderr, " last_sibling=%08x,", req->last_sibling );
fprintf( stderr, " first_child=%08x,", req->first_child );
fprintf( stderr, " last_child=%08x", req->last_child );
}
static const dump_func req_dumpers[REQ_NB_REQUESTS] = { static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_new_process_request, (dump_func)dump_new_process_request,
(dump_func)dump_get_new_process_info_request, (dump_func)dump_get_new_process_info_request,
...@@ -1818,11 +1867,13 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = { ...@@ -1818,11 +1867,13 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_wait_named_pipe_request, (dump_func)dump_wait_named_pipe_request,
(dump_func)dump_disconnect_named_pipe_request, (dump_func)dump_disconnect_named_pipe_request,
(dump_func)dump_get_named_pipe_info_request, (dump_func)dump_get_named_pipe_info_request,
(dump_func)dump_create_desktop_window_request,
(dump_func)dump_create_window_request, (dump_func)dump_create_window_request,
(dump_func)dump_link_window_request, (dump_func)dump_link_window_request,
(dump_func)dump_destroy_window_request, (dump_func)dump_destroy_window_request,
(dump_func)dump_get_window_info_request, (dump_func)dump_get_window_info_request,
(dump_func)dump_get_window_parents_request,
(dump_func)dump_get_window_children_request,
(dump_func)dump_get_window_tree_request,
}; };
static const dump_func reply_dumpers[REQ_NB_REQUESTS] = { static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
...@@ -1949,11 +2000,13 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = { ...@@ -1949,11 +2000,13 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(dump_func)0, (dump_func)0,
(dump_func)0, (dump_func)0,
(dump_func)dump_get_named_pipe_info_reply, (dump_func)dump_get_named_pipe_info_reply,
(dump_func)dump_create_desktop_window_reply,
(dump_func)dump_create_window_reply, (dump_func)dump_create_window_reply,
(dump_func)0, (dump_func)0,
(dump_func)0, (dump_func)0,
(dump_func)dump_get_window_info_reply, (dump_func)dump_get_window_info_reply,
(dump_func)dump_get_window_parents_reply,
(dump_func)dump_get_window_children_reply,
(dump_func)dump_get_window_tree_reply,
}; };
static const char * const req_names[REQ_NB_REQUESTS] = { static const char * const req_names[REQ_NB_REQUESTS] = {
...@@ -2080,11 +2133,13 @@ static const char * const req_names[REQ_NB_REQUESTS] = { ...@@ -2080,11 +2133,13 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"wait_named_pipe", "wait_named_pipe",
"disconnect_named_pipe", "disconnect_named_pipe",
"get_named_pipe_info", "get_named_pipe_info",
"create_desktop_window",
"create_window", "create_window",
"link_window", "link_window",
"destroy_window", "destroy_window",
"get_window_info", "get_window_info",
"get_window_parents",
"get_window_children",
"get_window_tree",
}; };
/* ### make_requests end ### */ /* ### make_requests end ### */
......
...@@ -91,11 +91,7 @@ void *get_user_object( user_handle_t handle, enum user_object type ) ...@@ -91,11 +91,7 @@ void *get_user_object( user_handle_t handle, enum user_object type )
{ {
struct user_handle *entry; struct user_handle *entry;
if (!(entry = handle_to_entry( handle )) || entry->type != type) if (!(entry = handle_to_entry( handle )) || entry->type != type) return NULL;
{
set_error( STATUS_INVALID_HANDLE );
return NULL;
}
return entry->ptr; return entry->ptr;
} }
...@@ -114,11 +110,7 @@ void *get_user_object_handle( user_handle_t *handle, enum user_object type ) ...@@ -114,11 +110,7 @@ void *get_user_object_handle( user_handle_t *handle, enum user_object type )
{ {
struct user_handle *entry; struct user_handle *entry;
if (!(entry = handle_to_entry( *handle )) || entry->type != type) if (!(entry = handle_to_entry( *handle )) || entry->type != type) return NULL;
{
set_error( STATUS_INVALID_HANDLE );
return NULL;
}
*handle = entry_to_handle( entry ); *handle = entry_to_handle( entry );
return entry->ptr; return entry->ptr;
} }
......
...@@ -33,5 +33,6 @@ extern void queue_cleanup_window( struct thread *thread, user_handle_t win ); ...@@ -33,5 +33,6 @@ extern void queue_cleanup_window( struct thread *thread, user_handle_t win );
/* window functions */ /* window functions */
extern void destroy_thread_windows( struct thread *thread ); extern void destroy_thread_windows( struct thread *thread );
extern int is_child_window( user_handle_t parent, user_handle_t child );
#endif /* __WINE_SERVER_USER_H */ #endif /* __WINE_SERVER_USER_H */
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