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
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, 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
->Parent
;
71 CurrentWnd
= CurrentWindow
->Wnd
;
72 if (!(CurrentWnd
) || !(CurrentWnd
->style
& WS_VISIBLE
))
74 GreDeleteObject(VisRgn
);
78 ClipRgn
= UnsafeIntCreateRectRgnIndirect(&CurrentWnd
->rcClient
);
79 NtGdiCombineRgn(VisRgn
, VisRgn
, ClipRgn
, RGN_AND
);
80 GreDeleteObject(ClipRgn
);
82 if ((PreviousWnd
->style
& WS_CLIPSIBLINGS
) ||
83 (PreviousWnd
== Wnd
&& ClipSiblings
))
85 CurrentSibling
= CurrentWindow
->FirstChild
;
86 while (CurrentSibling
!= NULL
&& CurrentSibling
!= PreviousWindow
)
88 CurrentSiblingWnd
= CurrentSibling
->Wnd
;
89 if ((CurrentSiblingWnd
->style
& WS_VISIBLE
) &&
90 !(CurrentSiblingWnd
->ExStyle
& WS_EX_TRANSPARENT
))
92 ClipRgn
= UnsafeIntCreateRectRgnIndirect(&CurrentSiblingWnd
->rcWindow
);
93 /* Combine it with the window region if available */
94 if (CurrentSibling
->WindowRegion
&& !(CurrentSiblingWnd
->style
& WS_MINIMIZE
))
96 NtGdiOffsetRgn(ClipRgn
, -CurrentSiblingWnd
->rcWindow
.left
, -CurrentSiblingWnd
->rcWindow
.top
);
97 NtGdiCombineRgn(ClipRgn
, ClipRgn
, CurrentSibling
->WindowRegion
, RGN_AND
);
98 NtGdiOffsetRgn(ClipRgn
, CurrentSiblingWnd
->rcWindow
.left
, CurrentSiblingWnd
->rcWindow
.top
);
100 NtGdiCombineRgn(VisRgn
, VisRgn
, ClipRgn
, RGN_DIFF
);
101 GreDeleteObject(ClipRgn
);
103 CurrentSibling
= CurrentSibling
->NextSibling
;
107 PreviousWindow
= CurrentWindow
;
108 PreviousWnd
= PreviousWindow
->Wnd
;
109 CurrentWindow
= CurrentWindow
->Parent
;
114 CurrentWindow
= Window
->FirstChild
;
115 while (CurrentWindow
)
117 CurrentWnd
= CurrentWindow
->Wnd
;
118 if ((CurrentWnd
->style
& WS_VISIBLE
) &&
119 !(CurrentWnd
->ExStyle
& WS_EX_TRANSPARENT
))
121 ClipRgn
= UnsafeIntCreateRectRgnIndirect(&CurrentWnd
->rcWindow
);
122 /* Combine it with the window region if available */
123 if (CurrentWindow
->WindowRegion
&& !(CurrentWnd
->style
& WS_MINIMIZE
))
125 NtGdiOffsetRgn(ClipRgn
, -CurrentWnd
->rcWindow
.left
, -CurrentWnd
->rcWindow
.top
);
126 NtGdiCombineRgn(ClipRgn
, ClipRgn
, CurrentWindow
->WindowRegion
, RGN_AND
);
127 NtGdiOffsetRgn(ClipRgn
, CurrentWnd
->rcWindow
.left
, CurrentWnd
->rcWindow
.top
);
129 NtGdiCombineRgn(VisRgn
, VisRgn
, ClipRgn
, RGN_DIFF
);
130 GreDeleteObject(ClipRgn
);
132 CurrentWindow
= CurrentWindow
->NextSibling
;
136 if (Window
->WindowRegion
&& !(Wnd
->style
& WS_MINIMIZE
))
138 NtGdiOffsetRgn(VisRgn
, -Wnd
->rcWindow
.left
, -Wnd
->rcWindow
.top
);
139 NtGdiCombineRgn(VisRgn
, VisRgn
, Window
->WindowRegion
, RGN_AND
);
140 NtGdiOffsetRgn(VisRgn
, Wnd
->rcWindow
.left
, Wnd
->rcWindow
.top
);
147 co_VIS_WindowLayoutChanged(
148 PWINDOW_OBJECT Window
,
152 PWINDOW_OBJECT Parent
;
153 USER_REFERENCE_ENTRY Ref
;
156 ASSERT_REFS_CO(Window
);
160 Temp
= NtGdiCreateRectRgn(0, 0, 0, 0);
161 NtGdiCombineRgn(Temp
, NewlyExposed
, NULL
, RGN_COPY
);
163 Parent
= Window
->Parent
;
166 ParentWnd
= Parent
->Wnd
;
168 Wnd
->rcWindow
.left
- ParentWnd
->rcClient
.left
,
169 Wnd
->rcWindow
.top
- ParentWnd
->rcClient
.top
);
171 UserRefObjectCo(Parent
, &Ref
);
172 co_UserRedrawWindow(Parent
, NULL
, Temp
,
173 RDW_FRAME
| RDW_ERASE
| RDW_INVALIDATE
|
175 UserDerefObjectCo(Parent
);
177 GreDeleteObject(Temp
);