2003-07-17 07:49:15 +00:00
|
|
|
/*
|
|
|
|
* ReactOS W32 Subsystem
|
|
|
|
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
*
|
2005-01-06 13:58:04 +00:00
|
|
|
* $Id$
|
2003-07-17 07:49:15 +00:00
|
|
|
*
|
|
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
|
|
* PROJECT: ReactOS kernel
|
|
|
|
* PURPOSE: Visibility computations
|
|
|
|
* FILE: subsys/win32k/ntuser/vis.c
|
|
|
|
* PROGRAMMER: Ge van Geldorp (ge@gse.nl)
|
|
|
|
*/
|
|
|
|
|
2004-05-10 17:07:20 +00:00
|
|
|
#include <w32k.h>
|
2003-07-17 07:49:15 +00:00
|
|
|
|
|
|
|
#define NDEBUG
|
|
|
|
#include <debug.h>
|
|
|
|
|
2004-01-17 15:18:25 +00:00
|
|
|
HRGN FASTCALL
|
|
|
|
VIS_ComputeVisibleRegion(
|
|
|
|
PWINDOW_OBJECT Window,
|
|
|
|
BOOLEAN ClientArea,
|
|
|
|
BOOLEAN ClipChildren,
|
|
|
|
BOOLEAN ClipSiblings)
|
|
|
|
{
|
|
|
|
HRGN VisRgn, ClipRgn;
|
|
|
|
INT LeftOffset, TopOffset;
|
2004-02-22 12:25:35 +00:00
|
|
|
PWINDOW_OBJECT PreviousWindow, CurrentWindow, CurrentSibling;
|
2004-01-17 15:18:25 +00:00
|
|
|
|
|
|
|
if (!(Window->Style & WS_VISIBLE))
|
|
|
|
{
|
2004-03-14 20:31:55 +00:00
|
|
|
return NtGdiCreateRectRgn(0, 0, 0, 0);
|
2004-01-17 15:18:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (ClientArea)
|
|
|
|
{
|
2004-03-23 16:32:20 +00:00
|
|
|
if(!(ClipRgn = VIS_ComputeVisibleRegion(Window, FALSE, ClipChildren, ClipSiblings)))
|
|
|
|
{
|
2004-03-27 15:16:05 +00:00
|
|
|
return NtGdiCreateRectRgn(0, 0, 0, 0);
|
2004-03-23 16:32:20 +00:00
|
|
|
}
|
|
|
|
if(!(VisRgn = UnsafeIntCreateRectRgnIndirect(&Window->ClientRect)))
|
|
|
|
{
|
|
|
|
NtGdiDeleteObject(VisRgn);
|
2004-03-27 15:16:05 +00:00
|
|
|
return NtGdiCreateRectRgn(0, 0, 0, 0);
|
2004-03-23 16:32:20 +00:00
|
|
|
}
|
|
|
|
LeftOffset = Window->ClientRect.left - Window->WindowRect.left;
|
|
|
|
TopOffset = Window->ClientRect.top - Window->WindowRect.top;
|
|
|
|
NtGdiOffsetRgn(VisRgn, -Window->WindowRect.left, -Window->WindowRect.top);
|
|
|
|
NtGdiCombineRgn(VisRgn, VisRgn, ClipRgn, RGN_AND);
|
|
|
|
NtGdiDeleteObject(ClipRgn);
|
|
|
|
NtGdiOffsetRgn(VisRgn, -LeftOffset, -TopOffset);
|
|
|
|
return VisRgn;
|
2004-01-17 15:18:25 +00:00
|
|
|
}
|
|
|
|
|
2004-03-23 16:32:20 +00:00
|
|
|
VisRgn = UnsafeIntCreateRectRgnIndirect(&Window->WindowRect);
|
|
|
|
LeftOffset = Window->WindowRect.left;
|
|
|
|
TopOffset = Window->WindowRect.top;
|
|
|
|
|
2004-02-22 12:25:35 +00:00
|
|
|
/*
|
2005-05-08 02:11:54 +00:00
|
|
|
* Walk through all parent windows and for each clip the visble region
|
2004-02-22 12:25:35 +00:00
|
|
|
* to the parent's client area and exclude all siblings that are over
|
|
|
|
* our window.
|
|
|
|
*/
|
|
|
|
|
|
|
|
PreviousWindow = Window;
|
2004-02-24 01:30:58 +00:00
|
|
|
CurrentWindow = IntGetParentObject(Window);
|
2004-01-17 15:18:25 +00:00
|
|
|
while (CurrentWindow)
|
|
|
|
{
|
|
|
|
if (!(CurrentWindow->Style & WS_VISIBLE))
|
|
|
|
{
|
|
|
|
NtGdiDeleteObject(VisRgn);
|
2004-03-27 15:16:05 +00:00
|
|
|
return NtGdiCreateRectRgn(0, 0, 0, 0);
|
2004-01-17 15:18:25 +00:00
|
|
|
}
|
|
|
|
ClipRgn = UnsafeIntCreateRectRgnIndirect(&CurrentWindow->ClientRect);
|
|
|
|
NtGdiCombineRgn(VisRgn, VisRgn, ClipRgn, RGN_AND);
|
|
|
|
NtGdiDeleteObject(ClipRgn);
|
2004-02-22 12:25:35 +00:00
|
|
|
|
2004-05-14 16:48:47 +00:00
|
|
|
if ((PreviousWindow->Style & WS_CLIPSIBLINGS) ||
|
2004-02-22 16:56:14 +00:00
|
|
|
(PreviousWindow == Window && ClipSiblings))
|
2004-02-22 12:25:35 +00:00
|
|
|
{
|
2004-02-24 01:30:58 +00:00
|
|
|
IntLockRelatives(CurrentWindow);
|
2004-02-22 12:25:35 +00:00
|
|
|
CurrentSibling = CurrentWindow->FirstChild;
|
2004-02-29 17:43:41 +00:00
|
|
|
while (CurrentSibling != NULL && CurrentSibling != PreviousWindow)
|
2004-02-22 12:25:35 +00:00
|
|
|
{
|
|
|
|
if (CurrentSibling->Style & WS_VISIBLE)
|
|
|
|
{
|
|
|
|
ClipRgn = UnsafeIntCreateRectRgnIndirect(&CurrentSibling->WindowRect);
|
2004-03-23 16:32:20 +00:00
|
|
|
/* Combine it with the window region if available */
|
2004-03-23 18:08:07 +00:00
|
|
|
if(CurrentSibling->WindowRegion && !(CurrentSibling->Style & WS_MINIMIZE))
|
2004-03-23 16:32:20 +00:00
|
|
|
{
|
|
|
|
NtGdiOffsetRgn(ClipRgn, -CurrentSibling->WindowRect.left, -CurrentSibling->WindowRect.top);
|
|
|
|
NtGdiCombineRgn(ClipRgn, ClipRgn, CurrentSibling->WindowRegion, RGN_AND);
|
|
|
|
NtGdiOffsetRgn(ClipRgn, CurrentSibling->WindowRect.left, CurrentSibling->WindowRect.top);
|
|
|
|
}
|
2004-02-22 12:25:35 +00:00
|
|
|
NtGdiCombineRgn(VisRgn, VisRgn, ClipRgn, RGN_DIFF);
|
|
|
|
NtGdiDeleteObject(ClipRgn);
|
|
|
|
}
|
|
|
|
CurrentSibling = CurrentSibling->NextSibling;
|
|
|
|
}
|
2004-02-24 01:30:58 +00:00
|
|
|
IntUnLockRelatives(CurrentWindow);
|
2004-02-22 12:25:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
PreviousWindow = CurrentWindow;
|
2004-02-24 01:30:58 +00:00
|
|
|
CurrentWindow = IntGetParentObject(CurrentWindow);
|
|
|
|
IntReleaseWindowObject(PreviousWindow);
|
2004-01-17 15:18:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (ClipChildren)
|
|
|
|
{
|
2004-02-24 01:30:58 +00:00
|
|
|
IntLockRelatives(Window);
|
2004-01-17 15:18:25 +00:00
|
|
|
CurrentWindow = Window->FirstChild;
|
|
|
|
while (CurrentWindow)
|
|
|
|
{
|
|
|
|
if (CurrentWindow->Style & WS_VISIBLE)
|
|
|
|
{
|
|
|
|
ClipRgn = UnsafeIntCreateRectRgnIndirect(&CurrentWindow->WindowRect);
|
2004-03-23 16:32:20 +00:00
|
|
|
/* Combine it with the window region if available */
|
2004-03-23 18:08:07 +00:00
|
|
|
if(CurrentWindow->WindowRegion && !(CurrentWindow->Style & WS_MINIMIZE))
|
2004-03-23 16:32:20 +00:00
|
|
|
{
|
|
|
|
NtGdiOffsetRgn(ClipRgn, -CurrentWindow->WindowRect.left, -CurrentWindow->WindowRect.top);
|
|
|
|
NtGdiCombineRgn(ClipRgn, ClipRgn, CurrentWindow->WindowRegion, RGN_AND);
|
|
|
|
NtGdiOffsetRgn(ClipRgn, CurrentWindow->WindowRect.left, CurrentWindow->WindowRect.top);
|
|
|
|
}
|
2004-01-17 15:18:25 +00:00
|
|
|
NtGdiCombineRgn(VisRgn, VisRgn, ClipRgn, RGN_DIFF);
|
|
|
|
NtGdiDeleteObject(ClipRgn);
|
|
|
|
}
|
|
|
|
CurrentWindow = CurrentWindow->NextSibling;
|
|
|
|
}
|
2004-02-24 01:30:58 +00:00
|
|
|
IntUnLockRelatives(Window);
|
2004-01-17 15:18:25 +00:00
|
|
|
}
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2004-03-23 18:08:07 +00:00
|
|
|
if(Window->WindowRegion && !(Window->Style & WS_MINIMIZE))
|
2004-03-23 16:32:20 +00:00
|
|
|
{
|
|
|
|
NtGdiOffsetRgn(VisRgn, -LeftOffset, -TopOffset);
|
|
|
|
NtGdiCombineRgn(VisRgn, VisRgn, Window->WindowRegion, RGN_AND);
|
|
|
|
return VisRgn;
|
|
|
|
}
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2004-01-17 15:18:25 +00:00
|
|
|
NtGdiOffsetRgn(VisRgn, -LeftOffset, -TopOffset);
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2004-01-17 15:18:25 +00:00
|
|
|
return VisRgn;
|
|
|
|
}
|
2003-07-17 07:49:15 +00:00
|
|
|
|
|
|
|
VOID FASTCALL
|
2004-01-17 15:18:25 +00:00
|
|
|
VIS_WindowLayoutChanged(
|
|
|
|
PWINDOW_OBJECT Window,
|
|
|
|
HRGN NewlyExposed)
|
2003-07-17 07:49:15 +00:00
|
|
|
{
|
2003-12-27 15:09:51 +00:00
|
|
|
HRGN Temp;
|
2004-02-24 01:30:58 +00:00
|
|
|
PWINDOW_OBJECT Parent;
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2003-12-27 15:09:51 +00:00
|
|
|
Temp = NtGdiCreateRectRgn(0, 0, 0, 0);
|
|
|
|
NtGdiCombineRgn(Temp, NewlyExposed, NULL, RGN_COPY);
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2004-02-24 01:30:58 +00:00
|
|
|
Parent = IntGetParentObject(Window);
|
|
|
|
if(Parent)
|
2003-12-27 15:09:51 +00:00
|
|
|
{
|
|
|
|
NtGdiOffsetRgn(Temp,
|
2004-02-24 01:30:58 +00:00
|
|
|
Window->WindowRect.left - Parent->ClientRect.left,
|
|
|
|
Window->WindowRect.top - Parent->ClientRect.top);
|
2004-02-26 22:23:55 +00:00
|
|
|
IntRedrawWindow(Parent, NULL, Temp,
|
2005-05-08 02:11:54 +00:00
|
|
|
RDW_FRAME | RDW_ERASE | RDW_INVALIDATE |
|
2004-02-26 22:23:55 +00:00
|
|
|
RDW_ALLCHILDREN);
|
2004-02-24 01:30:58 +00:00
|
|
|
IntReleaseWindowObject(Parent);
|
2004-02-26 22:23:55 +00:00
|
|
|
}
|
2003-12-27 15:09:51 +00:00
|
|
|
NtGdiDeleteObject(Temp);
|
2003-07-17 07:49:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* EOF */
|