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(
40 PWND PreviousWindow
, CurrentWindow
, CurrentSibling
;
42 if (!Wnd
|| !(Wnd
->style
& WS_VISIBLE
))
51 VisRgn
= IntSysCreateRectRgnIndirect(&Wnd
->rcClient
);
55 VisRgn
= IntSysCreateRectRgnIndirect(&Wnd
->rcWindow
);
59 * Walk through all parent windows and for each clip the visble region
60 * to the parent's client area and exclude all siblings that are over
65 CurrentWindow
= Wnd
->spwndParent
;
68 if ( CurrentWindow
->state2
& WNDS2_INDESTROY
||
69 CurrentWindow
->state
& WNDS_DESTROYED
)
71 DPRINT1("ATM the Current Window or Parent is dead!\n");
72 if (VisRgn
) REGION_FreeRgnByHandle(VisRgn
);
76 if (!(CurrentWindow
->style
& WS_VISIBLE
))
78 if (VisRgn
) REGION_FreeRgnByHandle(VisRgn
);
82 ClipRgn
= IntSysCreateRectRgnIndirect(&CurrentWindow
->rcClient
);
83 NtGdiCombineRgn(VisRgn
, VisRgn
, ClipRgn
, RGN_AND
);
84 REGION_FreeRgnByHandle(ClipRgn
);
86 if ((PreviousWindow
->style
& WS_CLIPSIBLINGS
) ||
87 (PreviousWindow
== Wnd
&& ClipSiblings
))
89 CurrentSibling
= CurrentWindow
->spwndChild
;
90 while ( CurrentSibling
!= NULL
&&
91 CurrentSibling
!= PreviousWindow
)
93 if ((CurrentSibling
->style
& WS_VISIBLE
) &&
94 !(CurrentSibling
->ExStyle
& WS_EX_TRANSPARENT
))
96 ClipRgn
= IntSysCreateRectRgnIndirect(&CurrentSibling
->rcWindow
);
97 /* Combine it with the window region if available */
98 if (CurrentSibling
->hrgnClip
&& !(CurrentSibling
->style
& WS_MINIMIZE
))
100 NtGdiOffsetRgn(ClipRgn
, -CurrentSibling
->rcWindow
.left
, -CurrentSibling
->rcWindow
.top
);
101 NtGdiCombineRgn(ClipRgn
, ClipRgn
, CurrentSibling
->hrgnClip
, RGN_AND
);
102 NtGdiOffsetRgn(ClipRgn
, CurrentSibling
->rcWindow
.left
, CurrentSibling
->rcWindow
.top
);
104 NtGdiCombineRgn(VisRgn
, VisRgn
, ClipRgn
, RGN_DIFF
);
105 REGION_FreeRgnByHandle(ClipRgn
);
107 CurrentSibling
= CurrentSibling
->spwndNext
;
111 PreviousWindow
= CurrentWindow
;
112 CurrentWindow
= CurrentWindow
->spwndParent
;
117 CurrentWindow
= Wnd
->spwndChild
;
118 while (CurrentWindow
)
120 if ((CurrentWindow
->style
& WS_VISIBLE
) &&
121 !(CurrentWindow
->ExStyle
& WS_EX_TRANSPARENT
))
123 ClipRgn
= IntSysCreateRectRgnIndirect(&CurrentWindow
->rcWindow
);
124 /* Combine it with the window region if available */
125 if (CurrentWindow
->hrgnClip
&& !(CurrentWindow
->style
& WS_MINIMIZE
))
127 NtGdiOffsetRgn(ClipRgn
, -CurrentWindow
->rcWindow
.left
, -CurrentWindow
->rcWindow
.top
);
128 NtGdiCombineRgn(ClipRgn
, ClipRgn
, CurrentWindow
->hrgnClip
, RGN_AND
);
129 NtGdiOffsetRgn(ClipRgn
, CurrentWindow
->rcWindow
.left
, CurrentWindow
->rcWindow
.top
);
131 NtGdiCombineRgn(VisRgn
, VisRgn
, ClipRgn
, RGN_DIFF
);
132 REGION_FreeRgnByHandle(ClipRgn
);
134 CurrentWindow
= CurrentWindow
->spwndNext
;
138 if (Wnd
->hrgnClip
&& !(Wnd
->style
& WS_MINIMIZE
))
140 NtGdiOffsetRgn(VisRgn
, -Wnd
->rcWindow
.left
, -Wnd
->rcWindow
.top
);
141 NtGdiCombineRgn(VisRgn
, VisRgn
, Wnd
->hrgnClip
, RGN_AND
);
142 NtGdiOffsetRgn(VisRgn
, Wnd
->rcWindow
.left
, Wnd
->rcWindow
.top
);
149 co_VIS_WindowLayoutChanged(
155 USER_REFERENCE_ENTRY Ref
;
159 Temp
= IntSysCreateRectRgn(0, 0, 0, 0);
160 NtGdiCombineRgn(Temp
, NewlyExposed
, NULL
, RGN_COPY
);
162 Parent
= Wnd
->spwndParent
;
166 Wnd
->rcWindow
.left
- Parent
->rcClient
.left
,
167 Wnd
->rcWindow
.top
- Parent
->rcClient
.top
);
169 UserRefObjectCo(Parent
, &Ref
);
170 co_UserRedrawWindow(Parent
, NULL
, Temp
,
171 RDW_FRAME
| RDW_ERASE
| RDW_INVALIDATE
|
173 UserDerefObjectCo(Parent
);
175 REGION_FreeRgnByHandle(Temp
);