From 6d3bb6bc5ce94907fefcacf4eb4a2bee7e9298b4 Mon Sep 17 00:00:00 2001 From: Giannis Adamopoulos Date: Sun, 13 Dec 2009 20:01:21 +0000 Subject: [PATCH] [user32] Optimize GetWindow by moving it completely to user mode [win32k] Remove reactos only syscall NtUserGetWindow svn path=/trunk/; revision=44571 --- reactos/dll/win32/user32/windows/window.c | 33 +++++++- reactos/include/reactos/win32k/ntuser.h | 4 - .../subsystems/win32/win32k/ntuser/window.c | 81 ++++++++++++------- reactos/subsystems/win32/win32k/w32ksvc.db | 1 - 4 files changed, 81 insertions(+), 38 deletions(-) diff --git a/reactos/dll/win32/user32/windows/window.c b/reactos/dll/win32/user32/windows/window.c index 42b23c1f134..4485333f230 100644 --- a/reactos/dll/win32/user32/windows/window.c +++ b/reactos/dll/win32/user32/windows/window.c @@ -1024,8 +1024,36 @@ GetWindow(HWND hWnd, FoundWnd = DesktopPtrToUser(Wnd->spwndOwner); break; + case GW_HWNDFIRST: + if(Wnd->spwndParent != NULL) + { + FoundWnd = DesktopPtrToUser(Wnd->spwndParent); + if (FoundWnd->spwndChild != NULL) + FoundWnd = DesktopPtrToUser(FoundWnd->spwndChild); + } + break; + case GW_HWNDNEXT: + if (Wnd->spwndNext != NULL) + FoundWnd = DesktopPtrToUser(Wnd->spwndNext); + break; + + case GW_HWNDPREV: + if (Wnd->spwndPrev != NULL) + FoundWnd = DesktopPtrToUser(Wnd->spwndPrev); + break; + + case GW_CHILD: + if (Wnd->spwndChild != NULL) + FoundWnd = DesktopPtrToUser(Wnd->spwndChild); + break; + + case GW_HWNDLAST: + FoundWnd = Wnd; + while ( FoundWnd->spwndNext != NULL) + FoundWnd = DesktopPtrToUser(FoundWnd->spwndNext); + break; + default: - /* FIXME: Optimize! Fall back to NtUserGetWindow for now... */ Wnd = NULL; break; } @@ -1039,9 +1067,6 @@ GetWindow(HWND hWnd, } _SEH2_END; - if (!Wnd) /* Fall back to win32k... */ - Ret = NtUserGetWindow(hWnd, uCmd); - return Ret; } diff --git a/reactos/include/reactos/win32k/ntuser.h b/reactos/include/reactos/win32k/ntuser.h index bd3b5dc9e16..4b3c838ef4b 100644 --- a/reactos/include/reactos/win32k/ntuser.h +++ b/reactos/include/reactos/win32k/ntuser.h @@ -3136,10 +3136,6 @@ NtUserGetScrollInfo( int fnBar, LPSCROLLINFO lpsi); -HWND -NTAPI -NtUserGetWindow(HWND hWnd, UINT Relationship); - /* Should be done in usermode and use NtUserGetCPD. */ LONG NTAPI diff --git a/reactos/subsystems/win32/win32k/ntuser/window.c b/reactos/subsystems/win32/win32k/ntuser/window.c index 61a76f837e9..069f2ea3987 100644 --- a/reactos/subsystems/win32/win32k/ntuser/window.c +++ b/reactos/subsystems/win32/win32k/ntuser/window.c @@ -1014,6 +1014,31 @@ IntIsWindowVisible(PWINDOW_OBJECT BaseWindow) return FALSE; } +VOID FASTCALL +IntLinkWnd( + PWND Wnd, + PWND WndParent, + PWND WndPrevSibling) /* set to NULL if top sibling */ +{ + Wnd->spwndParent = WndParent; + if ((Wnd->spwndPrev = WndPrevSibling)) + { + /* link after WndPrevSibling */ + if ((Wnd->spwndNext = WndPrevSibling->spwndNext)) + Wnd->spwndNext->spwndPrev = Wnd; + + Wnd->spwndPrev->spwndNext = Wnd; + } + else + { + /* link at top */ + if ((Wnd->spwndNext = WndParent->spwndChild)) + Wnd->spwndNext->spwndPrev = Wnd; + + WndParent->spwndChild = Wnd; + } + +} /* link the window into siblings and parent. children are kept in place. */ VOID FASTCALL @@ -1025,8 +1050,11 @@ IntLinkWindow( { PWINDOW_OBJECT Parent; + IntLinkWnd(Wnd->Wnd, + WndParent->Wnd, + WndPrevSibling ? WndPrevSibling->Wnd : NULL); + Wnd->Parent = WndParent; - Wnd->Wnd->spwndParent = WndParent ? WndParent->Wnd : NULL; if ((Wnd->PrevSibling = WndPrevSibling)) { /* link after WndPrevSibling */ @@ -1221,6 +1249,22 @@ IntSetSystemMenu(PWINDOW_OBJECT Window, PMENU_OBJECT Menu) return TRUE; } +/* unlink the window from siblings and parent. children are kept in place. */ +VOID FASTCALL +IntUnlinkWnd(PWND Wnd) +{ + if (Wnd->spwndNext) + Wnd->spwndNext->spwndPrev = Wnd->spwndPrev; + + if (Wnd->spwndPrev) + Wnd->spwndPrev->spwndNext = Wnd->spwndNext; + + if (Wnd->spwndParent && Wnd->spwndParent->spwndChild == Wnd) + Wnd->spwndParent->spwndChild = Wnd->spwndNext; + + Wnd->spwndParent = Wnd->spwndPrev = Wnd->spwndNext = Wnd->spwndParent = NULL; +} + /* unlink the window from siblings and parent. children are kept in place. */ VOID FASTCALL @@ -1228,6 +1272,8 @@ IntUnlinkWindow(PWINDOW_OBJECT Wnd) { PWINDOW_OBJECT WndParent = Wnd->Parent; + IntUnlinkWnd(Wnd->Wnd); + if (Wnd->NextSibling) Wnd->NextSibling->PrevSibling = Wnd->PrevSibling; else if (WndParent && WndParent->LastChild == Wnd) @@ -1239,8 +1285,6 @@ IntUnlinkWindow(PWINDOW_OBJECT Wnd) WndParent->FirstChild = Wnd->NextSibling; Wnd->PrevSibling = Wnd->NextSibling = Wnd->Parent = NULL; - if (Wnd->Wnd) - Wnd->Wnd->spwndParent = NULL; } BOOL FASTCALL @@ -1915,6 +1959,11 @@ AllocErr: Window->LastChild = NULL; Window->PrevSibling = NULL; Window->NextSibling = NULL; + + Wnd->spwndNext = NULL; + Wnd->spwndPrev = NULL; + Wnd->spwndChild = NULL; + Wnd->cbwndExtra = Wnd->pcls->cbwndExtra; InitializeListHead(&Wnd->PropListHead); @@ -3677,32 +3726,6 @@ UserGetWindow(HWND hWnd, UINT Relationship) return hWndResult; } -/* - * NtUserGetWindow - * - * The NtUserGetWindow function retrieves a handle to a window that has the - * specified relationship (Z order or owner) to the specified window. - * - * Status - * @implemented - */ - -HWND APIENTRY -NtUserGetWindow(HWND hWnd, UINT Relationship) -{ - DECLARE_RETURN(HWND); - - DPRINT("Enter NtUserGetWindow\n"); - UserEnterShared(); - - RETURN(UserGetWindow(hWnd, Relationship)); - -CLEANUP: - DPRINT("Leave NtUserGetWindow, ret=%i\n",_ret_); - UserLeave(); - END_CLEANUP; -} - /* * NtUserGetWindowLong * diff --git a/reactos/subsystems/win32/win32k/w32ksvc.db b/reactos/subsystems/win32/win32k/w32ksvc.db index 96110c38b41..a14cb7e02f7 100644 --- a/reactos/subsystems/win32/win32k/w32ksvc.db +++ b/reactos/subsystems/win32/win32k/w32ksvc.db @@ -690,7 +690,6 @@ NtUserGetLastInputInfo 1 NtUserGetMinMaxInfo 3 NtUserGetMonitorInfo 2 NtUserGetScrollInfo 3 -NtUserGetWindow 2 NtUserGetWindowLong 3 NtUserMenuInfo 3 NtUserMenuItemInfo 5 -- 2.17.1