xref: /reactos/win32ss/gdi/eng/engwindow.c (revision 89dbc88a)
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