86560c9770df9f15c805cbbc6820a330618b5602
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
;
104 * Updates all WNDOBJs of the given WND and calls the change-procs.
110 _In_ FLONG flChanged
)
115 * This function is broken because AtomWndObj conflicts with
116 * properties set from user mode using SetPropW
120 ASSERT_IRQL_LESS_OR_EQUAL(PASSIVE_LEVEL
);
122 Clip
= UserGetProp(Window
, AtomWndObj
);
128 ASSERT(Clip
->Hwnd
== Window
->head
.h
);
129 if (Clip
->WndObj
.pvConsumer
!= NULL
)
131 /* Update the WNDOBJ */
135 /* Update the clipobj and client rect of the WNDOBJ */
136 IntEngWndUpdateClipObj(Clip
, Window
);
140 /* FIXME: Should the WNDOBJs be deleted by win32k or by the driver? */
144 /* Call the change proc */
145 IntEngWndCallChangeProc(Clip
, flChanged
);
147 /* HACK: Send WOC_CHANGED after WOC_RGN_CLIENT */
148 if (flChanged
== WOC_RGN_CLIENT
)
150 IntEngWndCallChangeProc(Clip
, WOC_CHANGED
);
163 WNDOBJCHANGEPROC pfn
,
167 XCLIPOBJ
*Clip
= NULL
;
168 WNDOBJ
*WndObjUser
= NULL
;
171 DECLARE_RETURN(WNDOBJ
*);
173 TRACE("EngCreateWnd: pso = 0x%p, hwnd = 0x%p, pfn = 0x%p, fl = 0x%lx, pixfmt = %d\n",
174 pso
, hWnd
, pfn
, fl
, iPixelFormat
);
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
;
213 Clip
->PixelFormat
= iPixelFormat
;
215 /* associate object with window */
216 IntSetProp(Window
, AtomWndObj
, Clip
);
219 TRACE("EngCreateWnd: SUCCESS: %p!\n", WndObjUser
);
225 if (!calledFromUser
) {
241 XCLIPOBJ
* Clip
= CONTAINING_RECORD(pwo
, XCLIPOBJ
, WndObj
);
245 TRACE("EngDeleteWnd: pwo = 0x%p\n", pwo
);
247 calledFromUser
= UserIsEntered();
248 if (!calledFromUser
) {
249 UserEnterExclusive();
252 /* Get window object */
253 Window
= UserGetWindowObject(Clip
->Hwnd
);
256 ERR("Couldnt get window object for WndObjInt->Hwnd!!!\n");
260 /* Remove object from window */
261 IntRemoveProp(Window
, AtomWndObj
);
265 if (!calledFromUser
) {
270 IntEngFreeClipResources(Clip
);
286 return CLIPOBJ_bEnum(&pwo
->coClient
, cj
, pul
);
302 // FIXME: Should we enumerate all rectangles or not?
303 return CLIPOBJ_cEnumStart(&pwo
->coClient
, FALSE
, iType
, iDirection
, cLimit
);
316 XCLIPOBJ
* Clip
= CONTAINING_RECORD(pwo
, XCLIPOBJ
, WndObj
);
319 TRACE("WNDOBJ_vSetConsumer: pwo = 0x%p, pvConsumer = 0x%p\n", pwo
, pvConsumer
);
321 Hack
= (pwo
->pvConsumer
== NULL
);
322 pwo
->pvConsumer
= pvConsumer
;
326 * MSDN says that the WNDOBJCHANGEPROC will be called with the most recent state
327 * when a WNDOBJ is created - we do it here because most drivers will need pvConsumer
328 * in the callback to identify the WNDOBJ I think.
334 FIXME("Is this hack really needed?\n");
335 IntEngWndCallChangeProc(Clip
, WOC_RGN_CLIENT
);
336 IntEngWndCallChangeProc(Clip
, WOC_CHANGED
);
337 IntEngWndCallChangeProc(Clip
, WOC_DRAWN
);