[user32]
authorGiannis Adamopoulos <gadamopoulos@reactos.org>
Sun, 13 Dec 2009 20:01:21 +0000 (20:01 +0000)
committerGiannis Adamopoulos <gadamopoulos@reactos.org>
Sun, 13 Dec 2009 20:01:21 +0000 (20:01 +0000)
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
reactos/include/reactos/win32k/ntuser.h
reactos/subsystems/win32/win32k/ntuser/window.c
reactos/subsystems/win32/win32k/w32ksvc.db

index 42b23c1..4485333 100644 (file)
@@ -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;
 }
 
index bd3b5dc..4b3c838 100644 (file)
@@ -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
index 61a76f8..069f2ea 100644 (file)
@@ -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
  *
index 96110c3..a14cb7e 100644 (file)
@@ -690,7 +690,6 @@ NtUserGetLastInputInfo                  1
 NtUserGetMinMaxInfo                     3
 NtUserGetMonitorInfo                    2
 NtUserGetScrollInfo                     3
-NtUserGetWindow                         2
 NtUserGetWindowLong                     3
 NtUserMenuInfo                          3
 NtUserMenuItemInfo                      5