1c2c66affSColin Finck /*
2c2c66affSColin Finck * COPYRIGHT: See COPYING in the top level directory
3c2c66affSColin Finck * PROJECT: ReactOS kernel
4c2c66affSColin Finck * PURPOSE: GDI WNDOBJ Functions
5c2c66affSColin Finck * FILE: win32ss/gdi/eng/engwindow.c
6c2c66affSColin Finck * PROGRAMER: Gregor Anich
7c2c66affSColin Finck */
8c2c66affSColin Finck
9c2c66affSColin Finck #include <win32k.h>
10c2c66affSColin Finck #include <debug.h>
11c2c66affSColin Finck DBG_DEFAULT_CHANNEL(EngWnd);
12c2c66affSColin Finck
13c2c66affSColin Finck INT gcountPWO = 0;
14c2c66affSColin Finck
15c2c66affSColin Finck /*
16c2c66affSColin Finck * Calls the WNDOBJCHANGEPROC of the given WNDOBJ
17c2c66affSColin Finck */
18c2c66affSColin Finck VOID
19c2c66affSColin Finck FASTCALL
IntEngWndCallChangeProc(_In_ EWNDOBJ * Clip,_In_ FLONG flChanged)20c2c66affSColin Finck IntEngWndCallChangeProc(
21c2c66affSColin Finck _In_ EWNDOBJ *Clip,
22c2c66affSColin Finck _In_ FLONG flChanged)
23c2c66affSColin Finck {
24c2c66affSColin Finck if (Clip->ChangeProc == NULL)
25c2c66affSColin Finck {
26c2c66affSColin Finck return;
27c2c66affSColin Finck }
28c2c66affSColin Finck
29c2c66affSColin Finck /* check flags of the WNDOBJ */
30c2c66affSColin Finck flChanged &= Clip->Flags;
31c2c66affSColin Finck if (flChanged == 0)
32c2c66affSColin Finck {
33c2c66affSColin Finck return;
34c2c66affSColin Finck }
35c2c66affSColin Finck
36c2c66affSColin Finck TRACE("Calling WNDOBJCHANGEPROC (0x%p), Changed = 0x%x\n",
37c2c66affSColin Finck Clip->ChangeProc, flChanged);
38c2c66affSColin Finck
39c2c66affSColin Finck /* Call the WNDOBJCHANGEPROC */
40c2c66affSColin Finck if (flChanged == WOC_CHANGED)
41c2c66affSColin Finck Clip->ChangeProc(NULL, flChanged);
42c2c66affSColin Finck else
43c2c66affSColin Finck Clip->ChangeProc((WNDOBJ *)Clip, flChanged);
44c2c66affSColin Finck }
45c2c66affSColin Finck
46c2c66affSColin Finck /*
47c2c66affSColin Finck * Fills the CLIPOBJ and client rect of the WNDOBJ with the data from the given WND
48c2c66affSColin Finck */
49c2c66affSColin Finck BOOLEAN
50c2c66affSColin Finck FASTCALL
IntEngWndUpdateClipObj(EWNDOBJ * Clip,PWND Window)51c2c66affSColin Finck IntEngWndUpdateClipObj(
52c2c66affSColin Finck EWNDOBJ* Clip,
53c2c66affSColin Finck PWND Window)
54c2c66affSColin Finck {
55c2c66affSColin Finck PREGION visRgn;
56c2c66affSColin Finck
57c2c66affSColin Finck TRACE("IntEngWndUpdateClipObj\n");
58c2c66affSColin Finck
59c2c66affSColin Finck visRgn = VIS_ComputeVisibleRegion(Window, TRUE, TRUE, TRUE);
60c2c66affSColin Finck if (visRgn != NULL)
61c2c66affSColin Finck {
62c2c66affSColin Finck if (visRgn->rdh.nCount > 0)
63c2c66affSColin Finck {
64c2c66affSColin Finck IntEngUpdateClipRegion((XCLIPOBJ*)Clip, visRgn->rdh.nCount, visRgn->Buffer, &visRgn->rdh.rcBound);
65c2c66affSColin Finck TRACE("Created visible region with %lu rects\n", visRgn->rdh.nCount);
66c2c66affSColin Finck TRACE(" BoundingRect: %d, %d %d, %d\n",
67c2c66affSColin Finck visRgn->rdh.rcBound.left, visRgn->rdh.rcBound.top,
68c2c66affSColin Finck visRgn->rdh.rcBound.right, visRgn->rdh.rcBound.bottom);
69c2c66affSColin Finck {
70c2c66affSColin Finck ULONG i;
71c2c66affSColin Finck for (i = 0; i < visRgn->rdh.nCount; i++)
72c2c66affSColin Finck {
73c2c66affSColin Finck TRACE(" Rect #%lu: %ld,%ld %ld,%ld\n", i+1,
74c2c66affSColin Finck visRgn->Buffer[i].left, visRgn->Buffer[i].top,
75c2c66affSColin Finck visRgn->Buffer[i].right, visRgn->Buffer[i].bottom);
76c2c66affSColin Finck }
77c2c66affSColin Finck }
78c2c66affSColin Finck }
79c2c66affSColin Finck REGION_Delete(visRgn);
80c2c66affSColin Finck }
81c2c66affSColin Finck else
82c2c66affSColin Finck {
83c2c66affSColin Finck /* Fall back to client rect */
84c2c66affSColin Finck IntEngUpdateClipRegion((XCLIPOBJ*)Clip, 1, &Window->rcClient, &Window->rcClient);
85c2c66affSColin Finck }
86c2c66affSColin Finck
87c2c66affSColin Finck /* Update the WNDOBJ */
88c2c66affSColin Finck Clip->rclClient = Window->rcClient;
89c2c66affSColin Finck Clip->iUniq++;
90c2c66affSColin Finck
91c2c66affSColin Finck return TRUE;
92c2c66affSColin Finck }
93c2c66affSColin Finck
94c2c66affSColin Finck /*
95c2c66affSColin Finck * Updates all WNDOBJs of the given WND and calls the change-procs.
96c2c66affSColin Finck */
97c2c66affSColin Finck VOID
98c2c66affSColin Finck FASTCALL
IntEngWindowChanged(_In_ PWND Window,_In_ FLONG flChanged)99c2c66affSColin Finck IntEngWindowChanged(
100c2c66affSColin Finck _In_ PWND Window,
101c2c66affSColin Finck _In_ FLONG flChanged)
102c2c66affSColin Finck {
103c2c66affSColin Finck EWNDOBJ *Clip;
104c2c66affSColin Finck
105c2c66affSColin Finck ASSERT_IRQL_LESS_OR_EQUAL(PASSIVE_LEVEL);
106c2c66affSColin Finck
107c2c66affSColin Finck Clip = UserGetProp(Window, AtomWndObj, TRUE);
108c2c66affSColin Finck if (!Clip)
109c2c66affSColin Finck {
110c2c66affSColin Finck return;
111c2c66affSColin Finck }
112c2c66affSColin Finck
113c2c66affSColin Finck ASSERT(Clip->Hwnd == Window->head.h);
114c2c66affSColin Finck // if (Clip->pvConsumer != NULL)
115c2c66affSColin Finck {
116c2c66affSColin Finck /* Update the WNDOBJ */
117c2c66affSColin Finck switch (flChanged)
118c2c66affSColin Finck {
119c2c66affSColin Finck case WOC_RGN_CLIENT:
120c2c66affSColin Finck /* Update the clipobj and client rect of the WNDOBJ */
121c2c66affSColin Finck IntEngWndUpdateClipObj(Clip, Window);
122c2c66affSColin Finck break;
123c2c66affSColin Finck
124c2c66affSColin Finck case WOC_DELETE:
125c2c66affSColin Finck /* FIXME: Should the WNDOBJs be deleted by win32k or by the driver? */
126c2c66affSColin Finck break;
127c2c66affSColin Finck }
128c2c66affSColin Finck
129c2c66affSColin Finck /* Call the change proc */
130c2c66affSColin Finck IntEngWndCallChangeProc(Clip, flChanged);
131c2c66affSColin Finck
132c2c66affSColin Finck /* HACK: Send WOC_CHANGED after WOC_RGN_CLIENT */
133c2c66affSColin Finck if (flChanged == WOC_RGN_CLIENT)
134c2c66affSColin Finck {
135c2c66affSColin Finck IntEngWndCallChangeProc(Clip, WOC_CHANGED);
136c2c66affSColin Finck }
137c2c66affSColin Finck }
138c2c66affSColin Finck }
139c2c66affSColin Finck
140c2c66affSColin Finck /*
141c2c66affSColin Finck * @implemented
142c2c66affSColin Finck */
143c2c66affSColin Finck WNDOBJ*
144c2c66affSColin Finck APIENTRY
EngCreateWnd(SURFOBJ * pso,HWND hWnd,WNDOBJCHANGEPROC pfn,FLONG fl,int iPixelFormat)145c2c66affSColin Finck EngCreateWnd(
146c2c66affSColin Finck SURFOBJ *pso,
147c2c66affSColin Finck HWND hWnd,
148c2c66affSColin Finck WNDOBJCHANGEPROC pfn,
149c2c66affSColin Finck FLONG fl,
150c2c66affSColin Finck int iPixelFormat)
151c2c66affSColin Finck {
152c2c66affSColin Finck EWNDOBJ *Clip = NULL;
153c2c66affSColin Finck WNDOBJ *WndObjUser = NULL;
154c2c66affSColin Finck PWND Window;
155c2c66affSColin Finck
156c2c66affSColin Finck TRACE("EngCreateWnd: pso = 0x%p, hwnd = 0x%p, pfn = 0x%p, fl = 0x%lx, pixfmt = %d\n",
157c2c66affSColin Finck pso, hWnd, pfn, fl, iPixelFormat);
158c2c66affSColin Finck
159*89dbc88aSJérôme Gardou UserEnterExclusive();
160*89dbc88aSJérôme Gardou
161c2c66affSColin Finck if (fl & (WO_RGN_WINDOW | WO_RGN_DESKTOP_COORD | WO_RGN_UPDATE_ALL))
162c2c66affSColin Finck {
163c2c66affSColin Finck FIXME("Unsupported flags: 0x%lx\n", fl & ~(WO_RGN_CLIENT_DELTA | WO_RGN_CLIENT | WO_RGN_SURFACE_DELTA | WO_RGN_SURFACE));
164c2c66affSColin Finck }
165c2c66affSColin Finck
166c2c66affSColin Finck /* Get window object */
167c2c66affSColin Finck Window = UserGetWindowObject(hWnd);
168c2c66affSColin Finck if (Window == NULL)
169c2c66affSColin Finck {
170*89dbc88aSJérôme Gardou goto Exit;
171c2c66affSColin Finck }
172c2c66affSColin Finck
173c2c66affSColin Finck /* Create WNDOBJ */
174c2c66affSColin Finck Clip = EngAllocMem(FL_ZERO_MEMORY, sizeof(EWNDOBJ), GDITAG_WNDOBJ);
175c2c66affSColin Finck if (Clip == NULL)
176c2c66affSColin Finck {
177c2c66affSColin Finck ERR("Failed to allocate memory for a WND structure!\n");
178*89dbc88aSJérôme Gardou goto Exit;
179c2c66affSColin Finck }
180c2c66affSColin Finck IntEngInitClipObj((XCLIPOBJ*)Clip);
181c2c66affSColin Finck
182c2c66affSColin Finck /* Fill the clipobj */
183c2c66affSColin Finck if (!IntEngWndUpdateClipObj(Clip, Window))
184c2c66affSColin Finck {
185c2c66affSColin Finck EngFreeMem(Clip);
186*89dbc88aSJérôme Gardou goto Exit;
187c2c66affSColin Finck }
188c2c66affSColin Finck
189c2c66affSColin Finck /* Fill user object */
190c2c66affSColin Finck WndObjUser = (WNDOBJ *)Clip;
191c2c66affSColin Finck WndObjUser->psoOwner = pso;
192c2c66affSColin Finck WndObjUser->pvConsumer = NULL;
193c2c66affSColin Finck
194c2c66affSColin Finck /* Fill internal object */
195c2c66affSColin Finck Clip->Hwnd = hWnd;
196c2c66affSColin Finck Clip->ChangeProc = pfn;
197c2c66affSColin Finck /* Keep track of relevant flags */
198c2c66affSColin Finck Clip->Flags = fl & (WO_RGN_CLIENT_DELTA | WO_RGN_CLIENT | WO_RGN_SURFACE_DELTA | WO_RGN_SURFACE | WO_DRAW_NOTIFY);
199c2c66affSColin Finck if (fl & WO_SPRITE_NOTIFY)
200c2c66affSColin Finck Clip->Flags |= WOC_SPRITE_OVERLAP | WOC_SPRITE_NO_OVERLAP;
201c2c66affSColin Finck /* Those should always be sent */
202c2c66affSColin Finck Clip->Flags |= WOC_CHANGED | WOC_DELETE;
203c2c66affSColin Finck Clip->PixelFormat = iPixelFormat;
204c2c66affSColin Finck
205c2c66affSColin Finck /* associate object with window */
206c2c66affSColin Finck UserSetProp(Window, AtomWndObj, Clip, TRUE);
207c2c66affSColin Finck ++gcountPWO;
208c2c66affSColin Finck
209c2c66affSColin Finck TRACE("EngCreateWnd: SUCCESS: %p!\n", WndObjUser);
210c2c66affSColin Finck
211*89dbc88aSJérôme Gardou Exit:
212c2c66affSColin Finck UserLeave();
213*89dbc88aSJérôme Gardou return WndObjUser;
214c2c66affSColin Finck }
215c2c66affSColin Finck
216c2c66affSColin Finck
217c2c66affSColin Finck /*
218c2c66affSColin Finck * @implemented
219c2c66affSColin Finck */
220c2c66affSColin Finck VOID
221c2c66affSColin Finck APIENTRY
EngDeleteWnd(IN WNDOBJ * pwo)222c2c66affSColin Finck EngDeleteWnd(
223c2c66affSColin Finck IN WNDOBJ *pwo)
224c2c66affSColin Finck {
225c2c66affSColin Finck EWNDOBJ* Clip = (EWNDOBJ *)pwo;//CONTAINING_RECORD(pwo, XCLIPOBJ, WndObj);
226c2c66affSColin Finck PWND Window;
227c2c66affSColin Finck
228c2c66affSColin Finck TRACE("EngDeleteWnd: pwo = 0x%p\n", pwo);
229c2c66affSColin Finck
230c2c66affSColin Finck UserEnterExclusive();
231c2c66affSColin Finck
232c2c66affSColin Finck /* Get window object */
233c2c66affSColin Finck Window = UserGetWindowObject(Clip->Hwnd);
234c2c66affSColin Finck if (Window == NULL)
235c2c66affSColin Finck {
236c2c66affSColin Finck ERR("Couldnt get window object for WndObjInt->Hwnd!!!\n");
237c2c66affSColin Finck }
238c2c66affSColin Finck else
239c2c66affSColin Finck {
240c2c66affSColin Finck /* Remove object from window */
241c2c66affSColin Finck UserRemoveProp(Window, AtomWndObj, TRUE);
242c2c66affSColin Finck }
243c2c66affSColin Finck --gcountPWO;
244c2c66affSColin Finck
245c2c66affSColin Finck UserLeave();
246c2c66affSColin Finck
247c2c66affSColin Finck /* Free resources */
248c2c66affSColin Finck IntEngFreeClipResources((XCLIPOBJ*)Clip);
249c2c66affSColin Finck EngFreeMem(Clip);
250c2c66affSColin Finck }
251c2c66affSColin Finck
252c2c66affSColin Finck
253c2c66affSColin Finck /*
254c2c66affSColin Finck * @implemented
255c2c66affSColin Finck */
256c2c66affSColin Finck BOOL
257c2c66affSColin Finck APIENTRY
WNDOBJ_bEnum(IN WNDOBJ * pwo,IN ULONG cj,OUT ULONG * pul)258c2c66affSColin Finck WNDOBJ_bEnum(
259c2c66affSColin Finck IN WNDOBJ *pwo,
260c2c66affSColin Finck IN ULONG cj,
261c2c66affSColin Finck OUT ULONG *pul)
262c2c66affSColin Finck {
263c2c66affSColin Finck /* Relay */
264c2c66affSColin Finck return CLIPOBJ_bEnum(&pwo->coClient, cj, pul);
265c2c66affSColin Finck }
266c2c66affSColin Finck
267c2c66affSColin Finck
268c2c66affSColin Finck /*
269c2c66affSColin Finck * @implemented
270c2c66affSColin Finck */
271c2c66affSColin Finck ULONG
272c2c66affSColin Finck APIENTRY
WNDOBJ_cEnumStart(IN WNDOBJ * pwo,IN ULONG iType,IN ULONG iDirection,IN ULONG cLimit)273c2c66affSColin Finck WNDOBJ_cEnumStart(
274c2c66affSColin Finck IN WNDOBJ *pwo,
275c2c66affSColin Finck IN ULONG iType,
276c2c66affSColin Finck IN ULONG iDirection,
277c2c66affSColin Finck IN ULONG cLimit)
278c2c66affSColin Finck {
279c2c66affSColin Finck /* Relay */
280c2c66affSColin Finck // FIXME: Should we enumerate all rectangles or not?
281c2c66affSColin Finck return CLIPOBJ_cEnumStart(&pwo->coClient, FALSE, iType, iDirection, cLimit);
282c2c66affSColin Finck }
283c2c66affSColin Finck
284c2c66affSColin Finck
285c2c66affSColin Finck /*
286c2c66affSColin Finck * @implemented
287c2c66affSColin Finck */
288c2c66affSColin Finck VOID
289c2c66affSColin Finck APIENTRY
WNDOBJ_vSetConsumer(IN WNDOBJ * pwo,IN PVOID pvConsumer)290c2c66affSColin Finck WNDOBJ_vSetConsumer(
291c2c66affSColin Finck IN WNDOBJ *pwo,
292c2c66affSColin Finck IN PVOID pvConsumer)
293c2c66affSColin Finck {
294c2c66affSColin Finck EWNDOBJ* Clip = (EWNDOBJ *)pwo;//CONTAINING_RECORD(pwo, XCLIPOBJ, WndObj);
295c2c66affSColin Finck BOOL Hack;
296c2c66affSColin Finck
297c2c66affSColin Finck TRACE("WNDOBJ_vSetConsumer: pwo = 0x%p, pvConsumer = 0x%p\n", pwo, pvConsumer);
298c2c66affSColin Finck
299c2c66affSColin Finck Hack = (pwo->pvConsumer == NULL);
300c2c66affSColin Finck pwo->pvConsumer = pvConsumer;
301c2c66affSColin Finck
302c2c66affSColin Finck /* HACKHACKHACK
303c2c66affSColin Finck *
304c2c66affSColin Finck * MSDN says that the WNDOBJCHANGEPROC will be called with the most recent state
305c2c66affSColin Finck * when a WNDOBJ is created - we do it here because most drivers will need pvConsumer
306c2c66affSColin Finck * in the callback to identify the WNDOBJ I think.
307c2c66affSColin Finck *
308c2c66affSColin Finck * - blight
309c2c66affSColin Finck */
310c2c66affSColin Finck if (Hack)
311c2c66affSColin Finck {
312c2c66affSColin Finck FIXME("Is this hack really needed?\n");
313c2c66affSColin Finck IntEngWndCallChangeProc(Clip, WOC_RGN_CLIENT);
314c2c66affSColin Finck IntEngWndCallChangeProc(Clip, WOC_CHANGED);
315c2c66affSColin Finck IntEngWndCallChangeProc(Clip, WOC_DRAWN);
316c2c66affSColin Finck }
317c2c66affSColin Finck }
318c2c66affSColin Finck
319c2c66affSColin Finck /* EOF */
320c2c66affSColin Finck
321