Commit 4ef69e2b authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

win32u: Move NtUserGetAncestor implementation from user32.

parent 5da6282a
......@@ -496,7 +496,7 @@ static LRESULT DEFWND_DefWinProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPa
if( wParam == VK_F4 ) /* try to close the window */
{
HWND top = GetAncestor( hwnd, GA_ROOT );
HWND top = NtUserGetAncestor( hwnd, GA_ROOT );
if (!(GetClassLongW( top, GCL_STYLE ) & CS_NOCLOSE))
PostMessageW( top, WM_SYSCOMMAND, SC_CLOSE, 0 );
}
......@@ -516,7 +516,7 @@ static LRESULT DEFWND_DefWinProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPa
/* Press and release F10 or ALT */
if (((wParam == VK_MENU || wParam == VK_LMENU || wParam == VK_RMENU)
&& iMenuSysKey) || ((wParam == VK_F10) && iF10Key))
SendMessageW( GetAncestor( hwnd, GA_ROOT ), WM_SYSCOMMAND, SC_KEYMENU, 0L );
SendMessageW( NtUserGetAncestor( hwnd, GA_ROOT ), WM_SYSCOMMAND, SC_KEYMENU, 0L );
iMenuSysKey = iF10Key = 0;
break;
......
......@@ -104,7 +104,7 @@ LRESULT WINAPI DesktopWndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lP
ATOM atom;
WCHAR buffer[37];
if (GetAncestor( hwnd, GA_PARENT )) return FALSE; /* refuse to create non-desktop window */
if (NtUserGetAncestor( hwnd, GA_PARENT )) return FALSE; /* refuse to create non-desktop window */
swprintf( buffer, ARRAY_SIZE(buffer), L"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
guid->Data1, guid->Data2, guid->Data3,
......
......@@ -131,7 +131,7 @@ static void CDECL nulldrv_UpdateClipboard(void)
static BOOL CDECL nodrv_CreateWindow( HWND hwnd )
{
static int warned;
HWND parent = GetAncestor( hwnd, GA_PARENT );
HWND parent = NtUserGetAncestor( hwnd, GA_PARENT );
/* HWND_MESSAGE windows don't need a graphics driver */
if (!parent || parent == get_user_thread_info()->msg_window) return TRUE;
......
......@@ -165,7 +165,7 @@ static BOOL set_active_window( HWND hwnd, HWND *prev, BOOL mouse, BOOL focus )
SendMessageW( hwnd, WM_ACTIVATE,
MAKEWPARAM( mouse ? WA_CLICKACTIVE : WA_ACTIVE, IsIconic(hwnd) ),
(LPARAM)previous );
if (GetAncestor( hwnd, GA_PARENT ) == GetDesktopWindow())
if (NtUserGetAncestor( hwnd, GA_PARENT ) == GetDesktopWindow())
PostMessageW( GetDesktopWindow(), WM_PARENTNOTIFY, WM_NCACTIVATE, (LPARAM)hwnd );
}
......@@ -179,7 +179,7 @@ static BOOL set_active_window( HWND hwnd, HWND *prev, BOOL mouse, BOOL focus )
/* Do not change focus if the window is no more active */
if (hwnd == info.hwndActive)
{
if (!info.hwndFocus || !hwnd || GetAncestor( info.hwndFocus, GA_ROOT ) != hwnd)
if (!info.hwndFocus || !hwnd || NtUserGetAncestor( info.hwndFocus, GA_ROOT ) != hwnd)
set_focus_window( hwnd );
}
}
......@@ -291,7 +291,7 @@ HWND WINAPI SetFocus( HWND hwnd )
LONG style = GetWindowLongW( hwndTop, GWL_STYLE );
if (style & (WS_MINIMIZE | WS_DISABLED)) return 0;
if (!(style & WS_CHILD)) break;
parent = GetAncestor( hwndTop, GA_PARENT );
parent = NtUserGetAncestor( hwndTop, GA_PARENT );
if (!parent || parent == GetDesktopWindow())
{
if ((style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return 0;
......
......@@ -3436,7 +3436,7 @@ void MENU_TrackKbdMenuBar( HWND hwnd, UINT wParam, WCHAR wChar)
/* find window that has a menu */
while (is_win_menu_disallowed(hwnd))
if (!(hwnd = GetAncestor( hwnd, GA_PARENT ))) return;
if (!(hwnd = NtUserGetAncestor( hwnd, GA_PARENT ))) return;
/* check if we have to track a system menu */
......
......@@ -2552,7 +2552,7 @@ static BOOL process_mouse_message( MSG *msg, UINT hw_id, ULONG_PTR extra_info, H
if (msg->hwnd != info.hwndActive)
{
HWND hwndTop = GetAncestor( msg->hwnd, GA_ROOT );
HWND hwndTop = NtUserGetAncestor( msg->hwnd, GA_ROOT );
if ((GetWindowLongW( hwndTop, GWL_STYLE ) & (WS_POPUP|WS_CHILD)) != WS_CHILD)
{
......
......@@ -1083,7 +1083,7 @@ static void NC_DoNCPaint( HWND hwnd, HRGN clip )
*/
LRESULT NC_HandleNCPaint( HWND hwnd , HRGN clip)
{
HWND parent = GetAncestor( hwnd, GA_PARENT );
HWND parent = NtUserGetAncestor( hwnd, GA_PARENT );
DWORD dwStyle = GetWindowLongW( hwnd, GWL_STYLE );
if( dwStyle & WS_VISIBLE )
......@@ -1119,7 +1119,7 @@ LRESULT NC_HandleNCActivate( HWND hwnd, WPARAM wParam, LPARAM lParam )
{
NC_DoNCPaint( hwnd, (HRGN)1 );
if (GetAncestor( hwnd, GA_PARENT ) == GetDesktopWindow())
if (NtUserGetAncestor( hwnd, GA_PARENT ) == GetDesktopWindow())
PostMessageW( GetDesktopWindow(), WM_PARENTNOTIFY, WM_NCACTIVATE, (LPARAM)hwnd );
}
......@@ -1379,7 +1379,7 @@ LRESULT NC_HandleNCLButtonDown( HWND hwnd, WPARAM wParam, LPARAM lParam )
{
if ((GetWindowLongW( top, GWL_STYLE ) & (WS_POPUP|WS_CHILD)) != WS_CHILD)
break;
parent = GetAncestor( top, GA_PARENT );
parent = NtUserGetAncestor( top, GA_PARENT );
if (!parent || parent == GetDesktopWindow()) break;
top = parent;
}
......
......@@ -841,7 +841,7 @@ void move_window_bits_parent( HWND hwnd, HWND parent, const RECT *window_rect, c
}
TRACE( "copying %s -> %s\n", wine_dbgstr_rect( &src ), wine_dbgstr_rect( &dst ));
MapWindowPoints( GetAncestor( hwnd, GA_PARENT ), parent, (POINT *)&src, 2 );
MapWindowPoints( NtUserGetAncestor( hwnd, GA_PARENT ), parent, (POINT *)&src, 2 );
OffsetRect( &src, win->client_rect.left - win->visible_rect.left,
win->client_rect.top - win->visible_rect.top );
OffsetRect( &dst, -window_rect->left, -window_rect->top );
......@@ -1018,7 +1018,7 @@ HDC WINAPI GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags )
if (flags & DCX_WINDOW) flags &= ~DCX_CLIPCHILDREN;
parent = GetAncestor( hwnd, GA_PARENT );
parent = NtUserGetAncestor( hwnd, GA_PARENT );
if (!parent || (parent == GetDesktopWindow()))
flags = (flags & ~DCX_PARENTCLIP) | DCX_CLIPSIBLINGS;
......
......@@ -252,7 +252,7 @@
@ stdcall GetAltTabInfo(long long ptr ptr long) GetAltTabInfoA
@ stdcall GetAltTabInfoA(long long ptr ptr long)
@ stdcall GetAltTabInfoW(long long ptr ptr long)
@ stdcall GetAncestor(long long)
@ stdcall GetAncestor(long long) NtUserGetAncestor
@ stdcall GetAppCompatFlags(long)
@ stdcall GetAppCompatFlags2(long)
@ stdcall -import GetAsyncKeyState(long) NtUserGetAsyncKeyState
......
......@@ -2558,7 +2558,7 @@ LONG_PTR WIN_SetWindowLong( HWND hwnd, INT offset, UINT size, LONG_PTR newval, B
/* FIXME: move to win32u */
static ULONG_PTR get_hwnd_parent( HWND hwnd )
{
HWND parent = GetAncestor( hwnd, GA_PARENT );
HWND parent = NtUserGetAncestor( hwnd, GA_PARENT );
if (parent == GetDesktopWindow()) parent = GetWindow( hwnd, GW_OWNER );
return (ULONG_PTR)parent;
}
......@@ -2913,67 +2913,6 @@ HWND WINAPI GetParent( HWND hwnd )
/*****************************************************************
* GetAncestor (USER32.@)
*/
HWND WINAPI GetAncestor( HWND hwnd, UINT type )
{
WND *win;
HWND *list, ret = 0;
switch(type)
{
case GA_PARENT:
if (!(win = WIN_GetPtr( hwnd )))
{
SetLastError( ERROR_INVALID_WINDOW_HANDLE );
return 0;
}
if (win == WND_DESKTOP) return 0;
if (win != WND_OTHER_PROCESS)
{
ret = win->parent;
WIN_ReleasePtr( win );
}
else /* need to query the server */
{
SERVER_START_REQ( get_window_tree )
{
req->handle = wine_server_user_handle( hwnd );
if (!wine_server_call_err( req )) ret = wine_server_ptr_handle( reply->parent );
}
SERVER_END_REQ;
}
break;
case GA_ROOT:
if (!(list = list_window_parents( hwnd ))) return 0;
if (!list[0] || !list[1]) ret = WIN_GetFullHandle( hwnd ); /* top-level window */
else
{
int count = 2;
while (list[count]) count++;
ret = list[count - 2]; /* get the one before the desktop */
}
HeapFree( GetProcessHeap(), 0, list );
break;
case GA_ROOTOWNER:
if (is_desktop_window( hwnd )) return 0;
ret = WIN_GetFullHandle( hwnd );
for (;;)
{
HWND parent = GetParent( ret );
if (!parent) break;
ret = parent;
}
break;
}
return ret;
}
/*****************************************************************
* SetParent (USER32.@)
*/
HWND WINAPI SetParent( HWND hwnd, HWND parent )
......
......@@ -727,7 +727,7 @@ MINMAXINFO WINPOS_GetMinMaxInfo( HWND hwnd )
else
adjustedStyle = style;
GetClientRect(GetAncestor(hwnd,GA_PARENT), &rc);
GetClientRect(NtUserGetAncestor(hwnd,GA_PARENT), &rc);
AdjustWindowRectEx(&rc, adjustedStyle, ((style & WS_POPUP) && GetMenu(hwnd)), exstyle);
xinc = -rc.left;
......@@ -870,7 +870,7 @@ static POINT get_minimized_pos( HWND hwnd, POINT pt )
MINIMIZEDMETRICS metrics;
int width, height;
parent = GetAncestor( hwnd, GA_PARENT );
parent = NtUserGetAncestor( hwnd, GA_PARENT );
if (parent == GetDesktopWindow())
{
MONITORINFO mon_info;
......@@ -974,7 +974,7 @@ UINT WINPOS_MinMaximize( HWND hwnd, UINT cmd, LPRECT rect )
if (GetFocus() == hwnd)
{
if (GetWindowLongW(hwnd, GWL_STYLE) & WS_CHILD)
SetFocus(GetAncestor(hwnd, GA_PARENT));
SetFocus(NtUserGetAncestor(hwnd, GA_PARENT));
else
SetFocus(0);
}
......@@ -1139,7 +1139,7 @@ static BOOL show_window( HWND hwnd, INT cmd )
}
swp = new_swp;
parent = GetAncestor( hwnd, GA_PARENT );
parent = NtUserGetAncestor( hwnd, GA_PARENT );
if (parent && !IsWindowVisible( parent ) && !(swp & SWP_STATECHANGED))
{
/* if parent is not visible simply toggle WS_VISIBLE and return */
......@@ -1166,7 +1166,7 @@ static BOOL show_window( HWND hwnd, INT cmd )
hFocus = GetFocus();
if (hwnd == hFocus)
{
HWND parent = GetAncestor(hwnd, GA_PARENT);
HWND parent = NtUserGetAncestor(hwnd, GA_PARENT);
if (parent == GetDesktopWindow()) parent = 0;
SetFocus(parent);
}
......@@ -1203,7 +1203,7 @@ static BOOL show_window( HWND hwnd, INT cmd )
{
SetFocus( hwnd );
/* Send a WM_ACTIVATE message for a top level window, even if the window is already active */
if (GetAncestor( hwnd, GA_ROOT ) == hwnd && !(swp & SWP_NOACTIVATE))
if (NtUserGetAncestor( hwnd, GA_ROOT ) == hwnd && !(swp & SWP_NOACTIVATE))
SendMessageW( hwnd, WM_ACTIVATE, WA_ACTIVE, 0 );
}
......@@ -1616,7 +1616,7 @@ void WINPOS_ActivateOtherWindow(HWND hwnd)
if ((GetWindowLongW( hwnd, GWL_STYLE ) & WS_POPUP) && (hwndTo = GetWindow( hwnd, GW_OWNER )))
{
hwndTo = GetAncestor( hwndTo, GA_ROOT );
hwndTo = NtUserGetAncestor( hwndTo, GA_ROOT );
if (can_activate_window( hwndTo )) goto done;
}
......@@ -2037,7 +2037,7 @@ static BOOL fixup_flags( WINDOWPOS *winpos, const RECT *old_window_rect, int par
if (winpos->cy < 0) winpos->cy = 0;
else if (winpos->cy > 32767) winpos->cy = 32767;
parent = GetAncestor( winpos->hwnd, GA_PARENT );
parent = NtUserGetAncestor( winpos->hwnd, GA_PARENT );
if (!IsWindowVisible( parent )) winpos->flags |= SWP_NOREDRAW;
if (wndPtr->dwStyle & WS_VISIBLE) winpos->flags &= ~SWP_SHOWWINDOW;
......@@ -2160,7 +2160,7 @@ BOOL set_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags,
const RECT *window_rect, const RECT *client_rect, const RECT *valid_rects )
{
WND *win;
HWND surface_win = 0, parent = GetAncestor( hwnd, GA_PARENT );
HWND surface_win = 0, parent = NtUserGetAncestor( hwnd, GA_PARENT );
BOOL ret, needs_update = FALSE;
RECT visible_rect, old_visible_rect, old_window_rect, old_client_rect, extra_rects[3];
struct window_surface *old_surface, *new_surface = NULL;
......@@ -2352,8 +2352,8 @@ BOOL USER_SetWindowPos( WINDOWPOS * winpos, int parent_x, int parent_y )
winpos->hwndInsertAfter == HWND_TOPMOST ||
winpos->hwndInsertAfter == HWND_NOTOPMOST))
{
HWND parent = GetAncestor( winpos->hwnd, GA_PARENT );
HWND insertafter_parent = GetAncestor( winpos->hwndInsertAfter, GA_PARENT );
HWND parent = NtUserGetAncestor( winpos->hwnd, GA_PARENT );
HWND insertafter_parent = NtUserGetAncestor( winpos->hwndInsertAfter, GA_PARENT );
/* hwndInsertAfter must be a sibling of the window */
if (!insertafter_parent) return FALSE;
......@@ -2387,7 +2387,7 @@ BOOL USER_SetWindowPos( WINDOWPOS * winpos, int parent_x, int parent_y )
if((winpos->flags & (SWP_NOZORDER | SWP_HIDEWINDOW | SWP_SHOWWINDOW)) != SWP_NOZORDER)
{
if (GetAncestor( winpos->hwnd, GA_PARENT ) == GetDesktopWindow())
if (NtUserGetAncestor( winpos->hwnd, GA_PARENT ) == GetDesktopWindow())
winpos->hwndInsertAfter = SWP_DoOwnedPopups( winpos->hwnd, winpos->hwndInsertAfter );
}
......@@ -2422,7 +2422,7 @@ BOOL USER_SetWindowPos( WINDOWPOS * winpos, int parent_x, int parent_y )
(!(orig_flags & SWP_SHOWWINDOW) &&
(winpos->flags & SWP_AGG_STATUSFLAGS) != SWP_AGG_NOGEOMETRYCHANGE))
{
HWND parent = GetAncestor( winpos->hwnd, GA_PARENT );
HWND parent = NtUserGetAncestor( winpos->hwnd, GA_PARENT );
if (!parent || parent == GetDesktopWindow()) parent = winpos->hwnd;
erase_now( parent, 0 );
}
......
......@@ -112,6 +112,7 @@ static void * const syscalls[] =
NtUserCreateWindowStation,
NtUserDestroyAcceleratorTable,
NtUserFindExistingCursorIcon,
NtUserGetAncestor,
NtUserGetAtomName,
NtUserGetClassName,
NtUserGetClipboardFormatName,
......
......@@ -889,7 +889,7 @@
@ stub NtUserFunctionalizeDisplayConfig
@ stub NtUserGetActiveProcessesDpis
@ stub NtUserGetAltTabInfo
@ stub NtUserGetAncestor
@ stdcall -syscall NtUserGetAncestor(long long)
@ stub NtUserGetAppImeLevel
@ stdcall NtUserGetAsyncKeyState(long)
@ stdcall -syscall NtUserGetAtomName(long ptr)
......
......@@ -454,6 +454,135 @@ static HWND get_window_relative( HWND hwnd, UINT rel )
return retval;
}
/*******************************************************************
* list_window_parents
*
* Build an array of all parents of a given window, starting with
* the immediate parent. The array must be freed with free().
*/
static HWND *list_window_parents( HWND hwnd )
{
WND *win;
HWND current, *list;
int i, pos = 0, size = 16, count;
if (!(list = malloc( size * sizeof(HWND) ))) return NULL;
current = hwnd;
for (;;)
{
if (!(win = get_win_ptr( current ))) goto empty;
if (win == WND_OTHER_PROCESS) break; /* need to do it the hard way */
if (win == WND_DESKTOP)
{
if (!pos) goto empty;
list[pos] = 0;
return list;
}
list[pos] = current = win->parent;
release_win_ptr( win );
if (!current) return list;
if (++pos == size - 1)
{
/* need to grow the list */
HWND *new_list = realloc( list, (size + 16) * sizeof(HWND) );
if (!new_list) goto empty;
list = new_list;
size += 16;
}
}
/* at least one parent belongs to another process, have to query the server */
for (;;)
{
count = 0;
SERVER_START_REQ( get_window_parents )
{
req->handle = wine_server_user_handle( hwnd );
wine_server_set_reply( req, list, (size-1) * sizeof(user_handle_t) );
if (!wine_server_call( req )) count = reply->count;
}
SERVER_END_REQ;
if (!count) goto empty;
if (size > count)
{
/* start from the end since HWND is potentially larger than user_handle_t */
for (i = count - 1; i >= 0; i--)
list[i] = wine_server_ptr_handle( ((user_handle_t *)list)[i] );
list[count] = 0;
return list;
}
free( list );
size = count + 1;
if (!(list = malloc( size * sizeof(HWND) ))) return NULL;
}
empty:
free( list );
return NULL;
}
/*****************************************************************
* NtUserGetAncestor (win32u.@)
*/
HWND WINAPI NtUserGetAncestor( HWND hwnd, UINT type )
{
HWND *list, ret = 0;
WND *win;
switch(type)
{
case GA_PARENT:
if (!(win = get_win_ptr( hwnd )))
{
SetLastError( ERROR_INVALID_WINDOW_HANDLE );
return 0;
}
if (win == WND_DESKTOP) return 0;
if (win != WND_OTHER_PROCESS)
{
ret = win->parent;
release_win_ptr( win );
}
else /* need to query the server */
{
SERVER_START_REQ( get_window_tree )
{
req->handle = wine_server_user_handle( hwnd );
if (!wine_server_call_err( req )) ret = wine_server_ptr_handle( reply->parent );
}
SERVER_END_REQ;
}
break;
case GA_ROOT:
if (!(list = list_window_parents( hwnd ))) return 0;
if (!list[0] || !list[1]) ret = get_full_window_handle( hwnd ); /* top-level window */
else
{
int count = 2;
while (list[count]) count++;
ret = list[count - 2]; /* get the one before the desktop */
}
free( list );
break;
case GA_ROOTOWNER:
if (is_desktop_window( hwnd )) return 0;
ret = get_full_window_handle( hwnd );
for (;;)
{
HWND parent = get_parent( ret );
if (!parent) break;
ret = parent;
}
break;
}
return ret;
}
static LONG_PTR get_win_data( const void *ptr, UINT size )
{
if (size == sizeof(WORD))
......
......@@ -99,6 +99,7 @@
SYSCALL_ENTRY( NtUserCreateWindowStation ) \
SYSCALL_ENTRY( NtUserDestroyAcceleratorTable ) \
SYSCALL_ENTRY( NtUserFindExistingCursorIcon ) \
SYSCALL_ENTRY( NtUserGetAncestor ) \
SYSCALL_ENTRY( NtUserGetClipboardFormatName ) \
SYSCALL_ENTRY( NtUserGetClipboardOwner ) \
SYSCALL_ENTRY( NtUserGetClipboardSequenceNumber ) \
......
......@@ -189,6 +189,14 @@ NTSTATUS WINAPI wow64_NtUserRemoveProp( UINT *args )
return HandleToUlong( NtUserRemoveProp( hwnd, str ));
}
NTSTATUS WINAPI wow64_NtUserGetAncestor( UINT *args )
{
HWND hwnd = get_handle( &args );
UINT type = get_ulong( &args );
return HandleToUlong( NtUserGetAncestor( hwnd, type ));
}
NTSTATUS WINAPI wow64_NtUserBuildHwndList( UINT *args )
{
HDESK desktop = get_handle( &args );
......
......@@ -275,6 +275,7 @@ BOOL WINAPI NtUserEnumDisplaySettings( UNICODE_STRING *device, DWORD mode,
DEVMODEW *dev_mode, DWORD flags );
HICON WINAPI NtUserFindExistingCursorIcon( UNICODE_STRING *module, UNICODE_STRING *res_name,
void *desc );
HWND WINAPI NtUserGetAncestor( HWND hwnd, UINT type );
SHORT WINAPI NtUserGetAsyncKeyState( INT key );
ULONG WINAPI NtUserGetAtomName( ATOM atom, UNICODE_STRING *name );
ATOM WINAPI NtUserGetClassInfoEx( HINSTANCE instance, UNICODE_STRING *name, WNDCLASSEXW *wc,
......
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