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.
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS kernel
22 * PURPOSE: Visibility computations
23 * FILE: subsys/win32k/ntuser/vis.c
24 * PROGRAMMER: Ge van Geldorp (ge@gse.nl)
33 VIS_ComputeVisibleRegion(
34 PWINDOW_OBJECT Window
,
40 PWINDOW_OBJECT PreviousWindow
, CurrentWindow
, CurrentSibling
;
41 PWND Wnd
, CurrentWnd
, PreviousWnd
, CurrentSiblingWnd
;
45 if (!Wnd
|| !(Wnd
->style
& WS_VISIBLE
))
54 VisRgn
= IntSysCreateRectRgnIndirect(&Window
->Wnd
->rcClient
);
58 VisRgn
= IntSysCreateRectRgnIndirect(&Window
->Wnd
->rcWindow
);
62 * Walk through all parent windows and for each clip the visble region
63 * to the parent's client area and exclude all siblings that are over
67 PreviousWindow
= Window
;
68 PreviousWnd
= PreviousWindow
->Wnd
;
69 CurrentWindow
= Window
->spwndParent
;
72 if ( CurrentWindow
->state
& WINDOWSTATUS_DESTROYING
|| // state2
73 CurrentWindow
->state
& WINDOWSTATUS_DESTROYED
)
75 DPRINT1("ATM the Current Window or Parent is dead!\n");
76 if (VisRgn
) REGION_FreeRgnByHandle(VisRgn
);
80 CurrentWnd
= CurrentWindow
->Wnd
;
81 if (!CurrentWnd
|| !(CurrentWnd
->style
& WS_VISIBLE
))
83 if (VisRgn
) REGION_FreeRgnByHandle(VisRgn
);
87 ClipRgn
= IntSysCreateRectRgnIndirect(&CurrentWnd
->rcClient
);
88 NtGdiCombineRgn(VisRgn
, VisRgn
, ClipRgn
, RGN_AND
);
89 REGION_FreeRgnByHandle(ClipRgn
);
91 if ((PreviousWnd
->style
& WS_CLIPSIBLINGS
) ||
92 (PreviousWnd
== Wnd
&& ClipSiblings
))
94 CurrentSibling
= CurrentWindow
->spwndChild
;
95 while ( CurrentSibling
!= NULL
&&
96 CurrentSibling
!= PreviousWindow
&&
99 CurrentSiblingWnd
= CurrentSibling
->Wnd
;
100 if ((CurrentSiblingWnd
->style
& WS_VISIBLE
) &&
101 !(CurrentSiblingWnd
->ExStyle
& WS_EX_TRANSPARENT
))
103 ClipRgn
= IntSysCreateRectRgnIndirect(&CurrentSiblingWnd
->rcWindow
);
104 /* Combine it with the window region if available */
105 if (CurrentSibling
->hrgnClip
&& !(CurrentSiblingWnd
->style
& WS_MINIMIZE
))
107 NtGdiOffsetRgn(ClipRgn
, -CurrentSiblingWnd
->rcWindow
.left
, -CurrentSiblingWnd
->rcWindow
.top
);
108 NtGdiCombineRgn(ClipRgn
, ClipRgn
, CurrentSibling
->hrgnClip
, RGN_AND
);
109 NtGdiOffsetRgn(ClipRgn
, CurrentSiblingWnd
->rcWindow
.left
, CurrentSiblingWnd
->rcWindow
.top
);
111 NtGdiCombineRgn(VisRgn
, VisRgn
, ClipRgn
, RGN_DIFF
);
112 REGION_FreeRgnByHandle(ClipRgn
);
114 CurrentSibling
= CurrentSibling
->spwndNext
;
118 PreviousWindow
= CurrentWindow
;
119 PreviousWnd
= PreviousWindow
->Wnd
;
120 CurrentWindow
= CurrentWindow
->spwndParent
;
125 CurrentWindow
= Window
->spwndChild
;
126 while (CurrentWindow
&& CurrentWindow
->Wnd
)
128 CurrentWnd
= CurrentWindow
->Wnd
;
129 if ((CurrentWnd
->style
& WS_VISIBLE
) &&
130 !(CurrentWnd
->ExStyle
& WS_EX_TRANSPARENT
))
132 ClipRgn
= IntSysCreateRectRgnIndirect(&CurrentWnd
->rcWindow
);
133 /* Combine it with the window region if available */
134 if (CurrentWindow
->hrgnClip
&& !(CurrentWnd
->style
& WS_MINIMIZE
))
136 NtGdiOffsetRgn(ClipRgn
, -CurrentWnd
->rcWindow
.left
, -CurrentWnd
->rcWindow
.top
);
137 NtGdiCombineRgn(ClipRgn
, ClipRgn
, CurrentWindow
->hrgnClip
, RGN_AND
);
138 NtGdiOffsetRgn(ClipRgn
, CurrentWnd
->rcWindow
.left
, CurrentWnd
->rcWindow
.top
);
140 NtGdiCombineRgn(VisRgn
, VisRgn
, ClipRgn
, RGN_DIFF
);
141 REGION_FreeRgnByHandle(ClipRgn
);
143 CurrentWindow
= CurrentWindow
->spwndNext
;
147 if (Window
->hrgnClip
&& !(Wnd
->style
& WS_MINIMIZE
))
149 NtGdiOffsetRgn(VisRgn
, -Wnd
->rcWindow
.left
, -Wnd
->rcWindow
.top
);
150 NtGdiCombineRgn(VisRgn
, VisRgn
, Window
->hrgnClip
, RGN_AND
);
151 NtGdiOffsetRgn(VisRgn
, Wnd
->rcWindow
.left
, Wnd
->rcWindow
.top
);
158 co_VIS_WindowLayoutChanged(
159 PWINDOW_OBJECT Window
,
163 PWINDOW_OBJECT Parent
;
164 USER_REFERENCE_ENTRY Ref
;
167 ASSERT_REFS_CO(Window
);
171 Temp
= IntSysCreateRectRgn(0, 0, 0, 0);
172 NtGdiCombineRgn(Temp
, NewlyExposed
, NULL
, RGN_COPY
);
174 Parent
= Window
->spwndParent
;
177 ParentWnd
= Parent
->Wnd
;
179 Wnd
->rcWindow
.left
- ParentWnd
->rcClient
.left
,
180 Wnd
->rcWindow
.top
- ParentWnd
->rcClient
.top
);
182 UserRefObjectCo(Parent
, &Ref
);
183 co_UserRedrawWindow(Parent
, NULL
, Temp
,
184 RDW_FRAME
| RDW_ERASE
| RDW_INVALIDATE
|
186 UserDerefObjectCo(Parent
);
188 REGION_FreeRgnByHandle(Temp
);