2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * PURPOSE: Visibility computations
5 * FILE: subsys/win32k/ntuser/vis.c
6 * PROGRAMMER: Ge van Geldorp (ge@gse.nl)
10 DBG_DEFAULT_CHANNEL(UserWinpos
);
13 VIS_ComputeVisibleRegion(
19 PREGION VisRgn
, ClipRgn
;
20 PWND PreviousWindow
, CurrentWindow
, CurrentSibling
;
22 if (!Wnd
|| !(Wnd
->style
& WS_VISIBLE
))
31 VisRgn
= IntSysCreateRectpRgnIndirect(&Wnd
->rcClient
);
35 VisRgn
= IntSysCreateRectpRgnIndirect(&Wnd
->rcWindow
);
39 * Walk through all parent windows and for each clip the visble region
40 * to the parent's client area and exclude all siblings that are over
45 CurrentWindow
= Wnd
->spwndParent
;
48 if (!VerifyWnd(CurrentWindow
))
50 ERR("ATM the Current Window or Parent is dead! %p\n",CurrentWindow
);
52 REGION_Delete(VisRgn
);
56 if (!(CurrentWindow
->style
& WS_VISIBLE
))
59 REGION_Delete(VisRgn
);
63 ClipRgn
= IntSysCreateRectpRgnIndirect(&CurrentWindow
->rcClient
);
64 IntGdiCombineRgn(VisRgn
, VisRgn
, ClipRgn
, RGN_AND
);
65 REGION_Delete(ClipRgn
);
67 if ((PreviousWindow
->style
& WS_CLIPSIBLINGS
) ||
68 (PreviousWindow
== Wnd
&& ClipSiblings
))
70 CurrentSibling
= CurrentWindow
->spwndChild
;
71 while ( CurrentSibling
!= NULL
&&
72 CurrentSibling
!= PreviousWindow
)
74 if ((CurrentSibling
->style
& WS_VISIBLE
) &&
75 !(CurrentSibling
->ExStyle
& WS_EX_TRANSPARENT
))
77 ClipRgn
= IntSysCreateRectpRgnIndirect(&CurrentSibling
->rcWindow
);
78 /* Combine it with the window region if available */
79 if (CurrentSibling
->hrgnClip
&& !(CurrentSibling
->style
& WS_MINIMIZE
))
81 PREGION SiblingClipRgn
= REGION_LockRgn(CurrentSibling
->hrgnClip
);
84 REGION_bOffsetRgn(ClipRgn
, -CurrentSibling
->rcWindow
.left
, -CurrentSibling
->rcWindow
.top
);
85 IntGdiCombineRgn(ClipRgn
, ClipRgn
, SiblingClipRgn
, RGN_AND
);
86 REGION_bOffsetRgn(ClipRgn
, CurrentSibling
->rcWindow
.left
, CurrentSibling
->rcWindow
.top
);
87 REGION_UnlockRgn(SiblingClipRgn
);
90 IntGdiCombineRgn(VisRgn
, VisRgn
, ClipRgn
, RGN_DIFF
);
91 REGION_Delete(ClipRgn
);
93 CurrentSibling
= CurrentSibling
->spwndNext
;
97 PreviousWindow
= CurrentWindow
;
98 CurrentWindow
= CurrentWindow
->spwndParent
;
103 CurrentWindow
= Wnd
->spwndChild
;
104 while (CurrentWindow
)
106 if ((CurrentWindow
->style
& WS_VISIBLE
) &&
107 !(CurrentWindow
->ExStyle
& WS_EX_TRANSPARENT
))
109 ClipRgn
= IntSysCreateRectpRgnIndirect(&CurrentWindow
->rcWindow
);
110 /* Combine it with the window region if available */
111 if (CurrentWindow
->hrgnClip
&& !(CurrentWindow
->style
& WS_MINIMIZE
))
113 PREGION CurrentRgnClip
= REGION_LockRgn(CurrentWindow
->hrgnClip
);
116 REGION_bOffsetRgn(ClipRgn
, -CurrentWindow
->rcWindow
.left
, -CurrentWindow
->rcWindow
.top
);
117 IntGdiCombineRgn(ClipRgn
, ClipRgn
, CurrentRgnClip
, RGN_AND
);
118 REGION_bOffsetRgn(ClipRgn
, CurrentWindow
->rcWindow
.left
, CurrentWindow
->rcWindow
.top
);
119 REGION_UnlockRgn(CurrentRgnClip
);
122 IntGdiCombineRgn(VisRgn
, VisRgn
, ClipRgn
, RGN_DIFF
);
123 REGION_Delete(ClipRgn
);
125 CurrentWindow
= CurrentWindow
->spwndNext
;
129 if (Wnd
->hrgnClip
&& !(Wnd
->style
& WS_MINIMIZE
))
131 PREGION WndRgnClip
= REGION_LockRgn(Wnd
->hrgnClip
);
134 REGION_bOffsetRgn(VisRgn
, -Wnd
->rcWindow
.left
, -Wnd
->rcWindow
.top
);
135 IntGdiCombineRgn(VisRgn
, VisRgn
, WndRgnClip
, RGN_AND
);
136 REGION_bOffsetRgn(VisRgn
, Wnd
->rcWindow
.left
, Wnd
->rcWindow
.top
);
137 REGION_UnlockRgn(WndRgnClip
);
145 co_VIS_WindowLayoutChanged(
147 PREGION NewlyExposed
)
150 USER_REFERENCE_ENTRY Ref
;
154 Parent
= Wnd
->spwndParent
;
157 PREGION TempRgn
= IntSysCreateRectpRgn(0, 0, 0, 0);
162 IntGdiCombineRgn(TempRgn
, NewlyExposed
, NULL
, RGN_COPY
);
163 REGION_bOffsetRgn(TempRgn
,
164 Wnd
->rcWindow
.left
- Parent
->rcClient
.left
,
165 Wnd
->rcWindow
.top
- Parent
->rcClient
.top
);
167 UserRefObjectCo(Parent
, &Ref
);
168 co_UserRedrawWindow(Parent
, NULL
, TempRgn
,
169 RDW_FRAME
| RDW_ERASE
| RDW_INVALIDATE
|
171 UserDerefObjectCo(Parent
);
173 REGION_Delete(TempRgn
);