2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * PURPOSE: GDI WNDOBJ Functions
5 * FILE: subsystems/win32/win32k/eng/engwindow.c
6 * PROGRAMER: Gregor Anich
17 * Calls the WNDOBJCHANGEPROC of the given WNDOBJ
21 IntEngWndCallChangeProc(
25 WNDGDI
*WndObjInt
= ObjToGDI(pwo
, WND
);
27 if (WndObjInt
->ChangeProc
== NULL
)
32 /* check flags of the WNDOBJ */
33 flChanged
&= WndObjInt
->Flags
;
39 /* Call the WNDOBJCHANGEPROC */
40 if (flChanged
== WOC_CHANGED
)
45 DPRINT("Calling WNDOBJCHANGEPROC (0x%p), Changed = 0x%x\n",
46 WndObjInt
->ChangeProc
, flChanged
);
47 WndObjInt
->ChangeProc(pwo
, flChanged
);
51 * Fills the CLIPOBJ and client rect of the WNDOBJ with the data from the given WND
55 IntEngWndUpdateClipObj(
61 CLIPOBJ
*ClipObj
= NULL
;
64 DPRINT("IntEngWndUpdateClipObj\n");
66 hVisRgn
= VIS_ComputeVisibleRegion(Window
, TRUE
, TRUE
, TRUE
);
69 NtGdiOffsetRgn(hVisRgn
, Window
->rcClient
.left
, Window
->rcClient
.top
);
70 visRgn
= RGNOBJAPI_Lock(hVisRgn
, NULL
);
73 if (visRgn
->rdh
.nCount
> 0)
75 ClipObj
= IntEngCreateClipRegion(visRgn
->rdh
.nCount
, visRgn
->Buffer
,
76 &visRgn
->rdh
.rcBound
);
77 DPRINT("Created visible region with %lu rects\n", visRgn
->rdh
.nCount
);
78 DPRINT(" BoundingRect: %d, %d %d, %d\n",
79 visRgn
->rdh
.rcBound
.left
, visRgn
->rdh
.rcBound
.top
,
80 visRgn
->rdh
.rcBound
.right
, visRgn
->rdh
.rcBound
.bottom
);
83 for (i
= 0; i
< visRgn
->rdh
.nCount
; i
++)
85 DPRINT(" Rect #%lu: %ld,%ld %ld,%ld\n", i
+1,
86 visRgn
->Buffer
[i
].left
, visRgn
->Buffer
[i
].top
,
87 visRgn
->Buffer
[i
].right
, visRgn
->Buffer
[i
].bottom
);
91 RGNOBJAPI_Unlock(visRgn
);
95 DPRINT1("Warning: Couldn't lock visible region of window DC\n");
97 GreDeleteObject(hVisRgn
);
101 DPRINT1("Warning: VIS_ComputeVisibleRegion failed!\n");
106 /* Fall back to client rect */
107 ClipObj
= IntEngCreateClipRegion(1, &Window
->rcClient
,
113 DPRINT1("Warning: IntEngCreateClipRegion() failed!\n");
117 RtlCopyMemory(&WndObjInt
->WndObj
.coClient
, ClipObj
, sizeof (CLIPOBJ
));
118 RtlCopyMemory(&WndObjInt
->WndObj
.rclClient
, &Window
->rcClient
, sizeof (RECT
));
119 OldClipObj
= InterlockedExchangePointer((PVOID
*)&WndObjInt
->ClientClipObj
, ClipObj
);
120 if (OldClipObj
!= NULL
)
121 IntEngDeleteClipRegion(OldClipObj
);
127 * Updates all WNDOBJs of the given WND and calls the change-procs.
133 _In_ FLONG flChanged
)
139 ASSERT_IRQL_LESS_OR_EQUAL(PASSIVE_LEVEL
);
141 hWnd
= Window
->head
.h
;
142 pprop
= IntGetProp(Window
, AtomWndObj
);
147 Current
= (WNDGDI
*)pprop
->Data
;
150 Current
->Hwnd
== hWnd
&&
151 Current
->WndObj
.pvConsumer
!= NULL
)
153 /* Update the WNDOBJ */
157 /* Update the clipobj and client rect of the WNDOBJ */
158 IntEngWndUpdateClipObj(Current
, Window
);
162 /* FIXME: Should the WNDOBJs be deleted by win32k or by the driver? */
166 /* Call the change proc */
167 IntEngWndCallChangeProc(&Current
->WndObj
, flChanged
);
169 /* HACK: Send WOC_CHANGED after WOC_RGN_CLIENT */
170 if (flChanged
== WOC_RGN_CLIENT
)
172 IntEngWndCallChangeProc(&Current
->WndObj
, WOC_CHANGED
);
185 WNDOBJCHANGEPROC pfn
,
189 WNDGDI
*WndObjInt
= NULL
;
190 WNDOBJ
*WndObjUser
= NULL
;
193 DECLARE_RETURN(WNDOBJ
*);
195 DPRINT1("EngCreateWnd: pso = 0x%p, hwnd = 0x%p, pfn = 0x%p, fl = 0x%lx, pixfmt = %d\n",
196 pso
, hWnd
, pfn
, fl
, iPixelFormat
);
198 calledFromUser
= UserIsEntered();
199 if (!calledFromUser
) {
203 /* Get window object */
204 Window
= UserGetWindowObject(hWnd
);
211 WndObjInt
= EngAllocMem(0, sizeof (WNDGDI
), GDITAG_WNDOBJ
);
212 if (WndObjInt
== NULL
)
214 DPRINT1("Failed to allocate memory for a WND structure!\n");
218 /* Fill the clipobj */
219 WndObjInt
->ClientClipObj
= NULL
;
220 if (!IntEngWndUpdateClipObj(WndObjInt
, Window
))
222 EngFreeMem(WndObjInt
);
226 /* Fill user object */
227 WndObjUser
= GDIToObj(WndObjInt
, WND
);
228 WndObjUser
->psoOwner
= pso
;
229 WndObjUser
->pvConsumer
= NULL
;
231 /* Fill internal object */
232 WndObjInt
->Hwnd
= hWnd
;
233 WndObjInt
->ChangeProc
= pfn
;
234 WndObjInt
->Flags
= fl
;
235 WndObjInt
->PixelFormat
= iPixelFormat
;
237 /* associate object with window */
238 IntSetProp(Window
, AtomWndObj
, WndObjInt
);
241 DPRINT("EngCreateWnd: SUCCESS!\n");
247 if (!calledFromUser
) {
263 WNDGDI
*WndObjInt
= ObjToGDI(pwo
, WND
);
267 DPRINT("EngDeleteWnd: pwo = 0x%p\n", pwo
);
269 calledFromUser
= UserIsEntered();
270 if (!calledFromUser
) {
271 UserEnterExclusive();
274 /* Get window object */
275 Window
= UserGetWindowObject(WndObjInt
->Hwnd
);
278 DPRINT1("Warning: Couldnt get window object for WndObjInt->Hwnd!!!\n");
282 /* Remove object from window */
283 IntRemoveProp(Window
, AtomWndObj
);
287 if (!calledFromUser
) {
292 IntEngDeleteClipRegion(WndObjInt
->ClientClipObj
);
293 EngFreeMem(WndObjInt
);
307 WNDGDI
*WndObjInt
= ObjToGDI(pwo
, WND
);
310 DPRINT("WNDOBJ_bEnum: pwo = 0x%p, cj = %lu, pul = 0x%p\n", pwo
, cj
, pul
);
311 Ret
= CLIPOBJ_bEnum(WndObjInt
->ClientClipObj
, cj
, pul
);
313 DPRINT("WNDOBJ_bEnum: Returning %s\n", Ret
? "True" : "False");
329 WNDGDI
*WndObjInt
= ObjToGDI(pwo
, WND
);
332 DPRINT("WNDOBJ_cEnumStart: pwo = 0x%p, iType = %lu, iDirection = %lu, cLimit = %lu\n",
333 pwo
, iType
, iDirection
, cLimit
);
335 /* FIXME: Should we enumerate all rectangles or not? */
336 Ret
= CLIPOBJ_cEnumStart(WndObjInt
->ClientClipObj
, FALSE
, iType
, iDirection
, cLimit
);
338 DPRINT("WNDOBJ_cEnumStart: Returning 0x%lx\n", Ret
);
354 DPRINT("WNDOBJ_vSetConsumer: pwo = 0x%p, pvConsumer = 0x%p\n", pwo
, pvConsumer
);
356 Hack
= (pwo
->pvConsumer
== NULL
);
357 pwo
->pvConsumer
= pvConsumer
;
361 * MSDN says that the WNDOBJCHANGEPROC will be called with the most recent state
362 * when a WNDOBJ is created - we do it here because most drivers will need pvConsumer
363 * in the callback to identify the WNDOBJ I think.
369 IntEngWndCallChangeProc(pwo
, WOC_RGN_CLIENT
);
370 IntEngWndCallChangeProc(pwo
, WOC_CHANGED
);
371 IntEngWndCallChangeProc(pwo
, WOC_DRAWN
);