Sync with trunk r63743.
[reactos.git] / win32ss / gdi / eng / engwindow.c
index 423f61f..86560c9 100644 (file)
@@ -7,9 +7,8 @@
  */
 
 #include <win32k.h>
-
-#define NDEBUG
 #include <debug.h>
+DBG_DEFAULT_CHANNEL(EngWnd);
 
 INT gcountPWO = 0;
 
@@ -19,32 +18,29 @@ INT gcountPWO = 0;
 VOID
 FASTCALL
 IntEngWndCallChangeProc(
-    IN WNDOBJ *pwo,
-    IN FLONG   flChanged)
+    _In_ XCLIPOBJ *Clip,
+    _In_ FLONG   flChanged)
 {
-    WNDGDI *WndObjInt = ObjToGDI(pwo, WND);
-
-    if (WndObjInt->ChangeProc == NULL)
+    if (Clip->ChangeProc == NULL)
     {
         return;
     }
 
     /* check flags of the WNDOBJ */
-    flChanged &= WndObjInt->Flags;
+    flChanged &= Clip->Flags;
     if (flChanged == 0)
     {
         return;
     }
 
+    TRACE("Calling WNDOBJCHANGEPROC (0x%p), Changed = 0x%x\n",
+           Clip->ChangeProc, flChanged);
+
     /* Call the WNDOBJCHANGEPROC */
     if (flChanged == WOC_CHANGED)
-    {
-        pwo = NULL;
-    }
-
-    DPRINT("Calling WNDOBJCHANGEPROC (0x%p), Changed = 0x%x\n",
-           WndObjInt->ChangeProc, flChanged);
-    WndObjInt->ChangeProc(pwo, flChanged);
+        Clip->ChangeProc(NULL, flChanged);
+    else
+        Clip->ChangeProc(&Clip->WndObj, flChanged);
 }
 
 /*
@@ -53,36 +49,32 @@ IntEngWndCallChangeProc(
 BOOLEAN
 FASTCALL
 IntEngWndUpdateClipObj(
-    WNDGDI *WndObjInt,
+    XCLIPOBJ* Clip,
     PWND Window)
 {
     HRGN hVisRgn;
     PROSRGNDATA visRgn;
-    CLIPOBJ *ClipObj = NULL;
-    CLIPOBJ *OldClipObj;
 
-    DPRINT("IntEngWndUpdateClipObj\n");
+    TRACE("IntEngWndUpdateClipObj\n");
 
     hVisRgn = VIS_ComputeVisibleRegion(Window, TRUE, TRUE, TRUE);
     if (hVisRgn != NULL)
     {
-        NtGdiOffsetRgn(hVisRgn, Window->rcClient.left, Window->rcClient.top);
         visRgn = RGNOBJAPI_Lock(hVisRgn, NULL);
         if (visRgn != NULL)
         {
             if (visRgn->rdh.nCount > 0)
             {
-                ClipObj = IntEngCreateClipRegion(visRgn->rdh.nCount, visRgn->Buffer,
-                                                 &visRgn->rdh.rcBound);
-                DPRINT("Created visible region with %lu rects\n", visRgn->rdh.nCount);
-                DPRINT("  BoundingRect: %d, %d  %d, %d\n",
+                IntEngUpdateClipRegion(Clip, visRgn->rdh.nCount, visRgn->Buffer, &visRgn->rdh.rcBound);
+                TRACE("Created visible region with %lu rects\n", visRgn->rdh.nCount);
+                TRACE("  BoundingRect: %d, %d  %d, %d\n",
                        visRgn->rdh.rcBound.left, visRgn->rdh.rcBound.top,
                        visRgn->rdh.rcBound.right, visRgn->rdh.rcBound.bottom);
                 {
                     ULONG i;
                     for (i = 0; i < visRgn->rdh.nCount; i++)
                     {
-                        DPRINT("  Rect #%lu: %ld,%ld  %ld,%ld\n", i+1,
+                        TRACE("  Rect #%lu: %ld,%ld  %ld,%ld\n", i+1,
                                visRgn->Buffer[i].left, visRgn->Buffer[i].top,
                                visRgn->Buffer[i].right, visRgn->Buffer[i].bottom);
                     }
@@ -92,33 +84,18 @@ IntEngWndUpdateClipObj(
         }
         else
         {
-            DPRINT1("Warning: Couldn't lock visible region of window DC\n");
+            WARN("Couldn't lock visible region of window DC\n");
         }
         GreDeleteObject(hVisRgn);
     }
     else
-    {
-        DPRINT1("Warning: VIS_ComputeVisibleRegion failed!\n");
-    }
-
-    if (ClipObj == NULL)
     {
         /* Fall back to client rect */
-        ClipObj = IntEngCreateClipRegion(1, &Window->rcClient,
-                                         &Window->rcClient);
+        IntEngUpdateClipRegion(Clip, 1, &Window->rcClient, &Window->rcClient);
     }
 
