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
11 DBG_DEFAULT_CHANNEL(EngWnd
);
16 * Calls the WNDOBJCHANGEPROC of the given WNDOBJ
20 IntEngWndCallChangeProc(
24 XCLIPOBJ
* Clip
= CONTAINING_RECORD(pwo
, XCLIPOBJ
, WndObj
);
26 if (Clip
->ChangeProc
== NULL
)
31 /* check flags of the WNDOBJ */
32 flChanged
&= Clip
->Flags
;
38 /* Call the WNDOBJCHANGEPROC */
39 if (flChanged
== WOC_CHANGED
)
44 TRACE("Calling WNDOBJCHANGEPROC (0x%p), Changed = 0x%x\n",
45 Clip
->ChangeProc
, flChanged
);
46 Clip
->ChangeProc(pwo
, flChanged
);
50 * Fills the CLIPOBJ and client rect of the WNDOBJ with the data from the given WND
54 IntEngWndUpdateClipObj(
61 TRACE("IntEngWndUpdateClipObj\n");
63 hVisRgn
= VIS_ComputeVisibleRegion(Window
, TRUE
, TRUE
, TRUE
);
66 visRgn
= RGNOBJAPI_Lock(hVisRgn
, NULL
);
69 if (visRgn
->rdh
.nCount
> 0)
71 IntEngUpdateClipRegion(Clip
, visRgn
->rdh
.nCount
, visRgn
->Buffer
, &visRgn
->rdh
.rcBound
);
72 TRACE("Created visible region with %lu rects\n", visRgn
->rdh
.nCount
);
73 TRACE(" BoundingRect: %d, %d %d, %d\n",
74 visRgn
->rdh
.rcBound
.left
, visRgn
->rdh
.rcBound
.top
,
75 visRgn
->rdh
.rcBound
.right
, visRgn
->rdh
.rcBound
.bottom
);
78 for (i
= 0; i
< visRgn
->rdh
.nCount
; i
++)
80 TRACE(" Rect #%lu: %ld,%ld %ld,%ld\n", i
+1,
81 visRgn
->Buffer
[i
].left
, visRgn
->Buffer
[i
].top
,
82 visRgn
->Buffer
[i
].right
, visRgn
->Buffer
[i
].bottom
);
86 RGNOBJAPI_Unlock(visRgn
);
90 WARN("Couldn't lock visible region of window DC\n");
92 GreDeleteObject(hVisRgn
);
96 /* Fall back to client rect */
97 IntEngUpdateClipRegion(Clip
, 1, &Window
->rcClient
, &Window
->rcClient
);
100 /* Update the WNDOBJ */
101 Clip
->WndObj
.rclClient
= Window
->rcClient
;
107 * Updates all WNDOBJs of the given WND and calls the change-procs.
113 _In_ FLONG flChanged
)
119 ASSERT_IRQL_LESS_OR_EQUAL(PASSIVE_LEVEL
);
121 hWnd
= Window
->head
.h
;
122 pprop
= IntGetProp(Window
, AtomWndObj
);
127 Current
= (XCLIPOBJ
*)pprop
->Data
;
130 Current
->Hwnd
== hWnd
&&
131 Current
->WndObj
.pvConsumer
!= NULL
)
133 /* Update the WNDOBJ */
137 /* Update the clipobj and client rect of the WNDOBJ */
138 IntEngWndUpdateClipObj(Current
, Window
);
142 /* FIXME: Should the WNDOBJs be deleted by win32k or by the driver? */
146 /* Call the change proc */
147 IntEngWndCallChangeProc(&Current
->WndObj
, flChanged
);
149 /* HACK: Send WOC_CHANGED after WOC_RGN_CLIENT */
150 if (flChanged
== WOC_RGN_CLIENT
)
152 IntEngWndCallChangeProc(&Current
->WndObj
, WOC_CHANGED
);
165 WNDOBJCHANGEPROC pfn
,
169 XCLIPOBJ
*Clip
= NULL
;
170 WNDOBJ
*WndObjUser
= NULL
;
173 DECLARE_RETURN(WNDOBJ
*);
175 TRACE("EngCreateWnd: pso = 0x%p, hwnd = 0x%p, pfn = 0x%p, fl = 0x%lx, pixfmt = %d\n",
176 pso
, hWnd
, pfn
, fl
, iPixelFormat
);
178 calledFromUser
= UserIsEntered();
179 if (!calledFromUser
) {
183 /* Get window object */
184 Window
= UserGetWindowObject(hWnd
);
191 Clip
= EngAllocMem(FL_ZERO_MEMORY
, sizeof (XCLIPOBJ
), GDITAG_WNDOBJ
);
194 ERR("Failed to allocate memory for a WND structure!\n");
197 IntEngInitClipObj(Clip
);
199 /* Fill the clipobj */
200 if (!IntEngWndUpdateClipObj(Clip
, Window
))
206 /* Fill user object */
207 WndObjUser
= &Clip
->WndObj
;
208 WndObjUser
->psoOwner
= pso
;
209 WndObjUser
->pvConsumer
= NULL
;
211 /* Fill internal object */
213 Clip
->ChangeProc
= pfn
;
215 Clip
->PixelFormat
= iPixelFormat
;
217 /* associate object with window */
218 IntSetProp(Window
, AtomWndObj
, Clip
);
221 TRACE("EngCreateWnd: SUCCESS!\n");
227 if (!calledFromUser
) {
243 XCLIPOBJ
* Clip
= CONTAINING_RECORD(pwo
, XCLIPOBJ
, WndObj
);
247 TRACE("EngDeleteWnd: pwo = 0x%p\n", pwo
);
249 calledFromUser
= UserIsEntered();
250 if (!calledFromUser
) {
251 UserEnterExclusive();
254 /* Get window object */
255 Window
= UserGetWindowObject(Clip
->Hwnd
);
258 ERR("Couldnt get window object for WndObjInt->Hwnd!!!\n");
262 /* Remove object from window */
263 IntRemoveProp(Window
, AtomWndObj
);
267 if (!calledFromUser
) {
272 IntEngFreeClipResources(Clip
);
288 return CLIPOBJ_bEnum(&pwo
->coClient
, cj
, pul
);
304 // FIXME: Should we enumerate all rectangles or not?
305 return CLIPOBJ_cEnumStart(&pwo
->coClient
, FALSE
, iType
, iDirection
, cLimit
);
320 TRACE("WNDOBJ_vSetConsumer: pwo = 0x%p, pvConsumer = 0x%p\n", pwo
, pvConsumer
);
322 Hack
= (pwo
->pvConsumer
== NULL
);
323 pwo
->pvConsumer
= pvConsumer
;
327 * MSDN says that the WNDOBJCHANGEPROC will be called with the most recent state
328 * when a WNDOBJ is created - we do it here because most drivers will need pvConsumer
329 * in the callback to identify the WNDOBJ I think.
335 FIXME("Is this hack really needed?\n");
336 IntEngWndCallChangeProc(pwo
, WOC_RGN_CLIENT
);
337 IntEngWndCallChangeProc(pwo
, WOC_CHANGED
);
338 IntEngWndCallChangeProc(pwo
, WOC_DRAWN
);