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
;
43 if (!(Window
->Style
& WS_VISIBLE
))
50 if (!(ClipRgn
= VIS_ComputeVisibleRegion(Window
, FALSE
, ClipChildren
, ClipSiblings
)))
54 if (!(VisRgn
= UnsafeIntCreateRectRgnIndirect(&Window
->ClientRect
)))
56 NtGdiDeleteObject(VisRgn
);
59 NtGdiCombineRgn(VisRgn
, VisRgn
, ClipRgn
, RGN_AND
);
60 NtGdiDeleteObject(ClipRgn
);
64 VisRgn
= UnsafeIntCreateRectRgnIndirect(&Window
->WindowRect
);
67 * Walk through all parent windows and for each clip the visble region
68 * to the parent's client area and exclude all siblings that are over
72 PreviousWindow
= Window
;
73 CurrentWindow
= Window
->Parent
;
76 if (!(CurrentWindow
->Style
& WS_VISIBLE
))
78 NtGdiDeleteObject(VisRgn
);
82 ClipRgn
= UnsafeIntCreateRectRgnIndirect(&CurrentWindow
->ClientRect
);
83 NtGdiCombineRgn(VisRgn
, VisRgn
, ClipRgn
, RGN_AND
);
84 NtGdiDeleteObject(ClipRgn
);
86 if ((PreviousWindow
->Style
& WS_CLIPSIBLINGS
) ||
87 (PreviousWindow
== Window
&& ClipSiblings
))
89 CurrentSibling
= CurrentWindow
->FirstChild
;
90 while (CurrentSibling
!= NULL
&& CurrentSibling
!= PreviousWindow
)
92 if ((CurrentSibling
->Style
& WS_VISIBLE
) &&
93 !(CurrentSibling
->ExStyle
& WS_EX_TRANSPARENT
))
95 ClipRgn
= UnsafeIntCreateRectRgnIndirect(&CurrentSibling
->WindowRect
);
96 /* Combine it with the window region if available */
97 if (CurrentSibling
->WindowRegion
&& !(CurrentSibling
->Style
& WS_MINIMIZE
))
99 NtGdiOffsetRgn(ClipRgn
, -CurrentSibling
->WindowRect
.left
, -CurrentSibling
->WindowRect
.top
);
100 NtGdiCombineRgn(ClipRgn
, ClipRgn
, CurrentSibling
->WindowRegion
, RGN_AND
);
101 NtGdiOffsetRgn(ClipRgn
, CurrentSibling
->WindowRect
.left
, CurrentSibling
->WindowRect
.top
);
103 NtGdiCombineRgn(VisRgn
, VisRgn
, ClipRgn
, RGN_DIFF
);
104 NtGdiDeleteObject(ClipRgn
);
106 CurrentSibling
= CurrentSibling
->NextSibling
;
110 PreviousWindow
= CurrentWindow
;
111 CurrentWindow
= CurrentWindow
->Parent
;
116 CurrentWindow
= Window
->FirstChild
;
117 while (CurrentWindow
)
119 if ((CurrentWindow
->Style
& WS_VISIBLE
) &&
120 !(CurrentWindow
->ExStyle
& WS_EX_TRANSPARENT
))
122 ClipRgn
= UnsafeIntCreateRectRgnIndirect(&CurrentWindow
->WindowRect
);
123 /* Combine it with the window region if available */
124 if (CurrentWindow
->WindowRegion
&& !(CurrentWindow
->Style
& WS_MINIMIZE
))
126 NtGdiOffsetRgn(ClipRgn
, -CurrentWindow
->WindowRect
.left
, -CurrentWindow
->WindowRect
.top
);
127 NtGdiCombineRgn(ClipRgn
, ClipRgn
, CurrentWindow
->WindowRegion
, RGN_AND
);
128 NtGdiOffsetRgn(ClipRgn
, CurrentWindow
->WindowRect
.left
, CurrentWindow
->WindowRect
.top
);
130 NtGdiCombineRgn(VisRgn
, VisRgn
, ClipRgn
, RGN_DIFF
);
131 NtGdiDeleteObject(ClipRgn
);
133 CurrentWindow
= CurrentWindow
->NextSibling
;
137 if (Window
->WindowRegion
&& !(Window
->Style
& WS_MINIMIZE
))
139 NtGdiOffsetRgn(VisRgn
, -Window
->WindowRect
.left
, -Window
->WindowRect
.top
);
140 NtGdiCombineRgn(VisRgn
, VisRgn
, Window
->WindowRegion
, RGN_AND
);
141 NtGdiOffsetRgn(VisRgn
, Window
->WindowRect
.left
, Window
->WindowRect
.top
);
148 co_VIS_WindowLayoutChanged(
149 PWINDOW_OBJECT Window
,
153 PWINDOW_OBJECT Parent
;
154 USER_REFERENCE_ENTRY Ref
;
156 ASSERT_REFS_CO(Window
);
158 Temp
= NtGdiCreateRectRgn(0, 0, 0, 0);
159 NtGdiCombineRgn(Temp
, NewlyExposed
, NULL
, RGN_COPY
);
161 Parent
= Window
->Parent
;
165 Window
->WindowRect
.left
- Parent
->ClientRect
.left
,
166 Window
->WindowRect
.top
- Parent
->ClientRect
.top
);
168 UserRefObjectCo(Parent
, &Ref
);
169 co_UserRedrawWindow(Parent
, NULL
, Temp
,
170 RDW_FRAME
| RDW_ERASE
| RDW_ERASENOW
| RDW_INVALIDATE
|
172 UserDerefObjectCo(Parent
);
174 NtGdiDeleteObject(Temp
);