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(
20 PWND PreviousWindow
, CurrentWindow
, CurrentSibling
;
22 if (!Wnd
|| !(Wnd
->style
& WS_VISIBLE
))
31 VisRgn
= IntSysCreateRectRgnIndirect(&Wnd
->rcClient
);
35 VisRgn
= IntSysCreateRectRgnIndirect(&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
);
51 if (VisRgn
) GreDeleteObject(VisRgn
);
55 if (!(CurrentWindow
->style
& WS_VISIBLE
))
57 if (VisRgn
) GreDeleteObject(VisRgn
);
61 ClipRgn
= IntSysCreateRectRgnIndirect(&CurrentWindow
->rcClient
);
62 NtGdiCombineRgn(VisRgn
, VisRgn
, ClipRgn
, RGN_AND
);
63 GreDeleteObject(ClipRgn
);
65 if ((PreviousWindow
->style
& WS_CLIPSIBLINGS
) ||
66 (PreviousWindow
== Wnd
&& ClipSiblings
))
68 CurrentSibling
= CurrentWindow
->spwndChild
;
69 while ( CurrentSibling
!= NULL
&&
70 CurrentSibling
!= PreviousWindow
)
72 if ((CurrentSibling
->style
& WS_VISIBLE
) &&
73 !(CurrentSibling
->ExStyle
& WS_EX_TRANSPARENT
))
75 ClipRgn
= IntSysCreateRectRgnIndirect(&CurrentSibling
->rcWindow
);
76 /* Combine it with the window region if available */
77 if (CurrentSibling
->hrgnClip
&& !(CurrentSibling
->style
& WS_MINIMIZE
))
79 NtGdiOffsetRgn(ClipRgn
, -CurrentSibling
->rcWindow
.left
, -CurrentSibling
->rcWindow
.top
);
80 NtGdiCombineRgn(ClipRgn
, ClipRgn
, CurrentSibling
->hrgnClip
, RGN_AND
);
81 NtGdiOffsetRgn(ClipRgn
, CurrentSibling
->rcWindow
.left
, CurrentSibling
->rcWindow
.top
);
83 NtGdiCombineRgn(VisRgn
, VisRgn
, ClipRgn
, RGN_DIFF
);
84 GreDeleteObject(ClipRgn
);
86 CurrentSibling
= CurrentSibling
->spwndNext
;
90 PreviousWindow
= CurrentWindow
;
91 CurrentWindow
= CurrentWindow
->spwndParent
;
96 CurrentWindow
= Wnd
->spwndChild
;
99 if ((CurrentWindow
->style
& WS_VISIBLE
) &&
100 !(CurrentWindow
->ExStyle
& WS_EX_TRANSPARENT
))
102 ClipRgn
= IntSysCreateRectRgnIndirect(&CurrentWindow
->rcWindow
);
103 /* Combine it with the window region if available */
104 if (CurrentWindow
->hrgnClip
&& !(CurrentWindow
->style
& WS_MINIMIZE
))
106 NtGdiOffsetRgn(ClipRgn
, -CurrentWindow
->rcWindow
.left
, -CurrentWindow
->rcWindow
.top
);
107 NtGdiCombineRgn(ClipRgn
, ClipRgn
, CurrentWindow
->hrgnClip
, RGN_AND
);
108 NtGdiOffsetRgn(ClipRgn
, CurrentWindow
->rcWindow
.left
, CurrentWindow
->rcWindow
.top
);
110 NtGdiCombineRgn(VisRgn
, VisRgn
, ClipRgn
, RGN_DIFF
);
111 GreDeleteObject(ClipRgn
);
113 CurrentWindow
= CurrentWindow
->spwndNext
;
117 if (Wnd
->hrgnClip
&& !(Wnd
->style
& WS_MINIMIZE
))
119 NtGdiOffsetRgn(VisRgn
, -Wnd
->rcWindow
.left
, -Wnd
->rcWindow
.top
);
120 NtGdiCombineRgn(VisRgn
, VisRgn
, Wnd
->hrgnClip
, RGN_AND
);
121 NtGdiOffsetRgn(VisRgn
, Wnd
->rcWindow
.left
, Wnd
->rcWindow
.top
);
128 co_VIS_WindowLayoutChanged(
134 USER_REFERENCE_ENTRY Ref
;
138 Parent
= Wnd
->spwndParent
;
141 Temp
= IntSysCreateRectRgn(0, 0, 0, 0);
143 NtGdiCombineRgn(Temp
, NewlyExposed
, NULL
, RGN_COPY
);
145 Wnd
->rcWindow
.left
- Parent
->rcClient
.left
,
146 Wnd
->rcWindow
.top
- Parent
->rcClient
.top
);
148 UserRefObjectCo(Parent
, &Ref
);
149 co_UserRedrawWindow(Parent
, NULL
, Temp
,
150 RDW_FRAME
| RDW_ERASE
| RDW_INVALIDATE
|
152 UserDerefObjectCo(Parent
);
154 GreDeleteObject(Temp
);