[YAROTOWS] Reintegrate the branch. For a brighter future.
[reactos.git] / reactos / subsystems / win32 / win32k / ntuser / desktop.c
index b04fbe8..894245d 100644 (file)
@@ -10,7 +10,7 @@
 
 /* INCLUDES ******************************************************************/
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
@@ -142,11 +142,12 @@ IntDesktopObjectParse(IN PVOID ParseObject,
     if (!NT_SUCCESS(Status)) return Status;
 
     /* Initialize shell hook window list and set the parent */
+    RtlZeroMemory(Desktop, sizeof(DESKTOP));
     InitializeListHead(&Desktop->ShellHookWindows);
-    Desktop->WindowStation = (PWINSTATION_OBJECT)ParseObject;
+    Desktop->rpwinstaParent = (PWINSTATION_OBJECT)ParseObject;
 
     /* Put the desktop on the window station's list of associated desktops */
-    InsertTailList(&Desktop->WindowStation->DesktopListHead,
+    InsertTailList(&Desktop->rpwinstaParent->DesktopListHead,
                    &Desktop->ListEntry);
 
     /* Set the desktop object and return success */
@@ -418,35 +419,6 @@ IntValidateDesktopHandle(
    return Status;
 }
 
-VOID FASTCALL
-IntGetDesktopWorkArea(PDESKTOP Desktop, RECTL *Rect)
-{
-   RECTL *Ret;
-
-   ASSERT(Desktop);
-
-   Ret = &Desktop->WorkArea;
-   if((Ret->right == -1) && ScreenDeviceContext)
-   {
-      PDC dc;
-      SURFACE *psurf;
-      dc = DC_LockDc(ScreenDeviceContext);
-      /* FIXME - Handle dc == NULL!!!! */
-      psurf = dc->dclevel.pSurface;
-      if (psurf)
-      {
-         Ret->right = psurf->SurfObj.sizlBitmap.cx;
-         Ret->bottom = psurf->SurfObj.sizlBitmap.cy;
-      }
-      DC_UnlockDc(dc);
-   }
-
-   if(Rect)
-   {
-      *Rect = *Ret;
-   }
-}
-
 PDESKTOP FASTCALL
 IntGetActiveDesktop(VOID)
 {
@@ -543,7 +515,7 @@ HWND FASTCALL IntGetDesktopWindow(VOID)
    return pdo->DesktopWindow;
 }
 
-PWINDOW_OBJECT FASTCALL UserGetDesktopWindow(VOID)
+PWND FASTCALL UserGetDesktopWindow(VOID)
 {
    PDESKTOP pdo = IntGetActiveDesktop();
 
@@ -565,13 +537,13 @@ HWND FASTCALL IntGetMessageWindow(VOID)
       DPRINT("No active desktop\n");
       return NULL;
    }
-   return pdo->spwndMessage;
+   return pdo->spwndMessage->head.h;
 }
 
 HWND FASTCALL IntGetCurrentThreadDesktopWindow(VOID)
 {
    PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
-   PDESKTOP pdo = pti->Desktop;
+   PDESKTOP pdo = pti->rpdesk;
    if (NULL == pdo)
    {
       DPRINT1("Thread doesn't have a desktop\n");
@@ -621,7 +593,7 @@ BOOL FASTCALL IntDesktopUpdatePerUserSettings(BOOL bEnable)
 HDC FASTCALL
 UserGetDesktopDC(ULONG DcType, BOOL EmptyDC, BOOL ValidatehWnd)
 {
-    PWINDOW_OBJECT DesktopObject = 0;
+    PWND DesktopObject = 0;
     HDC DesktopHDC = 0;
 
     if (DcType == DC_TYPE_DIRECT)
@@ -642,19 +614,16 @@ UserGetDesktopDC(ULONG DcType, BOOL EmptyDC, BOOL ValidatehWnd)
 VOID APIENTRY
 UserRedrawDesktop()
 {
-    PWINDOW_OBJECT Window = NULL;
-
-    UserEnterExclusive();
+    PWND Window = NULL;
 
     Window = UserGetDesktopWindow();
 
     IntInvalidateWindows( Window,
-            Window->UpdateRegion,
+              Window->hrgnUpdate,
                        RDW_FRAME |
                        RDW_ERASE |
                   RDW_INVALIDATE |
                  RDW_ALLCHILDREN);
-    UserLeave();
 }
 
 
@@ -684,16 +653,14 @@ IntHideDesktop(PDESKTOP Desktop)
    return NotifyCsrss(&Request, &Reply);
 #else
 
-   PWINDOW_OBJECT DesktopWindow;
-   PWINDOW DesktopWnd;
+   PWND DesktopWnd;
 
-   DesktopWindow = IntGetWindowObject(Desktop->DesktopWindow);
-   if (! DesktopWindow)
+   DesktopWnd = IntGetWindowObject(Desktop->DesktopWindow);
+   if (! DesktopWnd)
    {
       return ERROR_INVALID_WINDOW_HANDLE;
    }
-   DesktopWnd = DesktopWindow->Wnd;
-   DesktopWnd->Style &= ~WS_VISIBLE;
+   DesktopWnd->style &= ~WS_VISIBLE;
 
    return STATUS_SUCCESS;
 #endif
@@ -716,7 +683,7 @@ UserBuildShellHookHwndList(PDESKTOP Desktop)
 
    if (!entries) return NULL;
 
-   list = ExAllocatePool(PagedPool, sizeof(HWND) * (entries + 1)); /* alloc one extra for nullterm */
+   list = ExAllocatePoolWithTag(PagedPool, sizeof(HWND) * (entries + 1), USERTAG_WINDOWLIST); /* alloc one extra for nullterm */
    if (list)
    {
       HWND* cursor = list;
@@ -795,7 +762,7 @@ VOID co_IntShellHookNotify(WPARAM Message, LPARAM lParam)
 BOOL IntRegisterShellHookWindow(HWND hWnd)
 {
    PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
-   PDESKTOP Desktop = pti->Desktop;
+   PDESKTOP Desktop = pti->rpdesk;
    PSHELL_HOOK_WINDOW Entry;
 
    DPRINT("IntRegisterShellHookWindow\n");
@@ -827,7 +794,7 @@ BOOL IntRegisterShellHookWindow(HWND hWnd)
 BOOL IntDeRegisterShellHookWindow(HWND hWnd)
 {
    PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
-   PDESKTOP Desktop = pti->Desktop;
+   PDESKTOP Desktop = pti->rpdesk;
    PSHELL_HOOK_WINDOW Current;
 
    LIST_FOR_EACH(Current, &Desktop->ShellHookWindows, SHELL_HOOK_WINDOW, ListEntry)
@@ -846,15 +813,14 @@ BOOL IntDeRegisterShellHookWindow(HWND hWnd)
 static VOID
 IntFreeDesktopHeap(IN OUT PDESKTOP Desktop)
 {
-    if (Desktop->DesktopHeapSection != NULL)
+    if (Desktop->hsectionDesktop != NULL)
     {
-        ObDereferenceObject(Desktop->DesktopHeapSection);
-        Desktop->DesktopHeapSection = NULL;
+        ObDereferenceObject(Desktop->hsectionDesktop);
+        Desktop->hsectionDesktop = NULL;
     }
 }
 /* SYSCALLS *******************************************************************/
 
-
 /*
  * NtUserCreateDesktop
  *
@@ -898,7 +864,6 @@ NtUserCreateDesktop(
 {
    OBJECT_ATTRIBUTES ObjectAttributes;
    PTHREADINFO W32Thread;
-//   HWND hwndMessage;
    PWINSTATION_OBJECT WinStaObject;
    PDESKTOP DesktopObject;
    UNICODE_STRING DesktopName;
@@ -912,7 +877,11 @@ NtUserCreateDesktop(
    ULONG_PTR HeapSize = 4 * 1024 * 1024; /* FIXME */
    HWINSTA hWindowStation = NULL ;
    PUNICODE_STRING lpszDesktopName = NULL;
-//   UNICODE_STRING AtomName;
+   UNICODE_STRING ClassName, MenuName;
+   LARGE_STRING WindowName;
+   PWND pWnd = NULL;
+   CREATESTRUCTW Cs;
+   INT i;
    DECLARE_RETURN(HDESK);
 
    DPRINT("Enter NtUserCreateDesktop: %wZ\n", lpszDesktopName);
@@ -1018,8 +987,8 @@ NtUserCreateDesktop(
                                       NULL);
    if (!NT_SUCCESS(Status)) RETURN(NULL);
 
-   DesktopObject->DesktopHeapSection = NULL;
-   DesktopObject->pheapDesktop = UserCreateHeap(&DesktopObject->DesktopHeapSection,
+   DesktopObject->hsectionDesktop = NULL;
+   DesktopObject->pheapDesktop = UserCreateHeap(&DesktopObject->hsectionDesktop,
                                                 &DesktopHeapSystemBase,
                                                 HeapSize);
    if (DesktopObject->pheapDesktop == NULL)
@@ -1032,36 +1001,34 @@ NtUserCreateDesktop(
    DesktopInfoSize = FIELD_OFFSET(DESKTOPINFO,
                                   szDesktopName[(lpszDesktopName->Length / sizeof(WCHAR)) + 1]);
 
-   DesktopObject->DesktopInfo = RtlAllocateHeap(DesktopObject->pheapDesktop,
+   DesktopObject->pDeskInfo = RtlAllocateHeap(DesktopObject->pheapDesktop,
                                                 HEAP_NO_SERIALIZE,
                                                 DesktopInfoSize);
 
-   if (DesktopObject->DesktopInfo == NULL)
+   if (DesktopObject->pDeskInfo == NULL)
    {
        ObDereferenceObject(DesktopObject);
        DPRINT1("Failed to create the DESKTOP structure!\n");
        RETURN(NULL);
    }
 
-   RtlZeroMemory(DesktopObject->DesktopInfo,
+   RtlZeroMemory(DesktopObject->pDeskInfo,
                  DesktopInfoSize);
 
-   DesktopObject->DesktopInfo->pvDesktopBase = DesktopHeapSystemBase;
-   DesktopObject->DesktopInfo->pvDesktopLimit = (PVOID)((ULONG_PTR)DesktopHeapSystemBase + HeapSize);
-   RtlCopyMemory(DesktopObject->DesktopInfo->szDesktopName,
+   DesktopObject->pDeskInfo->pvDesktopBase = DesktopHeapSystemBase;
+   DesktopObject->pDeskInfo->pvDesktopLimit = (PVOID)((ULONG_PTR)DesktopHeapSystemBase + HeapSize);
+   RtlCopyMemory(DesktopObject->pDeskInfo->szDesktopName,
                  lpszDesktopName->Buffer,
                  lpszDesktopName->Length);
 
-   // init desktop area
-   DesktopObject->WorkArea.left = 0;
-   DesktopObject->WorkArea.top = 0;
-   DesktopObject->WorkArea.right = -1;
-   DesktopObject->WorkArea.bottom = -1;
-   IntGetDesktopWorkArea(DesktopObject, NULL);
-
    /* Initialize some local (to win32k) desktop state. */
    InitializeListHead(&DesktopObject->PtiList);
    DesktopObject->ActiveMessageQueue = NULL;
+   /* Setup Global Hooks. */
+   for (i = 0; i < NB_HOOKS; i++)
+   {
+      InitializeListHead(&DesktopObject->pDeskInfo->aphkStart[i]);
+   }
    ExFreePoolWithTag(DesktopName.Buffer, TAG_STRING);
 
    if (! NT_SUCCESS(Status))
@@ -1072,7 +1039,12 @@ NtUserCreateDesktop(
    }
 
    /*
-    * Create a handle for CSRSS and notify CSRSS
+    * Create a handle for CSRSS and notify CSRSS for Creating Desktop Window.
+    *
+    * Honestly, I believe this is a cleverly written hack that allowed ReactOS
+    * to function at the beginning of the project by ramroding the GUI into
+    * operation and making the desktop window work from user space.
+    *                                                         (jt)
     */
    Request.Type = MAKE_CSR_API(CREATE_DESKTOP, CSR_GUI);
    Status = CsrInsertObject(Desktop,
@@ -1098,50 +1070,34 @@ NtUserCreateDesktop(
 
    W32Thread = PsGetCurrentThreadWin32Thread();
 
-   if (!W32Thread->Desktop) IntSetThreadDesktop(DesktopObject,FALSE);
+   if (!W32Thread->rpdesk) IntSetThreadDesktop(DesktopObject,FALSE);
 
-#if 0
   /*
-     Based on wine/server/window.c line 1804 in get_desktop_window.
-     We create an atom to be used for create desktop to create
-     the message window.
+     Based on wine/server/window.c in get_desktop_window.
    */
-   // FIXME!
-   // ReactOS CreateWindow does not know how to correctly use Atom Classes.
-   // So we have this HAX!
-   { // Warning! HACK! Yes it is very wrong!
 
-   // Normally, this would have been performed during the win32k init phase.
-   //  AtomMessage = IntAddGlobalAtom(L"Message", TRUE); // <- correct, but should be in ntuser.c
+   ClassName.Buffer = ((PWSTR)((ULONG_PTR)(WORD)(gpsi->atomSysClass[ICLS_HWNDMESSAGE])));
+   ClassName.Length = 0;
+   RtlZeroMemory(&MenuName, sizeof(MenuName));
+   RtlZeroMemory(&WindowName, sizeof(WindowName));
 
-     AtomMessage = 
-   }
-   AtomName.Buffer = ((PWSTR)((ULONG_PTR)(WORD)(AtomMessage)));
-   AtomName.Length = 0;
-
-   hwndMessage = co_IntCreateWindowEx( 0,
-                                       &AtomName,
-                                       NULL,
-                                      (WS_POPUP|WS_CLIPCHILDREN),
-                                       0,
-                                       0,
-                                       100,
-                                       100,
-                                       NULL,
-                                       NULL,
-                                       NULL,//hModuleWin, // pi->hModUser; ? no!
-                                       NULL,
-                                       0,
-                                       TRUE);
-   if (!hwndMessage)
+   RtlZeroMemory(&Cs, sizeof(Cs));
+   Cs.cx = Cs.cy = 100;
+   Cs.style = WS_POPUP|WS_CLIPCHILDREN;
+   Cs.hInstance = hModClient;
+   Cs.lpszName = (LPCWSTR) &WindowName;
+   Cs.lpszClass = (LPCWSTR) &ClassName;
+
+   pWnd = co_UserCreateWindowEx(&Cs, &ClassName, &WindowName);
+   if (!pWnd)
    {
       DPRINT1("Failed to create Message window handle\n");
    }
    else
    {
-      DesktopObject->spwndMessage = hwndMessage;
+      DesktopObject->spwndMessage = pWnd;
    }
-#endif
+
    RETURN( Desktop);
 
 CLEANUP:
@@ -1446,13 +1402,13 @@ NtUserPaintDesktop(HDC hDC)
    HBRUSH DesktopBrush, PreviousBrush;
    HWND hWndDesktop;
    BOOL doPatBlt = TRUE;
-   PWINDOW_OBJECT WndDesktop;
+   PWND WndDesktop;
    int len;
    COLORREF color_old;
    UINT align_old;
    int mode_old;
    PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
-   PWINSTATION_OBJECT WinSta = pti->Desktop->WindowStation;
+   PWINSTATION_OBJECT WinSta = pti->rpdesk->rpwinstaParent;
    DECLARE_RETURN(BOOL);
 
    UserEnterExclusive();
@@ -1468,7 +1424,7 @@ NtUserPaintDesktop(HDC hDC)
       RETURN(FALSE);
    }
 
-   DesktopBrush = (HBRUSH)UserGetClassLongPtr(WndDesktop->Wnd->Class, GCL_HBRBACKGROUND, FALSE);
+   DesktopBrush = (HBRUSH)WndDesktop->pcls->hbrBackground;
 
 
    /*
@@ -1477,7 +1433,7 @@ NtUserPaintDesktop(HDC hDC)
 
    if (WinSta->hbmWallpaper != NULL)
    {
-      PWINDOW_OBJECT DeskWin;
+      PWND DeskWin;
 
       DeskWin = UserGetWindowObject(hWndDesktop);
 
@@ -1487,8 +1443,8 @@ NtUserPaintDesktop(HDC hDC)
          int x, y;
          HDC hWallpaperDC;
 
-         sz.cx = DeskWin->Wnd->WindowRect.right - DeskWin->Wnd->WindowRect.left;
-         sz.cy = DeskWin->Wnd->WindowRect.bottom - DeskWin->Wnd->WindowRect.top;
+         sz.cx = DeskWin->rcWindow.right - DeskWin->rcWindow.left;
+         sz.cy = DeskWin->rcWindow.bottom - DeskWin->rcWindow.top;
 
          if (WinSta->WallpaperMode == wmStretch ||
              WinSta->WallpaperMode == wmTile)
@@ -1681,7 +1637,7 @@ NtUserSwitchDesktop(HDESK hDesktop)
     * Don't allow applications switch the desktop if it's locked, unless the caller
     * is the logon application itself
     */
-   if((DesktopObject->WindowStation->Flags & WSS_LOCKED) &&
+   if((DesktopObject->rpwinstaParent->Flags & WSS_LOCKED) &&
          LogonProcess != NULL && LogonProcess != PsGetCurrentProcessWin32Process())
    {
       ObDereferenceObject(DesktopObject);
@@ -1689,18 +1645,23 @@ NtUserSwitchDesktop(HDESK hDesktop)
       RETURN(FALSE);
    }
 
-   /* FIXME: Fail if the desktop belong to an invisible window station */
+   if(DesktopObject->rpwinstaParent != InputWindowStation)
+   {
+      ObDereferenceObject(DesktopObject);
+      DPRINT1("Switching desktop 0x%x denied because desktop doesn't belong to the interactive winsta!\n", hDesktop);
+      RETURN(FALSE);
+   }
+
    /* FIXME: Fail if the process is associated with a secured
              desktop such as Winlogon or Screen-Saver */
    /* FIXME: Connect to input device */
 
    /* Set the active desktop in the desktop's window station. */
-   DesktopObject->WindowStation->ActiveDesktop = DesktopObject;
+   InputWindowStation->ActiveDesktop = DesktopObject;
 
    /* Set the global state. */
    InputDesktop = DesktopObject;
    InputDesktopHandle = hDesktop;
-   InputWindowStation = DesktopObject->WindowStation;
 
    ObDereferenceObject(DesktopObject);
 
@@ -1763,14 +1724,14 @@ NtUserGetThreadDesktop(DWORD dwThreadId, DWORD Unknown1)
    {
       /* just return the handle, we queried the desktop handle of a thread running
          in the same context */
-      Ret = ((PTHREADINFO)Thread->Tcb.Win32Thread)->hDesktop;
+      Ret = ((PTHREADINFO)Thread->Tcb.Win32Thread)->hdesk;
       ObDereferenceObject(Thread);
       RETURN(Ret);
    }
 
    /* get the desktop handle and the desktop of the thread */
-   if(!(hThreadDesktop = ((PTHREADINFO)Thread->Tcb.Win32Thread)->hDesktop) ||
-         !(DesktopObject = ((PTHREADINFO)Thread->Tcb.Win32Thread)->Desktop))
+   if(!(hThreadDesktop = ((PTHREADINFO)Thread->Tcb.Win32Thread)->hdesk) ||
+         !(DesktopObject = ((PTHREADINFO)Thread->Tcb.Win32Thread)->rpdesk))
    {
       ObDereferenceObject(Thread);
       DPRINT1("Desktop information of thread 0x%x broken!?\n", dwThreadId);
@@ -1815,8 +1776,8 @@ CLEANUP:
 static NTSTATUS
 IntUnmapDesktopView(IN PDESKTOP DesktopObject)
 {
-    PW32THREADINFO ti;
-    PW32PROCESS CurrentWin32Process;
+    PTHREADINFO ti;
+    PPROCESSINFO CurrentWin32Process;
     PW32HEAP_USER_MAPPING HeapMapping, *PrevLink;
     NTSTATUS Status = STATUS_SUCCESS;
 
@@ -1852,10 +1813,6 @@ IntUnmapDesktopView(IN PDESKTOP DesktopObject)
     ti = GetW32ThreadInfo();
     if (ti != NULL)
     {
-        if (ti->pDeskInfo == DesktopObject->DesktopInfo)
-        {
-            ti->pDeskInfo = NULL;
-        }
         GetWin32ClientInfo()->pDeskInfo = NULL;
     }
     GetWin32ClientInfo()->ulClientDelta = 0;
@@ -1866,8 +1823,8 @@ IntUnmapDesktopView(IN PDESKTOP DesktopObject)
 static NTSTATUS
 IntMapDesktopView(IN PDESKTOP DesktopObject)
 {
-    PW32THREADINFO ti;
-    PW32PROCESS CurrentWin32Process;
+    PTHREADINFO ti;
+    PPROCESSINFO CurrentWin32Process;
     PW32HEAP_USER_MAPPING HeapMapping, *PrevLink;
     PVOID UserBase = NULL;
     SIZE_T ViewSize = 0;
@@ -1894,7 +1851,7 @@ IntMapDesktopView(IN PDESKTOP DesktopObject)
     /* we're the first, map the heap */
     DPRINT("Noone mapped the desktop heap %p yet, so - map it!\n", DesktopObject->pheapDesktop);
     Offset.QuadPart = 0;
-    Status = MmMapViewOfSection(DesktopObject->DesktopHeapSection,
+    Status = MmMapViewOfSection(DesktopObject->hsectionDesktop,
                                 PsGetCurrentProcess(),
                                 &UserBase,
                                 0,
@@ -1934,11 +1891,11 @@ IntMapDesktopView(IN PDESKTOP DesktopObject)
     GetWin32ClientInfo()->ulClientDelta = DesktopHeapGetUserDelta();
     if (ti != NULL)
     {
-        if (ti->pDeskInfo == NULL)
+        if (GetWin32ClientInfo()->pDeskInfo == NULL)
         {
-           ti->pDeskInfo = DesktopObject->DesktopInfo;
            GetWin32ClientInfo()->pDeskInfo = 
-                (PVOID)((ULONG_PTR)ti->pDeskInfo - GetWin32ClientInfo()->ulClientDelta);
+                (PVOID)((ULONG_PTR)DesktopObject->pDeskInfo - 
+                                          GetWin32ClientInfo()->ulClientDelta);
         }
     }
 
@@ -1958,9 +1915,9 @@ IntSetThreadDesktop(IN PDESKTOP DesktopObject,
     MapHeap = (PsGetCurrentProcess() != PsInitialSystemProcess);
     W32Thread = PsGetCurrentThreadWin32Thread();
 
-    if (W32Thread->Desktop != DesktopObject)
+    if (W32Thread->rpdesk != DesktopObject)
     {
-        OldDesktop = W32Thread->Desktop;
+        OldDesktop = W32Thread->rpdesk;
 
         if (!IsListEmpty(&W32Thread->WindowListHead))
         {
@@ -1969,7 +1926,7 @@ IntSetThreadDesktop(IN PDESKTOP DesktopObject,
             return FALSE;
         }
 
-        W32Thread->Desktop = DesktopObject;
+        W32Thread->rpdesk = DesktopObject;
 
         if (MapHeap && DesktopObject != NULL)
         {
@@ -1981,15 +1938,6 @@ IntSetThreadDesktop(IN PDESKTOP DesktopObject,
             }
         }
 
-        if (W32Thread->Desktop == NULL)
-        {
-            PW32THREADINFO ti = GetW32ThreadInfo();
-            if (ti != NULL)
-            {
-                ti->pDeskInfo = NULL;
-            }
-        }
-
         /* Hack for system threads */
         if (NtCurrentTeb())
         {
@@ -1997,7 +1945,7 @@ IntSetThreadDesktop(IN PDESKTOP DesktopObject,
             pci->ulClientDelta = DesktopHeapGetUserDelta();
             if (DesktopObject)
             {
-                pci->pDeskInfo = (PVOID)((ULONG_PTR)DesktopObject->DesktopInfo - pci->ulClientDelta);
+                pci->pDeskInfo = (PVOID)((ULONG_PTR)DesktopObject->pDeskInfo - pci->ulClientDelta);
             }
         }