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.
|
|
|
|
*
|
2004-02-24 01:30:58 +00:00
|
|
|
* $Id: vis.c,v 1.20 2004/02/24 01:30:57 weiden Exp $
|
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)
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <win32k/win32k.h>
|
|
|
|
#include <include/painting.h>
|
|
|
|
#include <include/rect.h>
|
|
|
|
#include <include/vis.h>
|
|
|
|
|
|
|
|
#define NDEBUG
|
|
|
|
#include <win32k/debug1.h>
|
|
|
|
#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))
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ClientArea)
|
|
|
|
{
|
|
|
|
VisRgn = UnsafeIntCreateRectRgnIndirect(&Window->ClientRect);
|
|
|
|
LeftOffset = Window->ClientRect.left;
|
|
|
|
TopOffset = Window->ClientRect.top;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
VisRgn = UnsafeIntCreateRectRgnIndirect(&Window->WindowRect);
|
|
|
|
LeftOffset = Window->WindowRect.left;
|
|
|
|
TopOffset = Window->WindowRect.top;
|
|
|
|
}
|
|
|
|
|
2004-02-22 12:25:35 +00:00
|
|
|
/*
|
|
|
|
* Walk through all perent windows and for each clip the visble region
|
|
|
|
* 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);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
ClipRgn = UnsafeIntCreateRectRgnIndirect(&CurrentWindow->ClientRect);
|
|
|
|
NtGdiCombineRgn(VisRgn, VisRgn, ClipRgn, RGN_AND);
|
|
|
|
NtGdiDeleteObject(ClipRgn);
|
2004-02-22 12:25:35 +00:00
|
|
|
|
2004-02-22 16:56:14 +00:00
|
|
|
if ((CurrentWindow->Style & WS_CLIPSIBLINGS) ||
|
|
|
|
(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;
|
|
|
|
while (CurrentSibling != PreviousWindow)
|
|
|
|
{
|
|
|
|
if (CurrentSibling->Style & WS_VISIBLE)
|
|
|
|
{
|
|
|
|
ClipRgn = UnsafeIntCreateRectRgnIndirect(&CurrentSibling->WindowRect);
|
|
|
|
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);
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
|
|
NtGdiOffsetRgn(VisRgn, -LeftOffset, -TopOffset);
|
|
|
|
|
|
|
|
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;
|
2003-12-27 15:09:51 +00:00
|
|
|
|
|
|
|
Temp = NtGdiCreateRectRgn(0, 0, 0, 0);
|
|
|
|
NtGdiCombineRgn(Temp, NewlyExposed, NULL, RGN_COPY);
|
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);
|
2003-12-27 15:09:51 +00:00
|
|
|
}
|
2004-02-24 01:30:58 +00:00
|
|
|
IntRedrawWindow(Parent, NULL, Temp,
|
2003-12-27 15:09:51 +00:00
|
|
|
RDW_FRAME | RDW_ERASE | RDW_INVALIDATE |
|
|
|
|
RDW_ALLCHILDREN);
|
2004-02-24 01:30:58 +00:00
|
|
|
if(Parent)
|
|
|
|
IntReleaseWindowObject(Parent);
|
2003-12-27 15:09:51 +00:00
|
|
|
NtGdiDeleteObject(Temp);
|
2003-07-17 07:49:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* EOF */
|