[WIN32SS]
[reactos.git] / win32ss / gdi / eng / engwindow.c
index 423f61f..ec34394 100644 (file)
@@ -2,14 +2,13 @@
  * COPYRIGHT:         See COPYING in the top level directory
  * PROJECT:           ReactOS kernel
  * PURPOSE:           GDI WNDOBJ Functions
- * FILE:              subsystems/win32/win32k/eng/engwindow.c
+ * FILE:              win32ss/gdi/eng/engwindow.c
  * PROGRAMER:         Gregor Anich
  */
 
 #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_ EWNDOBJ *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((WNDOBJ *)Clip, flChanged);
 }
 
 /*
@@ -53,72 +49,44 @@ IntEngWndCallChangeProc(
 BOOLEAN
 FASTCALL
 IntEngWndUpdateClipObj(
-    WNDGDI *WndObjInt,
+    EWNDOBJ* Clip,
     PWND Window)
 {
-    HRGN hVisRgn;
-    PROSRGNDATA visRgn;
-    CLIPOBJ *ClipObj = NULL;
-    CLIPOBJ *OldClipObj;
+    PREGION visRgn;
 
-    DPRINT("IntEngWndUpdateClipObj\n");
+    TRACE("IntEngWndUpdateClipObj\n");
 
-    hVisRgn = VIS_ComputeVisibleRegion(Window, TRUE, TRUE, TRUE);
-    if (hVisRgn != NULL)
+    visRgn = VIS_ComputeVisibleRegion(Window, TRUE, TRUE, TRUE);
+    if (visRgn != NULL)
     {
-        NtGdiOffsetRgn(hVisRgn, Window->rcClient.left, Window->rcClient.top);
-        visRgn = RGNOBJAPI_Lock(hVisRgn, NULL);
-        if (visRgn != NULL)
+        if (visRgn->rdh.nCount > 0)
         {
-            if (visRgn->rdh.nCount > 0)
+            IntEngUpdateClipRegion((XCLIPOBJ*)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);
             {
-                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",
-                       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++)
                 {
-                    ULONG i;
-                    for (i = 0; i < visRgn->rdh.nCount; i++)
-                    {
-                        DPRINT("  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);
-                    }
+                    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);
                 }
             }
-            RGNOBJAPI_Unlock(visRgn);
         }
-        else
-        {
-            DPRINT1("Warning: Couldn't lock visible region of window DC\n");
-        }
-        GreDeleteObject(hVisRgn);
+        REGION_Delete(visRgn);
     }
     else
-    {
-        DPRINT1("Warning: VIS_ComputeVisibleRegion failed!\n");
-    }
-
-    if (ClipObj == NULL)
     {
         /* Fall back to client rect */
-        ClipObj = IntEngCreateClipRegion(1, &Window->rcClient,
-                                         &Window->rcClient);
-    }
-
-    if (ClipObj == NULL)
-    {
-        DPRINT1("Warning: IntEngCreateClipRegion() failed!\n");
-        return FALSE;
+        IntEngUpdateClipRegion((XCLIPOBJ*)Clip, 1, &Window->rcClient, &Window->rcClient);
     }
 
-    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->rclClient = Window->rcClient;
+    Clip->iUniq++;
 
     return TRUE;
 }
