d23e974489405aed4bcffe8d5517d8ce82e18a53
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 DECLARE_RETURN(WNDOBJ
*);
158 TRACE("EngCreateWnd: pso = 0x%p, hwnd = 0x%p, pfn = 0x%p, fl = 0x%lx, pixfmt = %d\n",
159 pso
, hWnd
, pfn
, fl
, iPixelFormat
);
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 calledFromUser
= UserIsEntered();
167 if (!calledFromUser
) {
171 /* Get window object */
172 Window
= UserGetWindowObject(hWnd
);
179 Clip
= EngAllocMem(FL_ZERO_MEMORY
, sizeof (EWNDOBJ
), GDITAG_WNDOBJ
);
182 ERR("Failed to allocate memory for a WND structure!\n");
185 IntEngInitClipObj((XCLIPOBJ
*)Clip
);
187 /* Fill the clipobj */
188 if (!IntEngWndUpdateClipObj(Clip
, Window
))
194 /* Fill user object */
195 WndObjUser
= (WNDOBJ
*)Clip
;
196 WndObjUser
->psoOwner
= pso
;
197 WndObjUser
->pvConsumer
= NULL
;
199 /* Fill internal object */
201 Clip
->ChangeProc
= pfn
;
202 /* Keep track of relevant flags */
203 Clip
->Flags
= fl
& (WO_RGN_CLIENT_DELTA
| WO_RGN_CLIENT
| WO_RGN_SURFACE_DELTA
| WO_RGN_SURFACE
| WO_DRAW_NOTIFY
);
204 if (fl
& WO_SPRITE_NOTIFY
)
205 Clip
->Flags
|= WOC_SPRITE_OVERLAP
| WOC_SPRITE_NO_OVERLAP
;
206 /* Those should always be sent */
207 Clip
->Flags
|= WOC_CHANGED
| WOC_DELETE
;
208 Clip
->PixelFormat
= iPixelFormat
;
210 /* associate object with window */
211 UserSetProp(Window
, AtomWndObj
, Clip
, TRUE
);
214 TRACE("EngCreateWnd: SUCCESS: %p!\n", WndObjUser
);
220 if (!calledFromUser
) {
236 EWNDOBJ
* Clip
= (EWNDOBJ
*)pwo
;//CONTAINING_RECORD(pwo, XCLIPOBJ, WndObj);
240 TRACE("EngDeleteWnd: pwo = 0x%p\n", pwo
);
242 calledFromUser
= UserIsEntered();
243 if (!calledFromUser
) {
244 UserEnterExclusive();
247 /* Get window object */
248 Window
= UserGetWindowObject(Clip
->Hwnd
);
251 ERR("Couldnt get window object for WndObjInt->Hwnd!!!\n");
255 /* Remove object from window */
256 UserRemoveProp(Window
, AtomWndObj
, TRUE
);
260 if (!calledFromUser
) {
265 IntEngFreeClipResources((XCLIPOBJ
*)Clip
);
281 return CLIPOBJ_bEnum(&pwo
->coClient
, cj
, pul
);
297 // FIXME: Should we enumerate all rectangles or not?
298 return CLIPOBJ_cEnumStart(&pwo
->coClient
, FALSE
, iType
, iDirection
, cLimit
);
311 EWNDOBJ
* Clip
= (EWNDOBJ
*)pwo
;//CONTAINING_RECORD(pwo, XCLIPOBJ, WndObj);
314 TRACE("WNDOBJ_vSetConsumer: pwo = 0x%p, pvConsumer = 0x%p\n", pwo
, pvConsumer
);
316 Hack
= (pwo
->pvConsumer
== NULL
);
317 pwo
->pvConsumer
= pvConsumer
;
321 * MSDN says that the WNDOBJCHANGEPROC will be called with the most recent state
322 * when a WNDOBJ is created - we do it here because most drivers will need pvConsumer
323 * in the callback to identify the WNDOBJ I think.
329 FIXME("Is this hack really needed?\n");
330 IntEngWndCallChangeProc(Clip
, WOC_RGN_CLIENT
);
331 IntEngWndCallChangeProc(Clip
, WOC_CHANGED
);
332 IntEngWndCallChangeProc(Clip
, WOC_DRAWN
);