-    if (ClipObj == NULL)
-    {
-        DPRINT1("Warning: IntEngCreateClipRegion() failed!\n");
-        return FALSE;
-    }
-
-    RtlCopyMemory(&WndObjInt->WndObj.coClient, ClipObj, sizeof (CLIPOBJ));
-    RtlCopyMemory(&WndObjInt->WndObj.rclClient, &Window->rcClient, sizeof (RECT));
-    OldClipObj = InterlockedExchangePointer((PVOID*)&WndObjInt->ClientClipObj, ClipObj);
-    if (OldClipObj != NULL)
-        IntEngDeleteClipRegion(OldClipObj);
+    /* Update the WNDOBJ */
+    Clip->WndObj.rclClient = Window->rcClient;
 
     return TRUE;
 }
@@ -132,30 +109,31 @@ IntEngWindowChanged(
     _In_    PWND  Window,
     _In_    FLONG flChanged)
 {
-    PPROPERTY pprop;
-    WNDGDI *Current;
-    HWND hWnd;
+    XCLIPOBJ *Clip;
+
+    /*
+     * This function is broken because AtomWndObj conflicts with
+     * properties set from user mode using SetPropW
+     */
+    return;
 
     ASSERT_IRQL_LESS_OR_EQUAL(PASSIVE_LEVEL);
 
-    hWnd = Window->head.h;
-    pprop = IntGetProp(Window, AtomWndObj);
-    if (!pprop)
+    Clip = UserGetProp(Window, AtomWndObj);
+    if (!Clip)
     {
         return;
     }
-    Current = (WNDGDI *)pprop->Data;
-    if ( gcountPWO &&
-            Current &&
-            Current->Hwnd == hWnd &&
-            Current->WndObj.pvConsumer != NULL )
+
+    ASSERT(Clip->Hwnd == Window->head.h);
+    if (Clip->WndObj.pvConsumer != NULL)
     {
         /* Update the WNDOBJ */
         switch (flChanged)
         {
         case WOC_RGN_CLIENT:
             /* Update the clipobj and client rect of the WNDOBJ */
-            IntEngWndUpdateClipObj(Current, Window);
+            IntEngWndUpdateClipObj(Clip, Window);
             break;
 
         case WOC_DELETE:
@@ -164,12 +142,12 @@ IntEngWindowChanged(
         }
 
         /* Call the change proc */
-        IntEngWndCallChangeProc(&Current->WndObj, flChanged);
+        IntEngWndCallChangeProc(Clip, flChanged);
 
         /* HACK: Send WOC_CHANGED after WOC_RGN_CLIENT */
         if (flChanged == WOC_RGN_CLIENT)
         {
-            IntEngWndCallChangeProc(&Current->WndObj, WOC_CHANGED);
+            IntEngWndCallChangeProc(Clip, WOC_CHANGED);
         }
     }
 }
@@ -186,13 +164,13 @@ EngCreateWnd(
     FLONG             fl,
     int               iPixelFormat)
 {
-    WNDGDI *WndObjInt = NULL;
+    XCLIPOBJ *Clip = NULL;
     WNDOBJ *WndObjUser = NULL;
     PWND Window;
     BOOL calledFromUser;
     DECLARE_RETURN(WNDOBJ*);
 
-    DPRINT1("EngCreateWnd: pso = 0x%p, hwnd = 0x%p, pfn = 0x%p, fl = 0x%lx, pixfmt = %d\n",
+    TRACE("EngCreateWnd: pso = 0x%p, hwnd = 0x%p, pfn = 0x%p, fl = 0x%lx, pixfmt = %d\n",
             pso, hWnd, pfn, fl, iPixelFormat);
 
     calledFromUser = UserIsEntered();
@@ -208,37 +186,37 @@ EngCreateWnd(
     }
 
     /* Create WNDOBJ */
-    WndObjInt = EngAllocMem(0, sizeof (WNDGDI), GDITAG_WNDOBJ);
-    if (WndObjInt == NULL)
+    Clip = EngAllocMem(FL_ZERO_MEMORY, sizeof (XCLIPOBJ), GDITAG_WNDOBJ);
+    if (Clip == NULL)
     {
-        DPRINT1("Failed to allocate memory for a WND structure!\n");
+        ERR("Failed to allocate memory for a WND structure!\n");
         RETURN( NULL);
     }
+    IntEngInitClipObj(Clip);
 
     /* Fill the clipobj */
-    WndObjInt->ClientClipObj = NULL;
-    if (!IntEngWndUpdateClipObj(WndObjInt, Window))
+    if (!IntEngWndUpdateClipObj(Clip, Window))
     {
-        EngFreeMem(WndObjInt);
+        EngFreeMem(Clip);
         RETURN( NULL);
     }
 
     /* Fill user object */
-    WndObjUser = GDIToObj(WndObjInt, WND);
+    WndObjUser = &Clip->WndObj;
     WndObjUser->psoOwner = pso;
     WndObjUser->pvConsumer = NULL;
 
     /* Fill internal object */
-    WndObjInt->Hwnd = hWnd;
-    WndObjInt->ChangeProc = pfn;
-    WndObjInt->Flags = fl;
-    WndObjInt->PixelFormat = iPixelFormat;
+    Clip->Hwnd = hWnd;
+    Clip->ChangeProc = pfn;
+    Clip->Flags = fl;
+    Clip->PixelFormat = iPixelFormat;
 
     /* associate object with window */
-    IntSetProp(Window, AtomWndObj, WndObjInt);
+    IntSetProp(Window, AtomWndObj, Clip);
     ++gcountPWO;
 
-    DPRINT("EngCreateWnd: SUCCESS!\n");
+    TRACE("EngCreateWnd: SUCCESS: %p!\n", WndObjUser);
 
     RETURN( WndObjUser);
 
@@ -260,11 +238,11 @@ APIENTRY
 EngDeleteWnd(
     IN WNDOBJ *pwo)
 {
-    WNDGDI *WndObjInt = ObjToGDI(pwo, WND);
+    XCLIPOBJ* Clip = CONTAINING_RECORD(pwo, XCLIPOBJ, WndObj);
     PWND Window;
     BOOL calledFromUser;
 
-    DPRINT("EngDeleteWnd: pwo = 0x%p\n", pwo);
+    TRACE("EngDeleteWnd: pwo = 0x%p\n", pwo);
 
     calledFromUser = UserIsEntered();
     if (!calledFromUser) {
@@ -272,10 +250,10 @@ EngDeleteWnd(
     }
 
     /* Get window object */
-    Window = UserGetWindowObject(WndObjInt->Hwnd);
+    Window = UserGetWindowObject(Clip->Hwnd);
     if (Window == NULL)
     {
-        DPRINT1("Warning: Couldnt get window object for WndObjInt->Hwnd!!!\n");
+        ERR("Couldnt get window object for WndObjInt->Hwnd!!!\n");
     }
     else
     {
@@ -289,8 +267,8 @@ EngDeleteWnd(
     }
 
     /* Free resources */
-    IntEngDeleteClipRegion(WndObjInt->ClientClipObj);
-    EngFreeMem(WndObjInt);
+    IntEngFreeClipResources(Clip);
+    EngFreeMem(Clip);
 }
 
 
@@ -304,14 +282,8 @@ WNDOBJ_bEnum(
     IN ULONG  cj,
     OUT ULONG  *pul)
 {
-    WNDGDI *WndObjInt = ObjToGDI(pwo, WND);
-    BOOL Ret;
-
-    DPRINT("WNDOBJ_bEnum: pwo = 0x%p, cj = %lu, pul = 0x%p\n", pwo, cj, pul);
-    Ret = CLIPOBJ_bEnum(WndObjInt->ClientClipObj, cj, pul);
-
-    DPRINT("WNDOBJ_bEnum: Returning %s\n", Ret ? "True" : "False");
-    return Ret;
+    /* Relay */
+    return CLIPOBJ_bEnum(&pwo->coClient, cj, pul);
 }
 
 
@@ -326,17 +298,9 @@ WNDOBJ_cEnumStart(
     IN ULONG  iDirection,
     IN ULONG  cLimit)
 {
-    WNDGDI *WndObjInt = ObjToGDI(pwo, WND);
-    ULONG Ret;
-
-    DPRINT("WNDOBJ_cEnumStart: pwo = 0x%p, iType = %lu, iDirection = %lu, cLimit = %lu\n",
-           pwo, iType, iDirection, cLimit);
-
-    /* FIXME: Should we enumerate all rectangles or not? */
-    Ret = CLIPOBJ_cEnumStart(WndObjInt->ClientClipObj, FALSE, iType, iDirection, cLimit);
-
-    DPRINT("WNDOBJ_cEnumStart: Returning 0x%lx\n", Ret);
-    return Ret;
+    /* Relay */
+    // FIXME: Should we enumerate all rectangles or not?
+    return CLIPOBJ_cEnumStart(&pwo->coClient, FALSE, iType, iDirection, cLimit);
 }
 
 
@@ -349,9 +313,10 @@ WNDOBJ_vSetConsumer(
     IN WNDOBJ  *pwo,
     IN PVOID  pvConsumer)
 {
+    XCLIPOBJ* Clip = CONTAINING_RECORD(pwo, XCLIPOBJ, WndObj);
     BOOL Hack;
 
-    DPRINT("WNDOBJ_vSetConsumer: pwo = 0x%p, pvConsumer = 0x%p\n", pwo, pvConsumer);
+    TRACE("WNDOBJ_vSetConsumer: pwo = 0x%p, pvConsumer = 0x%p\n", pwo, pvConsumer);
 
     Hack = (pwo->pvConsumer == NULL);
     pwo->pvConsumer = pvConsumer;
@@ -366,9 +331,10 @@ WNDOBJ_vSetConsumer(
      */
     if (Hack)
     {
-        IntEngWndCallChangeProc(pwo, WOC_RGN_CLIENT);
-        IntEngWndCallChangeProc(pwo, WOC_CHANGED);
-        IntEngWndCallChangeProc(pwo, WOC_DRAWN);
+        FIXME("Is this hack really needed?\n");
+        IntEngWndCallChangeProc(Clip, WOC_RGN_CLIENT);
+        IntEngWndCallChangeProc(Clip, WOC_CHANGED);
+        IntEngWndCallChangeProc(Clip, WOC_DRAWN);
     }
 }