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 INT LeftOffset
, TopOffset
;
42 PWINDOW_OBJECT PreviousWindow
, CurrentWindow
, CurrentSibling
;
44 if (!(Window
->Style
& WS_VISIBLE
))
46 return NtGdiCreateRectRgn(0, 0, 0, 0);
51 if(!(ClipRgn
= VIS_ComputeVisibleRegion(Window
, FALSE
, ClipChildren
, ClipSiblings
)))
53 return NtGdiCreateRectRgn(0, 0, 0, 0);
55 if(!(VisRgn
= UnsafeIntCreateRectRgnIndirect(&Window
->ClientRect
)))
57 NtGdiDeleteObject(VisRgn
);
58 return NtGdiCreateRectRgn(0, 0, 0, 0);
60 LeftOffset
= Window
->ClientRect
.left
- Window
->WindowRect
.left
;
61 TopOffset
= Window
->ClientRect
.top
- Window
->WindowRect
.top
;
62 NtGdiOffsetRgn(VisRgn
, -Window
->WindowRect
.left
, -Window
->WindowRect
.top
);
63 NtGdiCombineRgn(VisRgn
, VisRgn
, ClipRgn
, RGN_AND
);
64 NtGdiDeleteObject(ClipRgn
);
65 NtGdiOffsetRgn(VisRgn
, -LeftOffset
, -TopOffset
);
69 VisRgn
= UnsafeIntCreateRectRgnIndirect(&Window
->WindowRect
);
70 LeftOffset
= Window
->WindowRect
.left
;
71 TopOffset
= Window
->WindowRect
.top
;
74 * Walk through all parent windows and for each clip the visble region
75 * to the parent's client area and exclude all siblings that are over
79 PreviousWindow
= Window
;
80 CurrentWindow
= IntGetParentObject(Window
);
83 if (!(CurrentWindow
->Style
& WS_VISIBLE
))
85 NtGdiDeleteObject(VisRgn
);
86 return NtGdiCreateRectRgn(0, 0, 0, 0);
88 ClipRgn
= UnsafeIntCreateRectRgnIndirect(&CurrentWindow
->ClientRect
);
89 NtGdiCombineRgn(VisRgn
, VisRgn
, ClipRgn
, RGN_AND
);
90 NtGdiDeleteObject(ClipRgn
);
92 if ((PreviousWindow
->Style
& WS_CLIPSIBLINGS
) ||
93 (PreviousWindow
== Window
&& ClipSiblings
))
95 CurrentSibling
= CurrentWindow
->FirstChild
;
96 while (CurrentSibling
!= NULL
&& CurrentSibling
!= PreviousWindow
)
98 if (CurrentSibling
->Style
& WS_VISIBLE
)
100 ClipRgn
= UnsafeIntCreateRectRgnIndirect(&CurrentSibling
->WindowRect
);
101 /* Combine it with the window region if available */
102 if(CurrentSibling
->WindowRegion
&& !(CurrentSibling
->Style
& WS_MINIMIZE
))
104 NtGdiOffsetRgn(ClipRgn
, -CurrentSibling
->WindowRect
.left
, -CurrentSibling
->WindowRect
.top
);
105 NtGdiCombineRgn(ClipRgn
, ClipRgn
, CurrentSibling
->WindowRegion
, RGN_AND
);
106 NtGdiOffsetRgn(ClipRgn
, CurrentSibling
->WindowRect
.left
, CurrentSibling
->WindowRect
.top
);
108 NtGdiCombineRgn(VisRgn
, VisRgn
, ClipRgn
, RGN_DIFF
);
109 NtGdiDeleteObject(ClipRgn
);
111 CurrentSibling
= CurrentSibling
->NextSibling
;
115 PreviousWindow
= CurrentWindow
;
116 CurrentWindow
= IntGetParentObject(CurrentWindow
);
117 IntReleaseWindowObject(PreviousWindow
);
122 CurrentWindow
= Window
->FirstChild
;
123 while (CurrentWindow
)
125 if (CurrentWindow
->Style
& WS_VISIBLE
)
127 ClipRgn
= UnsafeIntCreateRectRgnIndirect(&CurrentWindow
->WindowRect
);
128 /* Combine it with the window region if available */
129 if(CurrentWindow
->WindowRegion
&& !(CurrentWindow
->Style
& WS_MINIMIZE
))
131 NtGdiOffsetRgn(ClipRgn
, -CurrentWindow
->WindowRect
.left
, -CurrentWindow
->WindowRect
.top
);
132 NtGdiCombineRgn(ClipRgn
, ClipRgn
, CurrentWindow
->WindowRegion
, RGN_AND
);
133 NtGdiOffsetRgn(ClipRgn
, CurrentWindow
->WindowRect
.left
, CurrentWindow
->WindowRect
.top
);
135 NtGdiCombineRgn(VisRgn
, VisRgn
, ClipRgn
, RGN_DIFF
);
136 NtGdiDeleteObject(ClipRgn
);
138 CurrentWindow
= CurrentWindow
->NextSibling
;
142 if(Window
->WindowRegion
&& !(Window
->Style
& WS_MINIMIZE
))
144 NtGdiOffsetRgn(VisRgn
, -LeftOffset
, -TopOffset
);
145 NtGdiCombineRgn(VisRgn
, VisRgn
, Window
->WindowRegion
, RGN_AND
);
149 NtGdiOffsetRgn(VisRgn
, -LeftOffset
, -TopOffset
);
155 co_VIS_WindowLayoutChanged(
156 PWINDOW_OBJECT Window
,
160 PWINDOW_OBJECT Parent
;
162 Temp
= NtGdiCreateRectRgn(0, 0, 0, 0);
163 NtGdiCombineRgn(Temp
, NewlyExposed
, NULL
, RGN_COPY
);
165 Parent
= IntGetParentObject(Window
);
169 Window
->WindowRect
.left
- Parent
->ClientRect
.left
,
170 Window
->WindowRect
.top
- Parent
->ClientRect
.top
);
171 co_UserRedrawWindow(Parent
, NULL
, Temp
,
172 RDW_FRAME
| RDW_ERASE
| RDW_INVALIDATE
|
174 IntReleaseWindowObject(Parent
);
176 NtGdiDeleteObject(Temp
);