@@ -132,30 +100,25 @@ IntEngWindowChanged(
     _In_    PWND  Window,
     _In_    FLONG flChanged)
 {
-    PPROPERTY pprop;
-    WNDGDI *Current;
-    HWND hWnd;
+    EWNDOBJ *Clip;
 
     ASSERT_IRQL_LESS_OR_EQUAL(PASSIVE_LEVEL);
 
-    hWnd = Window->head.h;
-    pprop = IntGetProp(Window, AtomWndObj);
-    if (!pprop)
+    Clip = UserGetProp(Window, AtomWndObj, TRUE);
+    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->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 +127,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,69 +149,68 @@ EngCreateWnd(
     FLONG             fl,
     int               iPixelFormat)
 {
-    WNDGDI *WndObjInt = NULL;
+    EWNDOBJ *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();
-    if (!calledFromUser) {
-        UserEnterShared();
+    UserEnterExclusive();
+
+    if (fl & (WO_RGN_WINDOW | WO_RGN_DESKTOP_COORD | WO_RGN_UPDATE_ALL))
+    {
+        FIXME("Unsupported flags: 0x%lx\n", fl & ~(WO_RGN_CLIENT_DELTA | WO_RGN_CLIENT | WO_RGN_SURFACE_DELTA | WO_RGN_SURFACE));
     }
 
     /* Get window object */
     Window = UserGetWindowObject(hWnd);
     if (Window == NULL)
     {
-        RETURN( NULL);
+        goto Exit;
     }
 
     /* Create WNDOBJ */
-    WndObjInt = EngAllocMem(0, sizeof (WNDGDI), GDITAG_WNDOBJ);
-    if (WndObjInt == NULL)
+    Clip = EngAllocMem(FL_ZERO_MEMORY, sizeof(EWNDOBJ), GDITAG_WNDOBJ);
+    if (Clip == NULL)
     {
-        DPRINT1("Failed to allocate memory for a WND structure!\n");
-        RETURN( NULL);
+        ERR("Failed to allocate memory for a WND structure!\n");
+        goto Exit;
     }
+    IntEngInitClipObj((XCLIPOBJ*)Clip);
 
     /* Fill the clipobj */
-    WndObjInt->ClientClipObj = NULL;
-    if (!IntEngWndUpdateClipObj(WndObjInt, Window))
+    if (!IntEngWndUpdateClipObj(Clip, Window))
     {
-        EngFreeMem(WndObjInt);
-        RETURN( NULL);
+        EngFreeMem(Clip);
+        goto Exit;
     }
 
     /* Fill user object */
-    WndObjUser = GDIToObj(WndObjInt, WND);
+    WndObjUser = (WNDOBJ *)Clip;
     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;
+    /* Keep track of relevant flags */
+    Clip->Flags = fl & (WO_RGN_CLIENT_DELTA | WO_RGN_CLIENT | WO_RGN_SURFACE_DELTA | WO_RGN_SURFACE | WO_DRAW_NOTIFY);
+    if (fl & WO_SPRITE_NOTIFY)
+        Clip->Flags |= WOC_SPRITE_OVERLAP | WOC_SPRITE_NO_OVERLAP;
+    /* Those should always be sent */
+    Clip->Flags |= WOC_CHANGED | WOC_DELETE;
+    Clip->PixelFormat = iPixelFormat;
 
     /* associate object with window */
-    IntSetProp(Window, AtomWndObj, WndObjInt);
+    UserSetProp(Window, AtomWndObj, Clip, TRUE);
     ++gcountPWO;
 
-    DPRINT("EngCreateWnd: SUCCESS!\n");
-
-    RETURN( WndObjUser);
-
-CLEANUP:
-
-    if (!calledFromUser) {
-        UserLeave();
-    }
+    TRACE("EngCreateWnd: SUCCESS: %p!\n", WndObjUser);
 
-    END_CLEANUP;
+Exit:
+    UserLeave();
+    return WndObjUser;
 }
 
 
@@ -260,37 +222,31 @@ APIENTRY
 EngDeleteWnd(
     IN WNDOBJ *pwo)
 {
-    WNDGDI *WndObjInt = ObjToGDI(pwo, WND);
+    EWNDOBJ* Clip = (EWNDOBJ *)pwo;//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) {
-        UserEnterExclusive();
-    }
+    UserEnterExclusive();
 
     /* 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
     {
         /* Remove object from window */
-        IntRemoveProp(Window, AtomWndObj);
-        --gcountPWO;
+        UserRemoveProp(Window, AtomWndObj, TRUE);
     }
+    --gcountPWO;
 
-    if (!calledFromUser) {
-        UserLeave();
-    }
+    UserLeave();
 
     /* Free resources */
-    IntEngDeleteClipRegion(WndObjInt->ClientClipObj);
-    EngFreeMem(WndObjInt);
+    IntEngFreeClipResources((XCLIPOBJ*)Clip);
+    EngFreeMem(Clip);
 }
 
 
@@ -304,14 +260,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 +276,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 +291,10 @@ WNDOBJ_vSetConsumer(
     IN WNDOBJ  *pwo,
     IN PVOID  pvConsumer)
 {
+    EWNDOBJ* Clip = (EWNDOBJ *)pwo;//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 +309,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);
     }
 }