2 * ReactOS W32 Subsystem
3 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 * COPYRIGHT: See COPYING in the top level directory
22 * PROJECT: ReactOS kernel
23 * PURPOSE: Visibility computations
24 * FILE: subsys/win32k/ntuser/vis.c
25 * PROGRAMMER: Ge van Geldorp (ge@gse.nl)
34 VIS_ComputeVisibleRegion(
35 PWINDOW_OBJECT Window
,
41 PWINDOW_OBJECT PreviousWindow
, CurrentWindow
, CurrentSibling
;
42 PWND Wnd
, CurrentWnd
, PreviousWnd
, CurrentSiblingWnd
;
46 if (!Wnd
|| !(Wnd
->style
& WS_VISIBLE
))
53 VisRgn
= UnsafeIntCreateRectRgnIndirect(&Window
->Wnd
->rcClient
);
57 VisRgn
= UnsafeIntCreateRectRgnIndirect(&Window
->Wnd
->rcWindow
);
61 * Walk through all parent windows and for each clip the visble region
62 * to the parent's client area and exclude all siblings that are over
66 PreviousWindow
= Window
;
67 PreviousWnd
= PreviousWindow
->Wnd
;
68 CurrentWindow
= Window
->spwndParent
;
71 if ( CurrentWindow
->Status
& WINDOWSTATUS_DESTROYING
||
72 CurrentWindow
->Status
& WINDOWSTATUS_DESTROYED
)
74 DPRINT1("ATM the Current Window or Parent is dead!\n");
78 CurrentWnd
= CurrentWindow
->Wnd
;
79 if (!CurrentWnd
|| !(CurrentWnd
->style
& WS_VISIBLE
))
81 GreDeleteObject(VisRgn
);
85 ClipRgn
= UnsafeIntCreateRectRgnIndirect(&CurrentWnd
->rcClient
);
86 NtGdiCombineRgn(VisRgn
, VisRgn
, ClipRgn
, RGN_AND
);
87 GreDeleteObject(ClipRgn
);
89 if ((PreviousWnd
->style
& WS_CLIPSIBLINGS
) ||
90 (PreviousWnd
== Wnd
&& ClipSiblings
))
92 CurrentSibling
= CurrentWindow
->spwndChild
;
93 while (CurrentSibling
!= NULL
&& CurrentSibling
!= PreviousWindow
)
95 CurrentSiblingWnd
= CurrentSibling
->Wnd
;
96 if ((CurrentSiblingWnd
->style
& WS_VISIBLE
) &&
97 !(CurrentSiblingWnd
->ExStyle
& WS_EX_TRANSPARENT
))
99 ClipRgn
= UnsafeIntCreateRectRgnIndirect(&CurrentSiblingWnd
->rcWindow
);
100 /* Combine it with the window region if available */
101 if (CurrentSibling
->WindowRegion
&& !(CurrentSiblingWnd
->style
& WS_MINIMIZE
))
103 NtGdiOffsetRgn(ClipRgn
, -CurrentSiblingWnd
->rcWindow
.left
, -CurrentSiblingWnd
->rcWindow
.top
);
104 NtGdiCombineRgn(ClipRgn
, ClipRgn
, CurrentSibling
->WindowRegion
, RGN_AND
);
105 NtGdiOffsetRgn(ClipRgn
, CurrentSiblingWnd
->rcWindow
.left
, CurrentSiblingWnd
->rcWindow
.top
);
107 NtGdiCombineRgn(VisRgn
, VisRgn
, ClipRgn
, RGN_DIFF
);
108 GreDeleteObject(ClipRgn
);
110 CurrentSibling
= CurrentSibling
->spwndNext
;
114 PreviousWindow
= CurrentWindow
;
115 PreviousWnd
= PreviousWindow
->Wnd
;
116 CurrentWindow
= CurrentWindow
->spwndParent
;
121 CurrentWindow
= Window
->spwndChild
;
122 while (CurrentWindow
)
124 CurrentWnd
= CurrentWindow
->Wnd
;
125 if ((CurrentWnd
->style
& WS_VISIBLE
) &&
126 !(CurrentWnd
->ExStyle
& WS_EX_TRANSPARENT
))
128 ClipRgn
= UnsafeIntCreateRectRgnIndirect(&CurrentWnd
->rcWindow
);
129 /* Combine it with the window region if available */
130 if (CurrentWindow
->WindowRegion
&& !(CurrentWnd
->style
& WS_MINIMIZE
))
132 NtGdiOffsetRgn(ClipRgn
, -CurrentWnd
->rcWindow
.left
, -CurrentWnd
->rcWindow
.top
);
133 NtGdiCombineRgn(ClipRgn
, ClipRgn
, CurrentWindow
->WindowRegion
, RGN_AND
);
134 NtGdiOffsetRgn(ClipRgn
, CurrentWnd
->rcWindow
.left
, CurrentWnd
->rcWindow
.top
);
136 NtGdiCombineRgn(VisRgn
, VisRgn
, ClipRgn
, RGN_DIFF
);
137 GreDeleteObject(ClipRgn
);
139 CurrentWindow
= CurrentWindow
->spwndNext
;
143 if (Window
->WindowRegion
&& !(Wnd
->style
& WS_MINIMIZE
))
145 NtGdiOffsetRgn(VisRgn
, -Wnd
->rcWindow
.left
, -Wnd
->rcWindow
.top
);
146 NtGdiCombineRgn(VisRgn
, VisRgn
, Window
->WindowRegion
, RGN_AND
);
147 NtGdiOffsetRgn(VisRgn
, Wnd
->rcWindow
.left
, Wnd
->rcWindow
.top
);
154 co_VIS_WindowLayoutChanged(
155 PWINDOW_OBJECT Window
,
159 PWINDOW_OBJECT Parent
;
160 USER_REFERENCE_ENTRY Ref
;
163 ASSERT_REFS_CO(Window
);
167 Temp
= NtGdiCreateRectRgn(0, 0, 0, 0);
168 NtGdiCombineRgn(Temp
, NewlyExposed
, NULL
, RGN_COPY
);
170 Parent
= Window
->spwndParent
;
173 ParentWnd
= Parent
->Wnd
;
175 Wnd
->rcWindow
.left
- ParentWnd
->rcClient
.left
,
176 Wnd
->rcWindow
.top
- ParentWnd
->rcClient
.top
);
178 UserRefObjectCo(Parent
, &Ref
);
179 co_UserRedrawWindow(Parent
, NULL
, Temp
,
180 RDW_FRAME
| RDW_ERASE
| RDW_INVALIDATE
|
182 UserDerefObjectCo(Parent
);
184 GreDeleteObject(Temp
);