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
struct create_desktop_window_request
{
struct request_header __header;
user_handle_t handle;
};
struct create_window_request
{
struct request_header __header;
user_handle_t parent;
user_handle_t owner;
user_handle_t handle;
};
......@@ -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
{
REQ_new_process,
......@@ -1732,11 +1762,13 @@ enum request
REQ_wait_named_pipe,
REQ_disconnect_named_pipe,
REQ_get_named_pipe_info,
REQ_create_desktop_window,
REQ_create_window,
REQ_link_window,
REQ_destroy_window,
REQ_get_window_info,
REQ_get_window_parents,
REQ_get_window_children,
REQ_get_window_tree,
REQ_NB_REQUESTS
};
......@@ -1867,13 +1899,15 @@ union generic_request
struct wait_named_pipe_request wait_named_pipe;
struct disconnect_named_pipe_request disconnect_named_pipe;
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 link_window_request link_window;
struct destroy_window_request destroy_window;
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 */
......@@ -3602,8 +3602,8 @@ INT WINAPI GetUpdateRgn(HWND,HRGN,BOOL);
BOOL WINAPI GetUserObjectInformationA(HANDLE,INT,LPVOID,DWORD,LPDWORD);
BOOL WINAPI GetUserObjectInformationW(HANDLE,INT,LPVOID,DWORD,LPDWORD);
#define GetUserObjectInformation WINELIB_NAME_AW(GetUserObjectInformation)
HWND WINAPI GetWindow(HWND,WORD);
HDC WINAPI GetWindowDC(HWND);
HWND WINAPI GetWindow(HWND,UINT);
HDC WINAPI GetWindowDC(HWND);
LONG WINAPI GetWindowLongA(HWND,INT);
LONG WINAPI GetWindowLongW(HWND,INT);
#define GetWindowLong WINELIB_NAME_AW(GetWindowLong)
......
......@@ -1395,17 +1395,12 @@ enum message_type
@END
/* Create the desktop window */
@REQ(create_desktop_window)
@REPLY
user_handle_t handle; /* handle to the window */
@END
/* Create a window */
@REQ(create_window)
user_handle_t parent; /* parent window */
user_handle_t owner; /* owner window */
@REPLY
user_handle_t handle; /* handle to the window */
user_handle_t handle; /* created window */
@END
......@@ -1432,3 +1427,36 @@ enum message_type
void* pid; /* process owning the window */
void* tid; /* thread owning the window */
@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 *
{
/* check against the filters */
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 > last) continue;
break; /* found one */
......
......@@ -188,11 +188,13 @@ DECL_HANDLER(connect_named_pipe);
DECL_HANDLER(wait_named_pipe);
DECL_HANDLER(disconnect_named_pipe);
DECL_HANDLER(get_named_pipe_info);
DECL_HANDLER(create_desktop_window);
DECL_HANDLER(create_window);
DECL_HANDLER(link_window);
DECL_HANDLER(destroy_window);
DECL_HANDLER(get_window_info);
DECL_HANDLER(get_window_parents);
DECL_HANDLER(get_window_children);
DECL_HANDLER(get_window_tree);
#ifdef WANT_REQUEST_HANDLERS
......@@ -322,11 +324,13 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(req_handler)req_wait_named_pipe,
(req_handler)req_disconnect_named_pipe,
(req_handler)req_get_named_pipe_info,
(req_handler)req_create_desktop_window,
(req_handler)req_create_window,
(req_handler)req_link_window,
(req_handler)req_destroy_window,
(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 */
......
......@@ -119,6 +119,21 @@ static size_t dump_varargs_ptrs( const void *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 )
{
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
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 )
{
fprintf( stderr, " parent=%08x,", req->parent );
fprintf( stderr, " owner=%08x", req->owner );
}
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
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] = {
(dump_func)dump_new_process_request,
(dump_func)dump_get_new_process_info_request,
......@@ -1818,11 +1867,13 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_wait_named_pipe_request,
(dump_func)dump_disconnect_named_pipe_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_link_window_request,
(dump_func)dump_destroy_window_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] = {
......@@ -1949,11 +2000,13 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(dump_func)0,
(dump_func)0,
(dump_func)dump_get_named_pipe_info_reply,
(dump_func)dump_create_desktop_window_reply,
(dump_func)dump_create_window_reply,
(dump_func)0,
(dump_func)0,
(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] = {
......@@ -2080,11 +2133,13 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"wait_named_pipe",
"disconnect_named_pipe",
"get_named_pipe_info",
"create_desktop_window",
"create_window",
"link_window",
"destroy_window",
"get_window_info",
"get_window_parents",
"get_window_children",
"get_window_tree",
};
/* ### make_requests end ### */
......
......@@ -91,11 +91,7 @@ void *get_user_object( user_handle_t handle, enum user_object type )
{
struct user_handle *entry;
if (!(entry = handle_to_entry( handle )) || entry->type != type)
{
set_error( STATUS_INVALID_HANDLE );
return NULL;
}
if (!(entry = handle_to_entry( handle )) || entry->type != type) return NULL;
return entry->ptr;
}
......@@ -114,11 +110,7 @@ void *get_user_object_handle( user_handle_t *handle, enum user_object type )
{
struct user_handle *entry;
if (!(entry = handle_to_entry( *handle )) || entry->type != type)
{
set_error( STATUS_INVALID_HANDLE );
return NULL;
}
if (!(entry = handle_to_entry( *handle )) || entry->type != type) return NULL;
*handle = entry_to_handle( entry );
return entry->ptr;
}
......
......@@ -33,5 +33,6 @@ extern void queue_cleanup_window( struct thread *thread, user_handle_t win );
/* window functions */
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 */
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