* 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;
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);
}
/*
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;
}
_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:
}
/* 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);
}
}
}
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;
}
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);
}
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);
}
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);
}
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;
*/
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);
}
}