From 4d32a475a8f730f5a5df7ecc4f1282f8f8a175df Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Fri, 25 Mar 2005 10:38:56 +0000 Subject: [PATCH] Replace the link_window request by a set_parent request since that is all link_window is used for at this point. Get rid of the WIN_LinkWindow/UnlinkWindow functions. --- dlls/user/user32.spec | 2 - dlls/x11drv/window.c | 38 ++++++++++------ include/win.h | 2 - include/wine/server_protocol.h | 38 ++++++++-------- server/protocol.def | 20 ++++---- server/request.h | 4 +- server/trace.c | 30 ++++++------ server/window.c | 58 ++++++++++++----------- windows/win.c | 101 ++++------------------------------------- 9 files changed, 112 insertions(+), 181 deletions(-) diff --git a/dlls/user/user32.spec b/dlls/user/user32.spec index 895238a9930..c9a6efb7074 100644 --- a/dlls/user/user32.spec +++ b/dlls/user/user32.spec @@ -732,6 +732,4 @@ @ cdecl WINPOS_GetMinMaxInfo(long ptr ptr ptr ptr) @ cdecl WINPOS_ShowIconTitle(long long) @ cdecl WIN_GetPtr(long) -@ cdecl WIN_LinkWindow(long long long) @ cdecl WIN_SetStyle(long long long) -@ cdecl WIN_UnlinkWindow(long) diff --git a/dlls/x11drv/window.c b/dlls/x11drv/window.c index f987d878b47..b4a7fe47892 100644 --- a/dlls/x11drv/window.c +++ b/dlls/x11drv/window.c @@ -39,8 +39,9 @@ #include "winuser.h" #include "wine/unicode.h" -#include "wine/debug.h" #include "x11drv.h" +#include "wine/debug.h" +#include "wine/server.h" #include "win.h" #include "winpos.h" #include "mwm.h" @@ -1003,11 +1004,7 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode ) else ret = (SendMessageA( hwnd, WM_CREATE, 0, (LPARAM)cs ) != -1); - if (!ret) - { - WIN_UnlinkWindow( hwnd ); - return FALSE; - } + if (!ret) return FALSE; NotifyWinEvent(EVENT_OBJECT_CREATE, hwnd, OBJID_WINDOW, 0); @@ -1127,22 +1124,37 @@ XIC X11DRV_get_ic( HWND hwnd ) HWND X11DRV_SetParent( HWND hwnd, HWND parent ) { Display *display = thread_display(); - HWND old_parent; + WND *wndPtr; + BOOL ret; + HWND old_parent = 0; /* Windows hides the window first, then shows it again * including the WM_SHOWWINDOW messages and all */ BOOL was_visible = ShowWindow( hwnd, SW_HIDE ); - if (!IsWindow( parent )) return 0; + wndPtr = WIN_GetPtr( hwnd ); + if (!wndPtr || wndPtr == WND_OTHER_PROCESS || wndPtr == WND_DESKTOP) return 0; - old_parent = GetAncestor( hwnd, GA_PARENT ); - if (parent != old_parent) + SERVER_START_REQ( set_parent ) { - struct x11drv_win_data *data; + req->handle = hwnd; + req->parent = parent; + if ((ret = !wine_server_call( req ))) + { + old_parent = reply->old_parent; + wndPtr->parent = parent = reply->full_parent; + } - if (!(data = X11DRV_get_win_data( hwnd ))) return 0; + } + SERVER_END_REQ; + WIN_ReleasePtr( wndPtr ); + if (!ret) return 0; + + if (parent != old_parent) + { + struct x11drv_win_data *data = X11DRV_get_win_data( hwnd ); - WIN_LinkWindow( hwnd, parent, HWND_TOP ); + if (!data) return 0; if (parent != GetDesktopWindow()) /* a child window */ { diff --git a/include/win.h b/include/win.h index b55b9f9f876..78954794ea3 100644 --- a/include/win.h +++ b/include/win.h @@ -77,8 +77,6 @@ extern WND *WIN_GetPtr( HWND hwnd ); extern HWND WIN_Handle32( HWND16 hwnd16 ); extern HWND WIN_IsCurrentProcess( HWND hwnd ); extern HWND WIN_IsCurrentThread( HWND hwnd ); -extern void WIN_LinkWindow( HWND hwnd, HWND parent, HWND hwndInsertAfter ); -extern void WIN_UnlinkWindow( HWND hwnd ); extern HWND WIN_SetOwner( HWND hwnd, HWND owner ); extern ULONG WIN_SetStyle( HWND hwnd, ULONG set_bits, ULONG clear_bits ); extern BOOL WIN_GetRectangles( HWND hwnd, RECT *rectWindow, RECT *rectClient ); diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index fa632e03160..747c05b5455 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -2435,21 +2435,6 @@ struct create_window_reply -struct link_window_request -{ - struct request_header __header; - user_handle_t handle; - user_handle_t parent; - user_handle_t previous; -}; -struct link_window_reply -{ - struct reply_header __header; - user_handle_t full_parent; -}; - - - struct destroy_window_request { struct request_header __header; @@ -2527,6 +2512,21 @@ struct set_window_info_reply +struct set_parent_request +{ + struct request_header __header; + user_handle_t handle; + user_handle_t parent; +}; +struct set_parent_reply +{ + struct reply_header __header; + user_handle_t old_parent; + user_handle_t full_parent; +}; + + + struct get_window_parents_request { struct request_header __header; @@ -3380,11 +3380,11 @@ enum request REQ_disconnect_named_pipe, REQ_get_named_pipe_info, REQ_create_window, - REQ_link_window, REQ_destroy_window, REQ_set_window_owner, REQ_get_window_info, REQ_set_window_info, + REQ_set_parent, REQ_get_window_parents, REQ_get_window_children, REQ_get_window_children_from_point, @@ -3572,11 +3572,11 @@ union generic_request struct disconnect_named_pipe_request disconnect_named_pipe_request; struct get_named_pipe_info_request get_named_pipe_info_request; struct create_window_request create_window_request; - struct link_window_request link_window_request; struct destroy_window_request destroy_window_request; struct set_window_owner_request set_window_owner_request; struct get_window_info_request get_window_info_request; struct set_window_info_request set_window_info_request; + struct set_parent_request set_parent_request; struct get_window_parents_request get_window_parents_request; struct get_window_children_request get_window_children_request; struct get_window_children_from_point_request get_window_children_from_point_request; @@ -3762,11 +3762,11 @@ union generic_reply struct disconnect_named_pipe_reply disconnect_named_pipe_reply; struct get_named_pipe_info_reply get_named_pipe_info_reply; struct create_window_reply create_window_reply; - struct link_window_reply link_window_reply; struct destroy_window_reply destroy_window_reply; struct set_window_owner_reply set_window_owner_reply; struct get_window_info_reply get_window_info_reply; struct set_window_info_reply set_window_info_reply; + struct set_parent_reply set_parent_reply; struct get_window_parents_reply get_window_parents_reply; struct get_window_children_reply get_window_children_reply; struct get_window_children_from_point_reply get_window_children_from_point_reply; @@ -3812,6 +3812,6 @@ union generic_reply struct duplicate_token_reply duplicate_token_reply; }; -#define SERVER_PROTOCOL_VERSION 163 +#define SERVER_PROTOCOL_VERSION 164 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/server/protocol.def b/server/protocol.def index b6553e24063..da7dfe85642 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -1718,16 +1718,6 @@ enum message_type @END -/* Link a window into the tree */ -@REQ(link_window) - user_handle_t handle; /* handle to the window */ - user_handle_t parent; /* handle to the parent */ - user_handle_t previous; /* previous child in Z-order */ -@REPLY - user_handle_t full_parent; /* full handle of new parent */ -@END - - /* Destroy a window */ @REQ(destroy_window) user_handle_t handle; /* handle to the window */ @@ -1784,6 +1774,16 @@ enum message_type #define SET_WIN_EXTRA 0x20 +/* Set the parent of a window */ +@REQ(set_parent) + user_handle_t handle; /* handle to the window */ + user_handle_t parent; /* handle to the parent */ +@REPLY + user_handle_t old_parent; /* old parent window */ + user_handle_t full_parent; /* full handle of new parent */ +@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 */ diff --git a/server/request.h b/server/request.h index 7ce7aa16c38..5c8ffe2e397 100644 --- a/server/request.h +++ b/server/request.h @@ -240,11 +240,11 @@ DECL_HANDLER(wait_named_pipe); DECL_HANDLER(disconnect_named_pipe); DECL_HANDLER(get_named_pipe_info); DECL_HANDLER(create_window); -DECL_HANDLER(link_window); DECL_HANDLER(destroy_window); DECL_HANDLER(set_window_owner); DECL_HANDLER(get_window_info); DECL_HANDLER(set_window_info); +DECL_HANDLER(set_parent); DECL_HANDLER(get_window_parents); DECL_HANDLER(get_window_children); DECL_HANDLER(get_window_children_from_point); @@ -431,11 +431,11 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] = (req_handler)req_disconnect_named_pipe, (req_handler)req_get_named_pipe_info, (req_handler)req_create_window, - (req_handler)req_link_window, (req_handler)req_destroy_window, (req_handler)req_set_window_owner, (req_handler)req_get_window_info, (req_handler)req_set_window_info, + (req_handler)req_set_parent, (req_handler)req_get_window_parents, (req_handler)req_get_window_children, (req_handler)req_get_window_children_from_point, diff --git a/server/trace.c b/server/trace.c index 738a1b8a92e..317d22d4520 100644 --- a/server/trace.c +++ b/server/trace.c @@ -2069,18 +2069,6 @@ static void dump_create_window_reply( const struct create_window_reply *req ) fprintf( stderr, " class_ptr=%p", req->class_ptr ); } -static void dump_link_window_request( const struct link_window_request *req ) -{ - fprintf( stderr, " handle=%p,", req->handle ); - fprintf( stderr, " parent=%p,", req->parent ); - fprintf( stderr, " previous=%p", req->previous ); -} - -static void dump_link_window_reply( const struct link_window_reply *req ) -{ - fprintf( stderr, " full_parent=%p", req->full_parent ); -} - static void dump_destroy_window_request( const struct destroy_window_request *req ) { fprintf( stderr, " handle=%p", req->handle ); @@ -2136,6 +2124,18 @@ static void dump_set_window_info_reply( const struct set_window_info_reply *req fprintf( stderr, " old_extra_value=%08x", req->old_extra_value ); } +static void dump_set_parent_request( const struct set_parent_request *req ) +{ + fprintf( stderr, " handle=%p,", req->handle ); + fprintf( stderr, " parent=%p", req->parent ); +} + +static void dump_set_parent_reply( const struct set_parent_reply *req ) +{ + fprintf( stderr, " old_parent=%p,", req->old_parent ); + fprintf( stderr, " full_parent=%p", req->full_parent ); +} + static void dump_get_window_parents_request( const struct get_window_parents_request *req ) { fprintf( stderr, " handle=%p", req->handle ); @@ -2834,11 +2834,11 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_disconnect_named_pipe_request, (dump_func)dump_get_named_pipe_info_request, (dump_func)dump_create_window_request, - (dump_func)dump_link_window_request, (dump_func)dump_destroy_window_request, (dump_func)dump_set_window_owner_request, (dump_func)dump_get_window_info_request, (dump_func)dump_set_window_info_request, + (dump_func)dump_set_parent_request, (dump_func)dump_get_window_parents_request, (dump_func)dump_get_window_children_request, (dump_func)dump_get_window_children_from_point_request, @@ -3022,11 +3022,11 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_disconnect_named_pipe_reply, (dump_func)dump_get_named_pipe_info_reply, (dump_func)dump_create_window_reply, - (dump_func)dump_link_window_reply, (dump_func)0, (dump_func)dump_set_window_owner_reply, (dump_func)dump_get_window_info_reply, (dump_func)dump_set_window_info_reply, + (dump_func)dump_set_parent_reply, (dump_func)dump_get_window_parents_reply, (dump_func)dump_get_window_children_reply, (dump_func)dump_get_window_children_from_point_reply, @@ -3210,11 +3210,11 @@ static const char * const req_names[REQ_NB_REQUESTS] = { "disconnect_named_pipe", "get_named_pipe_info", "create_window", - "link_window", "destroy_window", "set_window_owner", "get_window_info", "set_window_info", + "set_parent", "get_window_parents", "get_window_children", "get_window_children_from_point", diff --git a/server/window.c b/server/window.c index ae46dc9876d..ff8c3393448 100644 --- a/server/window.c +++ b/server/window.c @@ -111,21 +111,37 @@ inline static struct window *get_window( user_handle_t handle ) return ret; } -/* link a window into the tree (or unlink it if the new parent is NULL) */ -static void link_window( struct window *win, struct window *parent, struct window *previous ) +/* change the parent of a window (or unlink the window if the new parent is NULL) */ +static int set_parent_window( struct window *win, struct window *parent ) { + struct window *ptr; + + /* make sure parent is not a child of window */ + for (ptr = parent; ptr; ptr = ptr->parent) + { + if (ptr == win) + { + set_error( STATUS_INVALID_PARAMETER ); + return 0; + } + } + list_remove( &win->entry ); /* unlink it from the previous location */ if (parent) { win->parent = parent; - if (previous) list_add_after( &previous->entry, &win->entry ); - else list_add_head( &parent->children, &win->entry ); + list_add_head( &parent->children, &win->entry ); + + /* if parent belongs to a different thread, attach the two threads */ + if (parent->thread && parent->thread != win->thread) + attach_thread_input( win->thread, parent->thread ); } else /* move it to parent unlinked list */ { list_add_head( &win->parent->unlinked, &win->entry ); } + return 1; } /* get next window in Z-order list */ @@ -1094,7 +1110,12 @@ static void set_window_pos( struct window *win, struct window *previous, win->window_rect = *window_rect; win->visible_rect = *visible_rect; win->client_rect = *client_rect; - if (!(swp_flags & SWP_NOZORDER)) link_window( win, win->parent, previous ); + if (!(swp_flags & SWP_NOZORDER) && win->parent) + { + list_remove( &win->entry ); /* unlink it from the previous location */ + if (previous) list_add_after( &previous->entry, &win->entry ); + else list_add_head( &win->parent->children, &win->entry ); + } if (swp_flags & SWP_SHOWWINDOW) win->style |= WS_VISIBLE; else if (swp_flags & SWP_HIDEWINDOW) win->style &= ~WS_VISIBLE; @@ -1198,10 +1219,10 @@ DECL_HANDLER(create_window) } -/* link a window into the tree */ -DECL_HANDLER(link_window) +/* set the parent of a window */ +DECL_HANDLER(set_parent) { - struct window *win, *parent = NULL, *previous = NULL; + struct window *win, *parent = NULL; if (!(win = get_window( req->handle ))) return; if (req->parent && !(parent = get_window( req->parent ))) return; @@ -1211,26 +1232,9 @@ DECL_HANDLER(link_window) set_error( STATUS_INVALID_PARAMETER ); return; } + reply->old_parent = win->parent->handle; reply->full_parent = parent ? parent->handle : 0; - if (parent && req->previous) - { - if (req->previous == (user_handle_t)1) /* special case: HWND_BOTTOM */ - { - previous = get_last_child( parent ); - if (previous == win) return; /* nothing to do */ - } - else - { - if (!(previous = get_window( req->previous ))) return; - /* previous must be a child of parent, and not win itself */ - if (previous->parent != parent || previous == win) - { - set_error( STATUS_INVALID_PARAMETER ); - return; - } - } - } - link_window( win, parent, previous ); + set_parent_window( win, parent ); } diff --git a/windows/win.c b/windows/win.c index 0405749080b..f3a2dca9666 100644 --- a/windows/win.c +++ b/windows/win.c @@ -395,52 +395,6 @@ HWND WIN_Handle32( HWND16 hwnd16 ) /*********************************************************************** - * WIN_UnlinkWindow - * - * Remove a window from the siblings linked list. - */ -void WIN_UnlinkWindow( HWND hwnd ) -{ - WIN_LinkWindow( hwnd, 0, 0 ); -} - - -/*********************************************************************** - * WIN_LinkWindow - * - * Insert a window into the siblings linked list. - * The window is inserted after the specified window, which can also - * be specified as HWND_TOP or HWND_BOTTOM. - * If parent is 0, window is unlinked from the tree. - */ -void WIN_LinkWindow( HWND hwnd, HWND parent, HWND hwndInsertAfter ) -{ - WND *wndPtr = WIN_GetPtr( hwnd ); - - if (!wndPtr || wndPtr == WND_DESKTOP) return; - if (wndPtr == WND_OTHER_PROCESS) - { - if (IsWindow(hwnd)) ERR(" cannot link other process window %p\n", hwnd ); - return; - } - - SERVER_START_REQ( link_window ) - { - req->handle = hwnd; - req->parent = parent; - req->previous = hwndInsertAfter; - if (!wine_server_call( req )) - { - if (reply->full_parent) wndPtr->parent = reply->full_parent; - } - - } - SERVER_END_REQ; - WIN_ReleasePtr( wndPtr ); -} - - -/*********************************************************************** * WIN_SetOwner * * Change the owner of a window. @@ -584,12 +538,6 @@ LRESULT WIN_DestroyWindow( HWND hwnd ) TRACE("%p\n", hwnd ); - if (!(hwnd = WIN_IsCurrentThread( hwnd ))) - { - ERR( "window doesn't belong to current thread\n" ); - return 0; - } - /* free child windows */ if ((list = WIN_ListChildren( hwnd ))) { @@ -603,7 +551,13 @@ LRESULT WIN_DestroyWindow( HWND hwnd ) } /* Unlink now so we won't bother with the children later on */ - WIN_UnlinkWindow( hwnd ); + SERVER_START_REQ( set_parent ) + { + req->handle = hwnd; + req->parent = 0; + wine_server_call( req ); + } + SERVER_END_REQ; /* * Send the WM_NCDESTROY to the window being destroyed. @@ -2556,9 +2510,7 @@ HWND WINAPI GetAncestor( HWND hwnd, UINT type ) */ HWND WINAPI SetParent( HWND hwnd, HWND parent ) { - WND *wndPtr; - HWND retvalue, full_handle; - BOOL was_visible; + HWND full_handle; if (is_broadcast(hwnd) || is_broadcast(parent)) { @@ -2585,43 +2537,10 @@ HWND WINAPI SetParent( HWND hwnd, HWND parent ) if (!(full_handle = WIN_IsCurrentThread( hwnd ))) return (HWND)SendMessageW( hwnd, WM_WINE_SETPARENT, (WPARAM)parent, 0 ); - hwnd = full_handle; - if (USER_Driver.pSetParent) - return USER_Driver.pSetParent( hwnd, parent ); + return USER_Driver.pSetParent( full_handle, parent ); - /* Windows hides the window first, then shows it again - * including the WM_SHOWWINDOW messages and all */ - was_visible = ShowWindow( hwnd, SW_HIDE ); - - if (!IsWindow( parent )) return 0; - if (!(wndPtr = WIN_GetPtr(hwnd)) || wndPtr == WND_OTHER_PROCESS || wndPtr == WND_DESKTOP) return 0; - - retvalue = wndPtr->parent; /* old parent */ - if (parent != retvalue) - { - WIN_LinkWindow( hwnd, parent, HWND_TOP ); - - if (parent != GetDesktopWindow()) /* a child window */ - { - if (!(wndPtr->dwStyle & WS_CHILD)) - { - HMENU menu = (HMENU)SetWindowLongPtrW( hwnd, GWLP_ID, 0 ); - if (menu) DestroyMenu( menu ); - } - } - } - WIN_ReleasePtr( wndPtr ); - - /* SetParent additionally needs to make hwnd the topmost window - in the x-order and send the expected WM_WINDOWPOSCHANGING and - WM_WINDOWPOSCHANGED notification messages. - */ - SetWindowPos( hwnd, HWND_TOPMOST, 0, 0, 0, 0, - SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | (was_visible ? SWP_SHOWWINDOW : 0) ); - /* FIXME: a WM_MOVE is also generated (in the DefWindowProc handler - * for WM_WINDOWPOSCHANGED) in Windows, should probably remove SWP_NOMOVE */ - return retvalue; + return 0; } -- 2.11.4.GIT