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 if (Clip
->ChangeProc
== NULL
)
29 /* check flags of the WNDOBJ */
30 flChanged
&= Clip
->Flags
;
36 TRACE("Calling WNDOBJCHANGEPROC (0x%p), Changed = 0x%x\n",
37 Clip
->ChangeProc
, flChanged
);
39 /* Call the WNDOBJCHANGEPROC */
40 if (flChanged
== WOC_CHANGED
)
41 Clip
->ChangeProc(NULL
, flChanged
);
43 Clip
->ChangeProc(&Clip
->WndObj
, flChanged
);
47 * Fills the CLIPOBJ and client rect of the WNDOBJ with the data from the given WND
51 IntEngWndUpdateClipObj(
58 TRACE("IntEngWndUpdateClipObj\n");
60 hVisRgn
= VIS_ComputeVisibleRegion(Window
, TRUE
, TRUE
, TRUE
);
63 visRgn
= RGNOBJAPI_Lock(hVisRgn
, NULL
);
66 if (visRgn
->rdh
.nCount
> 0)
68 IntEngUpdateClipRegion(Clip
, visRgn
->rdh
.nCount
, visRgn
->Buffer
, &visRgn
->rdh
.rcBound
);
69 TRACE("Created visible region with %lu rects\n", visRgn
->rdh
.nCount
);
70 TRACE(" BoundingRect: %d, %d %d, %d\n",
71 visRgn
->rdh
.rcBound
.left
, visRgn
->rdh
.rcBound
.top
,
72 visRgn
->rdh
.rcBound
.right
, visRgn
->rdh
.rcBound
.bottom
);
75 for (i
= 0; i
< visRgn
->rdh
.nCount
; i
++)
77 TRACE(" Rect #%lu: %ld,%ld %ld,%ld\n", i
+1,
78 visRgn
->Buffer
[i
].left
, visRgn
->Buffer
[i
].top
,
79 visRgn
->Buffer
[i
].right
, visRgn
->Buffer
[i
].bottom
);
83 RGNOBJAPI_Unlock(visRgn
);
87 WARN("Couldn't lock visible region of window DC\n");
89 GreDeleteObject(hVisRgn
);
93 /* Fall back to client rect */
94 IntEngUpdateClipRegion(Clip
, 1, &Window
->rcClient
, &Window
->rcClient
);
97 /* Update the WNDOBJ */
98 Clip
->WndObj
.rclClient
= Window
->rcClient
;
99 Clip
->WndObj
.coClient
.iUniq
++;
105 * Updates all WNDOBJs of the given WND and calls the change-procs.
111 _In_ FLONG flChanged
)
115 ASSERT_IRQL_LESS_OR_EQUAL(PASSIVE_LEVEL
);
117 Clip
= UserGetProp(Window
, AtomWndObj
);
123 ASSERT(Clip
->Hwnd
== Window
->head
.h
);
124 // if (Clip->WndObj.pvConsumer != NULL)
126 /* Update the WNDOBJ */
130 /* Update the clipobj and client rect of the WNDOBJ */
131 IntEngWndUpdateClipObj(Clip
, Window
);
135 /* FIXME: Should the WNDOBJs be deleted by win32k or by the driver? */
139 /* Call the change proc */
140 IntEngWndCallChangeProc(Clip
, flChanged
);
142 /* HACK: Send WOC_CHANGED after WOC_RGN_CLIENT */
143 if (flChanged
== WOC_RGN_CLIENT
)
145 IntEngWndCallChangeProc(Clip
, WOC_CHANGED
);
158 WNDOBJCHANGEPROC pfn
,
162 XCLIPOBJ
*Clip
= NULL
;
163 WNDOBJ
*WndObjUser
= NULL
;
166 DECLARE_RETURN(WNDOBJ
*);
168 TRACE("EngCreateWnd: pso = 0x%p, hwnd = 0x%p, pfn = 0x%p, fl = 0x%lx, pixfmt = %d\n",
169 pso
, hWnd
, pfn
, fl
, iPixelFormat
);
171 if (fl
& (WO_RGN_WINDOW
| WO_RGN_DESKTOP_COORD
| WO_RGN_UPDATE_ALL
))
173 FIXME("Unsupported flags: 0x%lx\n", fl
& ~(WO_RGN_CLIENT_DELTA
| WO_RGN_CLIENT
| WO_RGN_SURFACE_DELTA
| WO_RGN_SURFACE
));
176 calledFromUser
= UserIsEntered();
177 if (!calledFromUser
) {
181 /* Get window object */
182 Window
= UserGetWindowObject(hWnd
);
189 Clip
= EngAllocMem(FL_ZERO_MEMORY
, sizeof (XCLIPOBJ
), GDITAG_WNDOBJ
);
192 ERR("Failed to allocate memory for a WND structure!\n");
195 IntEngInitClipObj(Clip
);
197 /* Fill the clipobj */
198 if (!IntEngWndUpdateClipObj(Clip
, Window
))
204 /* Fill user object */
205 WndObjUser
= &Clip
->WndObj
;
206 WndObjUser
->psoOwner
= pso
;
207 WndObjUser
->pvConsumer
= NULL
;
209 /* Fill internal object */
211 Clip
->ChangeProc
= pfn
;
212 /* Keep track of relevant flags */
213 Clip
->Flags
= fl
& (WO_RGN_CLIENT_DELTA
| WO_RGN_CLIENT
| WO_RGN_SURFACE_DELTA
| WO_RGN_SURFACE
| WO_DRAW_NOTIFY
);
214 if (fl
& WO_SPRITE_NOTIFY
)
215 Clip
->Flags
|= WOC_SPRITE_OVERLAP
| WOC_SPRITE_NO_OVERLAP
;
216 /* Those should always be sent */
217 Clip
->Flags
|= WOC_CHANGED
| WOC_DELETE
;
218 Clip
->PixelFormat
= iPixelFormat
;
220 /* associate object with window */
221 IntSetProp(Window
, AtomWndObj
, Clip
);
224 TRACE("EngCreateWnd: SUCCESS: %p!\n", WndObjUser
);
230 if (!calledFromUser
) {
246 XCLIPOBJ
* Clip
= CONTAINING_RECORD(pwo
, XCLIPOBJ
, WndObj
);
250 TRACE("EngDeleteWnd: pwo = 0x%p\n", pwo
);
252 calledFromUser
= UserIsEntered();
253 if (!calledFromUser
) {
254 UserEnterExclusive();
257 /* Get window object */
258 Window
= UserGetWindowObject(Clip
->Hwnd
);
261 ERR("Couldnt get window object for WndObjInt->Hwnd!!!\n");
265 /* Remove object from window */
266 IntRemoveProp(Window
, AtomWndObj
);
270 if (!calledFromUser
) {
275 IntEngFreeClipResources(Clip
);
291 return CLIPOBJ_bEnum(&pwo
->coClient
, cj
, pul
);
307 // FIXME: Should we enumerate all rectangles or not?
308 return CLIPOBJ_cEnumStart(&pwo
->coClient
, FALSE
, iType
, iDirection
, cLimit
);
321 XCLIPOBJ
* Clip
= CONTAINING_RECORD(pwo
, XCLIPOBJ
, WndObj
);
324 TRACE("WNDOBJ_vSetConsumer: pwo = 0x%p, pvConsumer = 0x%p\n", pwo
, pvConsumer
);
326 Hack
= (pwo
->pvConsumer
== NULL
);
327 pwo
->pvConsumer
= pvConsumer
;
331 * MSDN says that the WNDOBJCHANGEPROC will be called with the most recent state
332 * when a WNDOBJ is created - we do it here because most drivers will need pvConsumer
333 * in the callback to identify the WNDOBJ I think.
339 FIXME("Is this hack really needed?\n");
340 IntEngWndCallChangeProc(Clip
, WOC_RGN_CLIENT
);
341 IntEngWndCallChangeProc(Clip
, WOC_CHANGED
);
342 IntEngWndCallChangeProc(Clip
, WOC_DRAWN
);