2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * PURPOSE: GDI WNDOBJ Functions
5 * FILE: win32ss/gdi/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((WNDOBJ
*)Clip
, flChanged
);
47 * Fills the CLIPOBJ and client rect of the WNDOBJ with the data from the given WND
51 IntEngWndUpdateClipObj(
57 TRACE("IntEngWndUpdateClipObj\n");
59 visRgn
= VIS_ComputeVisibleRegion(Window
, TRUE
, TRUE
, TRUE
);
62 if (visRgn
->rdh
.nCount
> 0)
64 IntEngUpdateClipRegion((XCLIPOBJ
*)Clip
, visRgn
->rdh
.nCount
, visRgn
->Buffer
, &visRgn
->rdh
.rcBound
);
65 TRACE("Created visible region with %lu rects\n", visRgn
->rdh
.nCount
);
66 TRACE(" BoundingRect: %d, %d %d, %d\n",
67 visRgn
->rdh
.rcBound
.left
, visRgn
->rdh
.rcBound
.top
,
68 visRgn
->rdh
.rcBound
.right
, visRgn
->rdh
.rcBound
.bottom
);
71 for (i
= 0; i
< visRgn
->rdh
.nCount
; i
++)
73 TRACE(" Rect #%lu: %ld,%ld %ld,%ld\n", i
+1,
74 visRgn
->Buffer
[i
].left
, visRgn
->Buffer
[i
].top
,
75 visRgn
->Buffer
[i
].right
, visRgn
->Buffer
[i
].bottom
);
79 REGION_Delete(visRgn
);
83 /* Fall back to client rect */
84 IntEngUpdateClipRegion((XCLIPOBJ
*)Clip
, 1, &Window
->rcClient
, &Window
->rcClient
);
87 /* Update the WNDOBJ */
88 Clip
->rclClient
= Window
->rcClient
;
95 * Updates all WNDOBJs of the given WND and calls the change-procs.
101 _In_ FLONG flChanged
)
105 ASSERT_IRQL_LESS_OR_EQUAL(PASSIVE_LEVEL
);
107 Clip
= UserGetProp(Window
, AtomWndObj
, TRUE
);
113 ASSERT(Clip
->Hwnd
== Window
->head
.h
);
114 // if (Clip->pvConsumer != NULL)
116 /* Update the WNDOBJ */
120 /* Update the clipobj and client rect of the WNDOBJ */
121 IntEngWndUpdateClipObj(Clip
, Window
);
125 /* FIXME: Should the WNDOBJs be deleted by win32k or by the driver? */
129 /* Call the change proc */
130 IntEngWndCallChangeProc(Clip
, flChanged
);
132 /* HACK: Send WOC_CHANGED after WOC_RGN_CLIENT */
133 if (flChanged
== WOC_RGN_CLIENT
)
135 IntEngWndCallChangeProc(Clip
, WOC_CHANGED
);
148 WNDOBJCHANGEPROC pfn
,
152 EWNDOBJ
*Clip
= NULL
;
153 WNDOBJ
*WndObjUser
= NULL
;
156 TRACE("EngCreateWnd: pso = 0x%p, hwnd = 0x%p, pfn = 0x%p, fl = 0x%lx, pixfmt = %d\n",
157 pso
, hWnd
, pfn
, fl
, iPixelFormat
);
159 UserEnterExclusive();
161 if (fl
& (WO_RGN_WINDOW
| WO_RGN_DESKTOP_COORD
| WO_RGN_UPDATE_ALL
))
163 FIXME("Unsupported flags: 0x%lx\n", fl
& ~(WO_RGN_CLIENT_DELTA
| WO_RGN_CLIENT
| WO_RGN_SURFACE_DELTA
| WO_RGN_SURFACE
));
166 /* Get window object */
167 Window
= UserGetWindowObject(hWnd
);
174 Clip
= EngAllocMem(FL_ZERO_MEMORY
, sizeof(EWNDOBJ
), GDITAG_WNDOBJ
);
177 ERR("Failed to allocate memory for a WND structure!\n");
180 IntEngInitClipObj((XCLIPOBJ
*)Clip
);
182 /* Fill the clipobj */
183 if (!IntEngWndUpdateClipObj(Clip
, Window
))
189 /* Fill user object */
190 WndObjUser
= (WNDOBJ
*)Clip
;
191 WndObjUser
->psoOwner
= pso
;
192 WndObjUser
->pvConsumer
= NULL
;
194 /* Fill internal object */
196 Clip
->ChangeProc
= pfn
;
197 /* Keep track of relevant flags */
198 Clip
->Flags
= fl
& (WO_RGN_CLIENT_DELTA
| WO_RGN_CLIENT
| WO_RGN_SURFACE_DELTA
| WO_RGN_SURFACE
| WO_DRAW_NOTIFY
);
199 if (fl
& WO_SPRITE_NOTIFY
)
200 Clip
->Flags
|= WOC_SPRITE_OVERLAP
| WOC_SPRITE_NO_OVERLAP
;
201 /* Those should always be sent */
202 Clip
->Flags
|= WOC_CHANGED
| WOC_DELETE
;
203 Clip
->PixelFormat
= iPixelFormat
;
205 /* associate object with window */
206 UserSetProp(Window
, AtomWndObj
, Clip
, TRUE
);
209 TRACE("EngCreateWnd: SUCCESS: %p!\n", WndObjUser
);
225 EWNDOBJ
* Clip
= (EWNDOBJ
*)pwo
;//CONTAINING_RECORD(pwo, XCLIPOBJ, WndObj);
228 TRACE("EngDeleteWnd: pwo = 0x%p\n", pwo
);
230 UserEnterExclusive();
232 /* Get window object */
233 Window
= UserGetWindowObject(Clip
->Hwnd
);
236 ERR("Couldnt get window object for WndObjInt->Hwnd!!!\n");
240 /* Remove object from window */
241 UserRemoveProp(Window
, AtomWndObj
, TRUE
);
248 IntEngFreeClipResources((XCLIPOBJ
*)Clip
);
264 return CLIPOBJ_bEnum(&pwo
->coClient
, cj
, pul
);
280 // FIXME: Should we enumerate all rectangles or not?
281 return CLIPOBJ_cEnumStart(&pwo
->coClient
, FALSE
, iType
, iDirection
, cLimit
);
294 EWNDOBJ
* Clip
= (EWNDOBJ
*)pwo
;//CONTAINING_RECORD(pwo, XCLIPOBJ, WndObj);
297 TRACE("WNDOBJ_vSetConsumer: pwo = 0x%p, pvConsumer = 0x%p\n", pwo
, pvConsumer
);
299 Hack
= (pwo
->pvConsumer
== NULL
);
300 pwo
->pvConsumer
= pvConsumer
;
304 * MSDN says that the WNDOBJCHANGEPROC will be called with the most recent state
305 * when a WNDOBJ is created - we do it here because most drivers will need pvConsumer
306 * in the callback to identify the WNDOBJ I think.
312 FIXME("Is this hack really needed?\n");
313 IntEngWndCallChangeProc(Clip
, WOC_RGN_CLIENT
);
314 IntEngWndCallChangeProc(Clip
, WOC_CHANGED
);
315 IntEngWndCallChangeProc(Clip
, WOC_DRAWN
);