Fixes to WinPosSetWindowPos() and the routines it depends upon

svn path=/trunk/; revision=6020
This commit is contained in:
Gé van Geldorp 2003-09-09 09:39:21 +00:00
parent a5743bd648
commit db573c519a
11 changed files with 522 additions and 471 deletions

View file

@ -380,6 +380,8 @@ DrvBitBlt(SURFOBJ *Dest,
RECT_ENUM RectEnum;
BOOL EnumMore;
unsigned i;
POINTL Pt;
ULONG Direction;
switch (rop4)
{
@ -420,13 +422,30 @@ DrvBitBlt(SURFOBJ *Dest,
case DC_RECT:
// Clip the blt to the clip rectangle
VGADDI_IntersectRect(&CombinedRect, DestRect, &(Clip->rclBounds));
Pt.x = SourcePoint->x + CombinedRect.left - DestRect->left;
Pt.y = SourcePoint->y + CombinedRect.top - DestRect->top;
Ret = (*BltRectFunc)(Dest, Source, Mask, ColorTranslation, &CombinedRect,
SourcePoint, MaskPoint, Brush, BrushPoint,
&Pt, MaskPoint, Brush, BrushPoint,
rop4);
break;
case DC_COMPLEX:
Ret = TRUE;
CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_ANY, ENUM_RECT_LIMIT);
if (Dest == Source)
{
if (DestRect->top <= SourcePoint->y)
{
Direction = DestRect->left < SourcePoint->x ? CD_RIGHTDOWN : CD_LEFTDOWN;
}
else
{
Direction = DestRect->left < SourcePoint->x ? CD_RIGHTUP : CD_LEFTUP;
}
}
else
{
Direction = CD_ANY;
}
CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, Direction, ENUM_RECT_LIMIT);
do
{
EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
@ -434,8 +453,10 @@ DrvBitBlt(SURFOBJ *Dest,
for (i = 0; i < RectEnum.c; i++)
{
VGADDI_IntersectRect(&CombinedRect, DestRect, RectEnum.arcl + i);
Pt.x = SourcePoint->x + CombinedRect.left - DestRect->left;
Pt.y = SourcePoint->y + CombinedRect.top - DestRect->top;
Ret = (*BltRectFunc)(Dest, Source, Mask, ColorTranslation, &CombinedRect,
SourcePoint, MaskPoint, Brush, BrushPoint, rop4) &&
&Pt, MaskPoint, Brush, BrushPoint, rop4) &&
Ret;
}
}

View file

@ -154,5 +154,6 @@ HRGN STDCALL REGION_CropRgn(HRGN hDst, HRGN hSrc, const PRECT lpRect, PPOINT lpP
HRGN STDCALL UnsafeIntCreateRectRgnIndirect(CONST PRECT rc);
INT STDCALL UnsafeIntGetRgnBox(HRGN hRgn, LPRECT pRect);
HRGN FASTCALL UnsafeIntUnionRectWithRgn(HRGN hDest, CONST PRECT Rect);
BOOL FASTCALL UnsafeIntRectInRegion(HRGN hRgn, CONST LPRECT rc);
#endif

View file

@ -1,4 +1,4 @@
/* $Id: defwnd.c,v 1.84 2003/09/08 18:50:00 weiden Exp $
/* $Id: defwnd.c,v 1.85 2003/09/09 09:39:21 gvg Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS user32.dll
@ -602,11 +602,9 @@ UserDrawCaptionNC (
}
VOID
UserDrawFrameNC(HWND hWnd, RECT* rect, BOOL dlgFrame, BOOL active)
static VOID
UserDrawFrameNC(HDC hDC, RECT* rect, BOOL dlgFrame, BOOL active)
{
HDC hDC = GetWindowDC(hWnd);
SelectObject( hDC, GetSysColorBrush(COLOR_WINDOW) );
DrawEdge(hDC, rect,EDGE_RAISED, BF_RECT | BF_MIDDLE);
}
@ -624,7 +622,6 @@ DefWndDoPaintNC(HWND hWnd, HRGN clip)
ULONG ExStyle;
int wFrame = 0;
// This won't work because it conflicts with BS_BITMAP :
if (GetActiveWindow() == hWnd) Active = TRUE;
Style = GetWindowLongW(hWnd, GWL_STYLE);
ExStyle = GetWindowLongW(hWnd, GWL_EXSTYLE);
@ -645,12 +642,12 @@ DefWndDoPaintNC(HWND hWnd, HRGN clip)
SelectObject(hDC, GetSysColorPen(COLOR_WINDOWFRAME));
if (UserHasThickFrameStyle(Style, ExStyle))
{
UserDrawFrameNC(hWnd, &rect, FALSE, Active);
UserDrawFrameNC(hDC, &rect, FALSE, Active);
wFrame = GetSystemMetrics(SM_CXSIZEFRAME);
}
else if (UserHasDlgFrameStyle(Style, ExStyle))
{
UserDrawFrameNC(hWnd, &rect, TRUE, Active);
UserDrawFrameNC(hDC, &rect, TRUE, Active);
wFrame = GetSystemMetrics(SM_CXDLGFRAME);
}
if (Style & WS_CAPTION)

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: bitblt.c,v 1.26 2003/08/17 17:32:58 royce Exp $
/* $Id: bitblt.c,v 1.27 2003/09/09 09:39:21 gvg Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -105,11 +105,11 @@ BltMask(PSURFOBJ Dest,
if (Mask != NULL)
{
tMask = Mask->pvBits;
tMask = Mask->pvBits + SourcePoint->y * Mask->lDelta + (SourcePoint->x >> 3);
for (j = 0; j < dy; j++)
{
lMask = tMask;
c8 = 0;
c8 = SourcePoint->x & 0x07;
for (i = 0; i < dx; i++)
{
if (0 != (*lMask & maskbit[c8]))
@ -213,6 +213,8 @@ EngBitBlt(SURFOBJ *DestObj,
BOOLEAN Ret;
RECTL ClipRect;
unsigned i;
POINTL Pt;
ULONG Direction;
if (NULL != SourcePoint)
{
@ -340,12 +342,29 @@ EngBitBlt(SURFOBJ *DestObj,
ClipRect.top = ClipRegion->rclBounds.top + Translate.y;
ClipRect.bottom = ClipRegion->rclBounds.bottom + Translate.y;
EngIntersectRect(&CombinedRect, &OutputRect, &ClipRect);
Pt.x = InputPoint.x + CombinedRect.left - OutputRect.left;
Pt.y = InputPoint.y + CombinedRect.top - OutputRect.top;
Ret = (*BltRectFunc)(OutputObj, OutputGDI, InputObj, InputGDI, Mask, ColorTranslation,
&CombinedRect, &InputPoint, MaskOrigin, Brush, BrushOrigin, Rop4);
&CombinedRect, &Pt, MaskOrigin, Brush, BrushOrigin, Rop4);
break;
case DC_COMPLEX:
Ret = TRUE;
CLIPOBJ_cEnumStart(ClipRegion, FALSE, CT_RECTANGLES, CD_ANY, ENUM_RECT_LIMIT);
if (OutputObj == InputObj)
{
if (OutputRect.top < InputPoint.y)
{
Direction = OutputRect.left < InputPoint.x ? CD_RIGHTDOWN : CD_LEFTDOWN;
}
else
{
Direction = OutputRect.left < InputPoint.x ? CD_RIGHTUP : CD_LEFTUP;
}
}
else
{
Direction = CD_ANY;
}
CLIPOBJ_cEnumStart(ClipRegion, FALSE, CT_RECTANGLES, Direction, ENUM_RECT_LIMIT);
do
{
EnumMore = CLIPOBJ_bEnum(ClipRegion,(ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
@ -357,8 +376,10 @@ EngBitBlt(SURFOBJ *DestObj,
ClipRect.top = RectEnum.arcl[i].top + Translate.y;
ClipRect.bottom = RectEnum.arcl[i].bottom + Translate.y;
EngIntersectRect(&CombinedRect, &OutputRect, &ClipRect);
Pt.x = InputPoint.x + CombinedRect.left - OutputRect.left;
Pt.y = InputPoint.y + CombinedRect.top - OutputRect.top;
Ret = (*BltRectFunc)(OutputObj, OutputGDI, InputObj, InputGDI, Mask, ColorTranslation,
&CombinedRect, &InputPoint, MaskOrigin, Brush, BrushOrigin, Rop4) &&
&CombinedRect, &Pt, MaskOrigin, Brush, BrushOrigin, Rop4) &&
Ret;
}
}

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: painting.c,v 1.30 2003/08/28 13:38:24 gvg Exp $
/* $Id: painting.c,v 1.31 2003/09/09 09:39:21 gvg Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -274,7 +274,8 @@ PaintUpdateRgns(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags,
}
Window->UpdateRegion =
REGION_CropRgn(Window->UpdateRegion,
Window->UpdateRegion, &Rect, NULL);
Window->UpdateRegion ? Window->UpdateRegion : hRgn,
&Rect, NULL);
if (! HadOne)
{
UnsafeIntGetRgnBox(Window->UpdateRegion, &Rect);
@ -389,42 +390,38 @@ PaintUpdateRgns(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags,
{
POINT Total = {0, 0};
POINT PrevOrign = {0, 0};
POINT Client;
PWINDOW_OBJECT Child;
Client.x = Window->ClientRect.left - Window->WindowRect.left;
Client.y = Window->ClientRect.top - Window->WindowRect.top;
ExAcquireFastMutexUnsafe(&Window->ChildrenListLock);
Child = Window->FirstChild;
while (Child)
{
if (0 != (Child->Style & WS_VISIBLE))
{
POINT Offset;
ExAcquireFastMutexUnsafe(&Window->ChildrenListLock);
Child = Window->FirstChild;
while (Child)
{
if (0 != (Child->Style & WS_VISIBLE))
{
POINT Offset;
Rect.left = Child->WindowRect.left - Window->WindowRect.left;
Rect.top = Child->WindowRect.top - Window->WindowRect.top;
Rect.right = Child->WindowRect.right - Window->WindowRect.left;
Rect.bottom = Child->WindowRect.bottom - Window->WindowRect.top;
Rect.left = Window->WindowRect.left + Client.x;
Rect.right = Window->WindowRect.right + Client.x;
Rect.top = Window->WindowRect.top + Client.y;
Rect.bottom = Window->WindowRect.bottom + Client.y;
Offset.x = Rect.left - PrevOrign.x;
Offset.y = Rect.top - PrevOrign.y;
NtGdiOffsetRect(&Rect, -Total.x, -Total.y);
Offset.x = Rect.left - PrevOrign.x;
Offset.y = Rect.top - PrevOrign.y;
NtGdiOffsetRect(&Rect, -Total.x, -Total.y);
if (NtGdiRectInRegion(hRgn, &Rect))
{
NtGdiOffsetRgn(hRgn, -Total.x, -Total.y);
PaintUpdateRgns(Child, hRgn, Flags, FALSE);
PrevOrign.x = Rect.left + Total.x;
PrevOrign.y = Rect.right + Total.y;
Total.x += Offset.x;
Total.y += Offset.y;
}
}
Child = Child->NextSibling;
}
ExReleaseFastMutexUnsafe(&Window->ChildrenListLock);
if (UnsafeIntRectInRegion(hRgn, &Rect))
{
NtGdiOffsetRgn(hRgn, -Offset.x, -Offset.y);
PaintUpdateRgns(Child, hRgn, Flags, FALSE);
PrevOrign.x = Rect.left + Total.x;
PrevOrign.y = Rect.right + Total.y;
Total.x += Offset.x;
Total.y += Offset.y;
}
}
Child = Child->NextSibling;
}
ExReleaseFastMutexUnsafe(&Window->ChildrenListLock);
NtGdiOffsetRgn(hRgn, Total.x, Total.y);
HasChildren = FALSE;
@ -746,11 +743,11 @@ PaintUpdateNCRegion(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags)
UnsafeIntGetRgnBox(Window->UpdateRegion, &UpdateRegionBox);
NtGdiUnionRect(&Rect, &ClientRect, &UpdateRegionBox);
if (Rect.left != ClientRect.left || Rect.top != ClientRect.top ||
Rect.right != ClientRect.right || Rect.right != ClientRect.right)
Rect.right != ClientRect.right || Rect.bottom != ClientRect.bottom)
{
hClip = Window->UpdateRegion;
Window->UpdateRegion = REGION_CropRgn(hRgn, hClip,
&Rect, NULL);
&ClientRect, NULL);
if (Flags & UNC_REGION)
{
hRgnRet = hClip;
@ -854,6 +851,28 @@ NtUserEndPaint(HWND hWnd, CONST PAINTSTRUCT* lPs)
return(TRUE);
}
static
HRGN FASTCALL
GetClientUpdateRegion(PWINDOW_OBJECT Window)
{
POINT Offset;
RECT Rect;
if ((DWORD) Window->UpdateRegion <= 1)
{
return Window->UpdateRegion;
}
Offset.x = Window->WindowRect.left - Window->ClientRect.left;
Offset.y = Window->WindowRect.top - Window->ClientRect.top;
Rect.left = - Offset.x;
Rect.top = - Offset.y;
Rect.right = Rect.left + (Window->ClientRect.right - Window->ClientRect.left);
Rect.bottom = Rect.top + (Window->ClientRect.bottom - Window->ClientRect.top);
return REGION_CropRgn(NULL, Window->UpdateRegion, &Rect, &Offset);
}
HDC STDCALL
NtUserBeginPaint(HWND hWnd, PAINTSTRUCT* lPs)
{
@ -881,7 +900,11 @@ NtUserBeginPaint(HWND hWnd, PAINTSTRUCT* lPs)
}
/* retrieve update region */
UpdateRegion = Window->UpdateRegion;
UpdateRegion = GetClientUpdateRegion(Window);
if (1 < (DWORD) Window->UpdateRegion)
{
NtGdiDeleteObject(Window->UpdateRegion);
}
Window->UpdateRegion = 0;
if (UpdateRegion != NULL || (Window->Flags & WINDOWOBJECT_NEED_INTERNALPAINT))
{

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: vis.c,v 1.6 2003/08/19 11:48:50 weiden Exp $
* $Id: vis.c,v 1.7 2003/09/09 09:39:21 gvg Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -139,6 +139,7 @@ VIS_ComputeVisibleRegion(PDESKTOP_OBJECT Desktop, PWINDOW_OBJECT Window,
RECT Rect;
HRGN ClipRgn;
PWINDOW_OBJECT DesktopWindow;
INT LeftOffset, TopOffset;
DesktopWindow = IntGetWindowObject(Desktop->DesktopWindow);
if (NULL == DesktopWindow)
@ -152,6 +153,17 @@ VIS_ComputeVisibleRegion(PDESKTOP_OBJECT Desktop, PWINDOW_OBJECT Window,
VisRgn = UnsafeIntCreateRectRgnIndirect(&Rect);
if (NULL != VisRgn)
{
if (ClientArea)
{
LeftOffset = Window->ClientRect.left;
TopOffset = Window->ClientRect.top;
}
else
{
LeftOffset = Window->WindowRect.left;
TopOffset = Window->WindowRect.top;
}
ClipRgn = NtGdiCreateRectRgn(0, 0, 0, 0);
if (ClipRgn != NULL)
@ -179,6 +191,7 @@ VIS_ComputeVisibleRegion(PDESKTOP_OBJECT Desktop, PWINDOW_OBJECT Window,
NtGdiCombineRgn(VisRgn, VisRgn, ClipRgn, RGN_DIFF);
NtGdiDeleteObject(ClipRgn);
NtGdiOffsetRgn(VisRgn, -LeftOffset, -TopOffset);
}
else
{
@ -208,6 +221,34 @@ VIS_RepaintDesktop(HWND Desktop, HRGN RepaintRgn)
NtUserReleaseDC(Desktop, dc);
}
static VOID FASTCALL
GetUncoveredArea(HRGN Uncovered, PWINDOW_OBJECT Parent, PWINDOW_OBJECT TargetChild,
BOOL IncludeTarget)
{
PWINDOW_OBJECT Child;
BOOL Passed;
HRGN Covered;
Passed = FALSE;
ExAcquireFastMutexUnsafe(&Parent->ChildrenListLock);
Child = Parent->FirstChild;
while (! Passed && Child)
{
if (0 != (Child->Style & WS_VISIBLE) && (Child != TargetChild || IncludeTarget))
{
Covered = UnsafeIntCreateRectRgnIndirect(&Child->WindowRect);
NtGdiCombineRgn(Uncovered, Uncovered, Covered, RGN_DIFF);
NtGdiDeleteObject(Covered);
}
if (Child == TargetChild)
{
Passed = TRUE;
}
Child = Child->NextSibling;
}
ExReleaseFastMutexUnsafe(&Parent->ChildrenListLock);
}
VOID FASTCALL
@ -215,33 +256,95 @@ VIS_WindowLayoutChanged(PDESKTOP_OBJECT Desktop, PWINDOW_OBJECT Window,
HRGN NewlyExposed)
{
PWINDOW_OBJECT DesktopWindow;
PWINDOW_OBJECT Child;
PWINDOW_OBJECT Parent;
PWINDOW_OBJECT Sibling;
PWINDOW_OBJECT TopLevel;
HRGN Uncovered;
HRGN Covered;
HRGN Repaint;
HRGN DirtyRgn;
HRGN ExposedWindow;
HRGN Covered;
INT RgnType;
POINT Offset;
DesktopWindow = IntGetWindowObject(Desktop->DesktopWindow);
Uncovered = UnsafeIntCreateRectRgnIndirect(&DesktopWindow->WindowRect);
ExAcquireFastMutexUnsafe(&DesktopWindow->ChildrenListLock);
Child = DesktopWindow->FirstChild;
while (Child)
{
if (0 != (Child->Style & WS_VISIBLE))
if (Window->Style & WS_CHILD)
{
Covered = UnsafeIntCreateRectRgnIndirect(&Child->WindowRect);
NtGdiCombineRgn(Uncovered, Uncovered, Covered, RGN_DIFF);
PaintRedrawWindow(Child, NULL, NULL, RDW_INVALIDATE | RDW_FRAME | RDW_ERASE, 0);
NtGdiDeleteObject(Covered);
}
Child = Child->NextSibling;
}
ExReleaseFastMutexUnsafe(&DesktopWindow->ChildrenListLock);
/* Determine our toplevel window */
TopLevel = Window;
while (TopLevel->Style & WS_CHILD)
{
TopLevel = TopLevel->Parent;
}
Repaint = NtGdiCreateRectRgn(0, 0, 0, 0);
NtGdiCombineRgn(Repaint, NewlyExposed, Uncovered, RGN_AND);
VIS_RepaintDesktop(DesktopWindow->Self, Repaint);
NtGdiDeleteObject(Repaint);
GetUncoveredArea(Uncovered, DesktopWindow, TopLevel, FALSE);
Parent = Window->Parent;
}
else
{
Parent = DesktopWindow;
}
GetUncoveredArea(Uncovered, Parent, Window, TRUE);
ExAcquireFastMutexUnsafe(&Parent->ChildrenListLock);
Sibling = Window->NextSibling;
while (Sibling)
{
if (0 != (Sibling->Style & WS_VISIBLE))
{
Offset.x = - Sibling->WindowRect.left;
Offset.y = - Sibling->WindowRect.top;
DirtyRgn = REGION_CropRgn(NULL, Uncovered, &Sibling->WindowRect, &Offset);
Offset.x = Window->WindowRect.left - Sibling->WindowRect.left;
Offset.y = Window->WindowRect.top - Sibling->WindowRect.top;
ExposedWindow = REGION_CropRgn(NULL, NewlyExposed, NULL, &Offset);
RgnType = NtGdiCombineRgn(DirtyRgn, DirtyRgn, ExposedWindow, RGN_AND);
if (NULLREGION != RgnType && ERROR != RgnType)
{
PaintRedrawWindow(Sibling, NULL, DirtyRgn,
RDW_INVALIDATE | RDW_FRAME | RDW_ERASE
| RDW_ALLCHILDREN, RDW_EX_XYWINDOW);
}
Covered = UnsafeIntCreateRectRgnIndirect(&Sibling->WindowRect);
NtGdiCombineRgn(Uncovered, Uncovered, Covered, RGN_DIFF);
NtGdiDeleteObject(Covered);
NtGdiDeleteObject(ExposedWindow);
NtGdiDeleteObject(DirtyRgn);
}
Sibling = Sibling->NextSibling;
}
ExReleaseFastMutexUnsafe(&Parent->ChildrenListLock);
if (Window->Style & WS_CHILD)
{
Offset.x = - Parent->WindowRect.left;
Offset.y = - Parent->WindowRect.top;
DirtyRgn = REGION_CropRgn(NULL, Uncovered, &Parent->WindowRect, &Offset);
Offset.x = Window->WindowRect.left - Parent->WindowRect.left;
Offset.y = Window->WindowRect.top - Parent->WindowRect.top;
ExposedWindow = REGION_CropRgn(NULL, NewlyExposed, NULL, &Offset);
RgnType = NtGdiCombineRgn(DirtyRgn, DirtyRgn, ExposedWindow, RGN_AND);
if (NULLREGION != RgnType && ERROR != RgnType)
{
PaintRedrawWindow(Parent, NULL, DirtyRgn,
RDW_INVALIDATE | RDW_FRAME | RDW_ERASE
| RDW_NOCHILDREN, RDW_EX_XYWINDOW);
}
NtGdiDeleteObject(ExposedWindow);
NtGdiDeleteObject(DirtyRgn);
}
else
{
Repaint = NtGdiCreateRectRgn(0, 0, 0, 0);
NtGdiCombineRgn(Repaint, NewlyExposed, NULL, RGN_COPY);
NtGdiOffsetRgn(Repaint, Window->WindowRect.left, Window->WindowRect.top);
NtGdiCombineRgn(Repaint, Repaint, Uncovered, RGN_AND);
VIS_RepaintDesktop(DesktopWindow->Self, Repaint);
NtGdiDeleteObject(Repaint);
}
NtGdiDeleteObject(Uncovered);
}

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: windc.c,v 1.22 2003/08/20 07:45:01 gvg Exp $
/* $Id: windc.c,v 1.23 2003/09/09 09:39:21 gvg Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -416,12 +416,12 @@ NtUserGetDCEx(HWND hWnd, HANDLE ClipRegion, ULONG Flags)
}
}
if (0 != (Dce->DCXFlags & DCX_INTERSECTRGN))
if (0 != (Flags & DCX_INTERSECTRGN))
{
NtGdiCombineRgn(hRgnVisible, hRgnVisible, Dce->hClipRgn, RGN_AND);
}
if (0 != (Dce->DCXFlags & DCX_EXCLUDERGN))
if (0 != (Flags & DCX_EXCLUDERGN))
{
NtGdiCombineRgn(hRgnVisible, hRgnVisible, Dce->hClipRgn, RGN_DIFF);
}

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: winpos.c,v 1.29 2003/08/29 09:29:11 gvg Exp $
/* $Id: winpos.c,v 1.30 2003/09/09 09:39:21 gvg Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -378,7 +378,66 @@ LONG STATIC STDCALL
WinPosDoNCCALCSize(PWINDOW_OBJECT Window, PWINDOWPOS WinPos,
RECT* WindowRect, RECT* ClientRect)
{
return 0; /* FIXME: Calculate non client size */
UINT wvrFlags = 0;
/* Send WM_NCCALCSIZE message to get new client area */
if ((WinPos->flags & (SWP_FRAMECHANGED | SWP_NOSIZE)) != SWP_NOSIZE)
{
NCCALCSIZE_PARAMS params;
WINDOWPOS winposCopy;
params.rgrc[0] = *WindowRect;
params.rgrc[1] = Window->WindowRect;
params.rgrc[2] = Window->ClientRect;
if (Window->Style & WS_CHILD)
{
NtGdiOffsetRect(&(params.rgrc[2]), - Window->Parent->ClientRect.left,
- Window->Parent->ClientRect.top);
}
params.lppos = &winposCopy;
winposCopy = *WinPos;
wvrFlags = IntSendNCCALCSIZEMessage(Window->Self, TRUE, NULL, &params);
/* If the application send back garbage, ignore it */
if (params.rgrc[0].left <= params.rgrc[0].right &&
params.rgrc[0].top <= params.rgrc[0].bottom)
{
*ClientRect = params.rgrc[0];
if (Window->Style & WS_CHILD)
{
NtGdiOffsetRect(ClientRect, Window->Parent->ClientRect.left,
Window->Parent->ClientRect.top);
}
}
/* FIXME: WVR_ALIGNxxx */
if (ClientRect->left != Window->ClientRect.left ||
ClientRect->top != Window->ClientRect.top)
{
WinPos->flags &= ~SWP_NOCLIENTMOVE;
}
if ((ClientRect->right - ClientRect->left !=
Window->ClientRect.right - Window->ClientRect.left) ||
(ClientRect->bottom - ClientRect->top !=
Window->ClientRect.bottom - Window->ClientRect.top))
{
WinPos->flags &= ~SWP_NOCLIENTSIZE;
}
}
else
{
if (! (WinPos->flags & SWP_NOMOVE)
&& (ClientRect->left != Window->ClientRect.left ||
ClientRect->top != Window->ClientRect.top))
{
WinPos->flags &= ~SWP_NOCLIENTMOVE;
}
}
return wvrFlags;
}
BOOL STDCALL
@ -416,280 +475,9 @@ WinPosDoWinPosChanging(PWINDOW_OBJECT WindowObject,
WinPos->flags |= SWP_NOCLIENTMOVE | SWP_NOCLIENTSIZE;
if (!(WinPos->flags & SWP_NOSIZE) || !(WinPos->flags & SWP_NOMOVE))
{
WinPosGetNonClientSize(WindowObject->Self, WindowRect, ClientRect);
}
return(TRUE);
}
/***********************************************************************
* SWP_DoSimpleFrameChanged
*
* NOTE: old and new client rect origins are identical, only
* extents may have changed. Window extents are the same.
*/
VOID STATIC
WinPosDoSimpleFrameChanged( PWINDOW_OBJECT wndPtr, RECT* pOldClientRect, WORD swpFlags, UINT uFlags )
{
INT i = 0;
RECT rect;
HRGN hrgn = 0;
if( !(swpFlags & SWP_NOCLIENTSIZE) )
{
/* Client rect changed its position/size, most likely a scrollar
* was added/removed.
*
* FIXME: WVR alignment flags
*/
if( wndPtr->ClientRect.right > pOldClientRect->right ) /* right edge */
{
i++;
rect.top = 0;
rect.bottom = wndPtr->ClientRect.bottom - wndPtr->ClientRect.top;
rect.right = wndPtr->ClientRect.right - wndPtr->ClientRect.left;
if(!(uFlags & SWP_EX_NOCOPY))
rect.left = pOldClientRect->right - wndPtr->ClientRect.left;
else
{
rect.left = 0;
goto redraw;
}
}
if( wndPtr->ClientRect.bottom > pOldClientRect->bottom ) /* bottom edge */
{
if( i )
hrgn = NtGdiCreateRectRgnIndirect( &rect );
rect.left = 0;
rect.right = wndPtr->ClientRect.right - wndPtr->ClientRect.left;
rect.bottom = wndPtr->ClientRect.bottom - wndPtr->ClientRect.top;
if(!(uFlags & SWP_EX_NOCOPY))
rect.top = pOldClientRect->bottom - wndPtr->ClientRect.top;
else
rect.top = 0;
if( i++ )
{
HRGN hRectRgn = NtGdiCreateRectRgnIndirect(&rect);
NtGdiCombineRgn(hrgn, hrgn, hRectRgn, RGN_OR);
NtGdiDeleteObject(hRectRgn);
}
}
if( i == 0 && (uFlags & SWP_EX_NOCOPY) ) /* force redraw anyway */
{
rect = wndPtr->WindowRect;
NtGdiOffsetRect( &rect, wndPtr->WindowRect.left - wndPtr->ClientRect.left,
wndPtr->WindowRect.top - wndPtr->ClientRect.top );
i++;
}
}
if( i )
{
redraw:
PaintRedrawWindow( wndPtr, &rect, hrgn, RDW_INVALIDATE | RDW_FRAME | RDW_ERASE |
RDW_ERASENOW | RDW_ALLCHILDREN, RDW_EX_TOPFRAME | RDW_EX_USEHRGN );
}
else
{
PaintUpdateNCRegion(wndPtr, 0, UNC_UPDATE | UNC_ENTIRE);
}
if( hrgn > (HRGN)1 )
NtGdiDeleteObject( hrgn );
}
/***********************************************************************
* SWP_CopyValidBits
*
* Make window look nice without excessive repainting
*
* visible and update regions are in window coordinates
* client and window rectangles are in parent client coordinates
*
* Returns: uFlags and a dirty region in *pVisRgn.
*/
static UINT WinPosCopyValidBits( PWINDOW_OBJECT Wnd, HRGN* pVisRgn,
LPRECT lpOldWndRect,
LPRECT lpOldClientRect, UINT uFlags )
{
RECT r;
HRGN newVisRgn, dirtyRgn;
INT my = COMPLEXREGION;
if( Wnd->UpdateRegion == (HRGN)1 )
uFlags |= SWP_EX_NOCOPY; /* whole window is invalid, nothing to copy */
newVisRgn = DceGetVisRgn( Wnd->Self, DCX_WINDOW | DCX_CLIPSIBLINGS, 0, 0);
NtGdiOffsetRgn(newVisRgn, -Wnd->WindowRect.left, -Wnd->WindowRect.top);
dirtyRgn = NtGdiCreateRectRgn( 0, 0, 0, 0 );
if( !(uFlags & SWP_EX_NOCOPY) ) /* make sure dst region covers only valid bits */
my = NtGdiCombineRgn( dirtyRgn, newVisRgn, *pVisRgn, RGN_AND );
if( (my == NULLREGION) || (uFlags & SWP_EX_NOCOPY) )
{
nocopy:
/* set dirtyRgn to the sum of old and new visible regions
* in parent client coordinates */
NtGdiOffsetRgn( newVisRgn, Wnd->WindowRect.left, Wnd->WindowRect.top );
NtGdiOffsetRgn( *pVisRgn, lpOldWndRect->left, lpOldWndRect->top );
NtGdiCombineRgn(*pVisRgn, *pVisRgn, newVisRgn, RGN_OR );
}
else /* copy valid bits to a new location */
{
INT dx, dy, ow, oh, nw, nh, ocw, ncw, och, nch;
HRGN hrgnValid = dirtyRgn; /* non-empty intersection of old and new visible rgns */
/* subtract already invalid region inside Wnd from the dst region */
if( Wnd->UpdateRegion )
if( NtGdiCombineRgn( hrgnValid, hrgnValid, Wnd->UpdateRegion, RGN_DIFF) == NULLREGION )
goto nocopy;
/* check if entire window can be copied */
ow = lpOldWndRect->right - lpOldWndRect->left;
oh = lpOldWndRect->bottom - lpOldWndRect->top;
nw = Wnd->WindowRect.right - Wnd->WindowRect.left;
nh = Wnd->WindowRect.bottom - Wnd->WindowRect.top;
ocw = lpOldClientRect->right - lpOldClientRect->left;
och = lpOldClientRect->bottom - lpOldClientRect->top;
ncw = Wnd->ClientRect.right - Wnd->ClientRect.left;
nch = Wnd->ClientRect.bottom - Wnd->ClientRect.top;
if( (ocw != ncw) || (och != nch) ||
( ow != nw) || ( oh != nh) ||
((lpOldClientRect->top - lpOldWndRect->top) !=
(Wnd->ClientRect.top - Wnd->WindowRect.top)) ||
((lpOldClientRect->left - lpOldWndRect->left) !=
(Wnd->ClientRect.left - Wnd->WindowRect.left)) )
{
if(uFlags & SWP_EX_PAINTSELF)
{
/* movement relative to the window itself */
dx = (Wnd->ClientRect.left - Wnd->WindowRect.left) -
(lpOldClientRect->left - lpOldWndRect->left) ;
dy = (Wnd->ClientRect.top - Wnd->WindowRect.top) -
(lpOldClientRect->top - lpOldWndRect->top) ;
}
else
{
/* movement relative to the parent's client area */
dx = Wnd->ClientRect.left - lpOldClientRect->left;
dy = Wnd->ClientRect.top - lpOldClientRect->top;
}
/* restrict valid bits to the common client rect */
r.left = Wnd->ClientRect.left - Wnd->WindowRect.left;
r.top = Wnd->ClientRect.top - Wnd->WindowRect.top;
r.right = r.left + min( ocw, ncw );
r.bottom = r.top + min( och, nch );
REGION_CropRgn( hrgnValid, hrgnValid, &r,
(uFlags & SWP_EX_PAINTSELF) ? NULL : (POINT*)&(Wnd->WindowRect));
NtGdiGetRgnBox( hrgnValid, &r );
if( NtGdiIsEmptyRect( &r ) )
goto nocopy;
r = *lpOldClientRect;
}
else
{
if(uFlags & SWP_EX_PAINTSELF) {
/*
* with SWP_EX_PAINTSELF, the window repaints itself. Since a window can't move
* relative to itself, only the client area can change.
* if the client rect didn't change, there's nothing to do.
*/
dx = 0;
dy = 0;
}
else
{
dx = Wnd->WindowRect.left - lpOldWndRect->left;
dy = Wnd->WindowRect.top - lpOldWndRect->top;
NtGdiOffsetRgn( hrgnValid, Wnd->WindowRect.left, Wnd->WindowRect.top );
}
r = *lpOldWndRect;
}
if( !(uFlags & SWP_EX_PAINTSELF) )
{
/* Move remaining regions to parent coordinates */
NtGdiOffsetRgn( newVisRgn, Wnd->WindowRect.left, Wnd->WindowRect.top );
NtGdiOffsetRgn( *pVisRgn, lpOldWndRect->left, lpOldWndRect->top );
}
else
NtGdiOffsetRect( &r, -lpOldWndRect->left, -lpOldWndRect->top );
/* Compute combined dirty region (old + new - valid) */
NtGdiCombineRgn( *pVisRgn, *pVisRgn, newVisRgn, RGN_OR);
NtGdiCombineRgn( *pVisRgn, *pVisRgn, hrgnValid, RGN_DIFF);
/* Blt valid bits, r is the rect to copy */
if( dx || dy )
{
RECT rClip;
HDC hDC;
/* get DC and clip rect with drawable rect to avoid superfluous expose events
from copying clipped areas */
if( uFlags & SWP_EX_PAINTSELF )
{
hDC = NtUserGetDCEx( Wnd->Self, hrgnValid, DCX_WINDOW | DCX_CACHE |
DCX_KEEPCLIPRGN | DCX_INTERSECTRGN | DCX_CLIPSIBLINGS );
rClip.right = nw; rClip.bottom = nh;
}
else
{
hDC = NtUserGetDCEx( Wnd->Parent->Self, hrgnValid, DCX_CACHE |
DCX_KEEPCLIPRGN | DCX_INTERSECTRGN | DCX_CLIPSIBLINGS );
rClip.right = Wnd->Parent->ClientRect.right - Wnd->Parent->ClientRect.left;
rClip.bottom = Wnd->Parent->ClientRect.bottom - Wnd->Parent->ClientRect.top;
}
rClip.left = rClip.top = 0;
if( oh > nh ) r.bottom = r.top + nh;
if( ow < nw ) r.right = r.left + nw;
if( NtGdiIntersectRect( &r, &r, &rClip ) )
{
NtGdiBitBlt(hDC, dx + r.left, dy + r.top, r.right - r.left, r.bottom - r.top, hDC, r.left, r.top, SRCCOPY);
/* When you copy the bits without repainting, parent doesn't
get validated appropriately. Therefore, we have to validate
the parent with the windows' updated region when the
parent's update region is not empty. */
if (Wnd->Parent->UpdateRegion != 0 && !(Wnd->Parent->Style & WS_CLIPCHILDREN))
{
NtGdiOffsetRect(&r, dx, dy);
NtUserValidateRect(Wnd->Parent->Self, &r);
}
}
NtUserReleaseDC( (uFlags & SWP_EX_PAINTSELF) ?
Wnd->Self : Wnd->Parent->Self, hDC);
}
}
/* *pVisRgn now points to the invalidated region */
NtGdiDeleteObject(newVisRgn);
NtGdiDeleteObject(dirtyRgn);
return uFlags;
}
/***********************************************************************
* WinPosInternalMoveWindow
*
@ -731,11 +519,18 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
WINDOWPOS WinPos;
RECT NewWindowRect;
RECT NewClientRect;
HRGN VisRgn = NULL;
HRGN VisibleRgn = NULL;
HRGN VisBefore = NULL;
HRGN VisAfter = NULL;
HRGN DirtyRgn = NULL;
HRGN ExposedRgn = NULL;
HRGN CopyRgn = NULL;
ULONG WvrFlags = 0;
RECT OldWindowRect, OldClientRect;
UINT FlagsEx = 0;
int RgnType;
HDC Dc;
RECT CopyRect;
RECT TempRect;
/* FIXME: Get current active window from active queue. */
@ -822,6 +617,7 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
/* FIXME: Adjust flags based on WndInsertAfter */
/* Compute the visible region before the window position is changed */
if ((!(WinPos.flags & (SWP_NOREDRAW | SWP_SHOWWINDOW)) &&
WinPos.flags & (SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER |
SWP_HIDEWINDOW | SWP_FRAMECHANGED)) !=
@ -829,15 +625,19 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
{
if (Window->Style & WS_CLIPCHILDREN)
{
VisRgn = VIS_ComputeVisibleRegion(PsGetWin32Thread()->Desktop,
Window, FALSE, FALSE, TRUE);
VisBefore = VIS_ComputeVisibleRegion(PsGetWin32Thread()->Desktop,
Window, FALSE, FALSE, TRUE);
}
else
{
VisRgn = VIS_ComputeVisibleRegion(PsGetWin32Thread()->Desktop,
Window, FALSE, FALSE, FALSE);
VisBefore = VIS_ComputeVisibleRegion(PsGetWin32Thread()->Desktop,
Window, FALSE, FALSE, FALSE);
}
if (NULLREGION == UnsafeIntGetRgnBox(VisBefore, &TempRect))
{
NtGdiDeleteObject(VisBefore);
VisBefore = NULL;
}
NtGdiOffsetRgn(VisRgn, -Window->WindowRect.left, -Window->WindowRect.top);
}
WvrFlags = WinPosDoNCCALCSize(Window, &WinPos, &NewWindowRect,
@ -865,96 +665,167 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
{
Window->Style |= WS_VISIBLE;
FlagsEx |= SWP_EX_PAINTSELF;
/* Redraw entire window. */
VisRgn = (HRGN) 1;
}
else if (!(WinPos.flags & SWP_NOREDRAW))
else if (WinPos.flags & SWP_HIDEWINDOW)
{
if (WinPos.flags & SWP_HIDEWINDOW)
Window->Style &= ~WS_VISIBLE;
}
if (!(WinPos.flags & SWP_NOREDRAW))
{
/* Determine the new visible region */
if (Window->Style & WS_CLIPCHILDREN)
{
if (VisRgn > (HRGN)1)
VisAfter = VIS_ComputeVisibleRegion(PsGetWin32Thread()->Desktop,
Window, FALSE, FALSE, TRUE);
}
else
{
VisAfter = VIS_ComputeVisibleRegion(PsGetWin32Thread()->Desktop,
Window, FALSE, FALSE, FALSE);
}
if (NULLREGION == UnsafeIntGetRgnBox(VisAfter, &TempRect))
{
NtGdiDeleteObject(VisAfter);
VisAfter = NULL;
}
/* Determine which pixels can be copied from the old window position
to the new. Those pixels must be visible in both the old and new
position. */
if (NULL != VisBefore && NULL != VisAfter && ! (WinPos.flags & SWP_NOCOPYBITS))
{
CopyRgn = NtGdiCreateRectRgn(0, 0, 0, 0);
RgnType = NtGdiCombineRgn(CopyRgn, VisAfter, VisBefore, RGN_AND);
/* If this is (also) a window resize, the whole nonclient area
needs to be repainted. So we limit the copy to the client area,
'cause there is no use in copying it (would possibly cause
"flashing" too). However, if the copy region is already empty,
we don't have to crop (can't take anything away from an empty
region...) */
if (! (WinPos.flags & SWP_NOSIZE)
&& ERROR != RgnType && NULLREGION != RgnType)
{
NtGdiOffsetRgn(VisRgn, OldWindowRect.left, OldWindowRect.top);
RECT ORect = OldClientRect;
RECT NRect = NewClientRect;
NtGdiOffsetRect(&ORect, - OldWindowRect.left, - OldWindowRect.top);
NtGdiOffsetRect(&NRect, - NewWindowRect.left, - NewWindowRect.top);
NtGdiIntersectRect(&CopyRect, &ORect, &NRect);
REGION_CropRgn(CopyRgn, CopyRgn, &CopyRect, NULL);
}
else
/* No use in copying bits which are in the update region. */
if ((HRGN) 1 == Window->UpdateRegion)
{
VisRgn = 0;
/* The whole window is in the update region. No use
copying anything, so set the copy region empty */
NtGdiSetRectRgn(CopyRgn, 0, 0, 0, 0);
}
else if (1 < (DWORD) Window->UpdateRegion)
{
NtGdiCombineRgn(CopyRgn, CopyRgn, Window->UpdateRegion, RGN_DIFF);
}
/* Now, get the bounding box of the copy region. If it's empty
there's nothing to copy. Also, it's no use copying bits onto
themselves */
UnsafeIntGetRgnBox(CopyRgn, &CopyRect);
if (NtGdiIsEmptyRect(&CopyRect))
{
/* Nothing to copy, clean up */
NtGdiDeleteObject(CopyRgn);
CopyRgn = NULL;
}
else if (OldWindowRect.left != NewWindowRect.left
|| OldWindowRect.top != NewWindowRect.top)
{
/* Small trick here: there is no function to bitblt a region. So
we set the region as the clipping region, take the bounding box
of the region and bitblt that. Since nothing outside the clipping
region is copied, this has the effect of bitblt'ing the region.
Since NtUserGetDCEx takes ownership of the clip region, we need
to create a copy of CopyRgn and pass that. We need CopyRgn later */
HRGN ClipRgn = NtGdiCreateRectRgn(0, 0, 0, 0);
NtGdiCombineRgn(ClipRgn, CopyRgn, NULL, RGN_COPY);
Dc = NtUserGetDCEx(Wnd, ClipRgn, DCX_WINDOW | DCX_CACHE |
DCX_KEEPCLIPRGN | DCX_INTERSECTRGN | DCX_CLIPSIBLINGS );
NtGdiBitBlt(Dc, CopyRect.left, CopyRect.top, CopyRect.right - CopyRect.left,
CopyRect.bottom - CopyRect.top, Dc,
CopyRect.left + (OldWindowRect.left - NewWindowRect.left),
CopyRect.top + (OldWindowRect.top - NewWindowRect.top), SRCCOPY);
NtUserReleaseDC(Wnd, Dc);
}
}
else
{
if ((WinPos.flags & SWP_AGG_NOPOSCHANGE) != SWP_AGG_NOPOSCHANGE)
CopyRgn = NULL;
}
/* We need to redraw what wasn't visible before */
if (NULL != VisAfter)
{
if (NULL != CopyRgn)
{
if ((WinPos.flags & SWP_AGG_NOGEOMETRYCHANGE) == SWP_AGG_NOGEOMETRYCHANGE)
DirtyRgn = NtGdiCreateRectRgn(0, 0, 0, 0);
RgnType = NtGdiCombineRgn(DirtyRgn, VisAfter, CopyRgn, RGN_DIFF);
if (ERROR != RgnType && NULLREGION != RgnType)
{
FlagsEx |= SWP_EX_PAINTSELF;
PaintRedrawWindow(Window, NULL, DirtyRgn,
RDW_ERASE | RDW_FRAME | RDW_INVALIDATE |
RDW_ALLCHILDREN | RDW_ERASENOW,
RDW_EX_XYWINDOW | RDW_EX_USEHRGN);
}
FlagsEx = WinPosCopyValidBits(Window, &VisRgn, &OldWindowRect, &OldClientRect, FlagsEx);
NtGdiDeleteObject(DirtyRgn);
}
else
{
if (WinPos.flags & SWP_FRAMECHANGED)
{
WinPosDoSimpleFrameChanged(Window, &OldClientRect, WinPos.flags, FlagsEx);
}
if (VisRgn != 0)
{
NtGdiDeleteObject(VisRgn);
VisRgn = 0;
}
PaintRedrawWindow(Window, NULL, NULL,
RDW_ERASE | RDW_FRAME | RDW_INVALIDATE |
RDW_ALLCHILDREN | RDW_ERASENOW,
RDW_EX_XYWINDOW | RDW_EX_USEHRGN);
}
}
}
if (WinPos.flags & SWP_HIDEWINDOW)
{
VisibleRgn = VIS_ComputeVisibleRegion(PsGetWin32Thread()->Desktop, Window,
FALSE, FALSE, FALSE);
Window->Style &= ~WS_VISIBLE;
VIS_WindowLayoutChanged(PsGetWin32Thread()->Desktop, Window, VisibleRgn);
NtGdiDeleteObject(VisibleRgn);
if (NULL != CopyRgn)
{
NtGdiDeleteObject(CopyRgn);
}
}
if (! (WinPos.flags & SWP_NOMOVE))
/* Expose what was covered before but not covered anymore */
if (NULL != VisBefore)
{
VisibleRgn = UnsafeIntCreateRectRgnIndirect(&Window->WindowRect);
NtGdiCombineRgn(VisibleRgn, VisRgn, VisibleRgn, RGN_DIFF);
VIS_WindowLayoutChanged(PsGetWin32Thread()->Desktop, Window, VisibleRgn);
NtGdiDeleteObject(VisibleRgn);
ExposedRgn = NtGdiCreateRectRgn(0, 0, 0, 0);
NtGdiCombineRgn(ExposedRgn, VisBefore, NULL, RGN_COPY);
NtGdiOffsetRgn(ExposedRgn, OldWindowRect.left - NewWindowRect.left,
OldWindowRect.top - NewWindowRect.top);
if (NULL != VisAfter)
{
RgnType = NtGdiCombineRgn(ExposedRgn, ExposedRgn, VisAfter, RGN_DIFF);
}
else
{
RgnType = SIMPLEREGION;
}
if (ERROR != RgnType && NULLREGION != RgnType)
{
VIS_WindowLayoutChanged(PsGetWin32Thread()->Desktop, Window, ExposedRgn);
}
NtGdiDeleteObject(ExposedRgn);
NtGdiDeleteObject(VisBefore);
}
if (NULL != VisAfter)
{
NtGdiDeleteObject(VisAfter);
}
/* FIXME: Hide or show the claret */
if (VisRgn)
{
if (!(WinPos.flags & SWP_NOREDRAW))
{
if (FlagsEx & SWP_EX_PAINTSELF)
{
PaintRedrawWindow(Window, NULL,
(VisRgn == (HRGN) 1) ? 0 : VisRgn,
RDW_ERASE | RDW_FRAME | RDW_INVALIDATE |
RDW_ALLCHILDREN | RDW_ERASENOW,
RDW_EX_XYWINDOW | RDW_EX_USEHRGN);
}
#if 0
else
{
PaintRedrawWindow(Window->Parent, NULL,
(VisRgn == (HRGN) 1) ? 0 : VisRgn,
RDW_ERASE | RDW_INVALIDATE | RDW_ALLCHILDREN |
RDW_ERASENOW,
RDW_EX_USEHRGN);
}
#endif
/* FIXME: Redraw the window parent. */
}
if ((HRGN) 1 != VisRgn)
{
NtGdiDeleteObject(VisRgn);
}
}
if (!(flags & SWP_NOACTIVATE))
{
WinPosChangeActiveWindow(WinPos.hwnd, FALSE);

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: cliprgn.c,v 1.23 2003/08/31 07:56:24 gvg Exp $ */
/* $Id: cliprgn.c,v 1.24 2003/09/09 09:39:21 gvg Exp $ */
#undef WIN32_LEAN_AND_MEAN
#include <windows.h>
@ -69,6 +69,7 @@ CLIPPING_UpdateGCRegion(DC* Dc)
NtGdiCombineRgn(Combined, Dc->w.hClipRgn, Dc->w.hVisRgn,
RGN_AND);
}
NtGdiOffsetRgn(Combined, Dc->w.DCOrgX, Dc->w.DCOrgY);
CombinedRegion = RGNDATA_LockRgn(Combined);
ASSERT(NULL != CombinedRegion);
@ -161,10 +162,6 @@ int STDCALL NtGdiGetClipBox(HDC hDC,
if (!(dc = DC_LockDc(hDC)))
return ERROR;
retval = UnsafeIntGetRgnBox(dc->w.hGCClipRgn, rc);
rc->left -= dc->w.DCOrgX;
rc->right -= dc->w.DCOrgX;
rc->top -= dc->w.DCOrgY;
rc->bottom -= dc->w.DCOrgY;
DC_UnlockDc( hDC );
NtGdiDPtoLP(hDC, (LPPOINT)rc, 2);
@ -241,7 +238,6 @@ int STDCALL NtGdiSelectClipRgn(HDC hDC,
DC_UnlockDc(hDC);
return ERROR;
}
NtGdiOffsetRgn(Copy, dc->w.DCOrgX, dc->w.DCOrgY);
}
else
{

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: coord.c,v 1.18 2003/08/20 22:07:36 royce Exp $
/* $Id: coord.c,v 1.19 2003/09/09 09:39:21 gvg Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -229,7 +229,7 @@ NtGdiLPtoDP ( HDC hDC, LPPOINT UnsafePoints, INT Count )
MmCopyFromCaller( Points, UnsafePoints, Count*sizeof(POINT) );
IntLPtoDP ( dc, UnsafePoints, Count );
IntLPtoDP ( dc, Points, Count );
MmCopyToCaller ( UnsafePoints, Points, Count*sizeof(POINT) );

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: region.c,v 1.35 2003/08/20 07:45:02 gvg Exp $ */
/* $Id: region.c,v 1.36 2003/09/09 09:39:21 gvg Exp $ */
#undef WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <ddk/ntddk.h>
@ -139,6 +139,7 @@ static void FASTCALL REGION_SetExtents (ROSRGNDATA *pReg)
pReg->rdh.rcBound.top = 0;
pReg->rdh.rcBound.right = 0;
pReg->rdh.rcBound.bottom = 0;
pReg->rdh.iType = NULLREGION;
return;
}
@ -166,6 +167,7 @@ static void FASTCALL REGION_SetExtents (ROSRGNDATA *pReg)
pExtents->right = pRect->right;
pRect++;
}
pReg->rdh.iType = (1 == pReg->rdh.nCount ? SIMPLEREGION : COMPLEXREGION);
}
@ -1573,34 +1575,44 @@ NtGdiCreatePolyPolygonRgn(CONST PPOINT pt,
HRGN
STDCALL
NtGdiCreateRectRgn(INT LeftRect,
INT TopRect,
INT RightRect,
INT BottomRect)
NtGdiCreateRectRgn(INT LeftRect,
INT TopRect,
INT RightRect,
INT BottomRect)
{
HRGN hRgn;
PROSRGNDATA pRgnData;
PRECT pRect;
// Allocate region data structure with space for 1 RECT
if( ( hRgn = RGNDATA_AllocRgn(1) ) ){
if( ( pRgnData = RGNDATA_LockRgn( hRgn ) ) ){
pRect = (PRECT)pRgnData->Buffer;
ASSERT(pRect);
if (RightRect < LeftRect || BottomRect < TopRect)
{
DPRINT1("Invalid parameters (%d, %d) - (%d, %d)\n", LeftRect, TopRect, RightRect, BottomRect);
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return NULL;
}
// Fill in the region data header
pRgnData->rdh.iType = SIMPLEREGION;
NtGdiSetRect(&(pRgnData->rdh.rcBound), LeftRect, TopRect, RightRect, BottomRect);
/* Allocate region data structure with space for 1 RECT */
if ((hRgn = RGNDATA_AllocRgn(1)))
{
if ((pRgnData = RGNDATA_LockRgn(hRgn)))
{
pRect = (PRECT)pRgnData->Buffer;
ASSERT(pRect);
// use NtGdiCopyRect when implemented
NtGdiSetRect(pRect, LeftRect, TopRect, RightRect, BottomRect);
RGNDATA_UnlockRgn( hRgn );
/* Fill in the region data header */
pRgnData->rdh.iType = (LeftRect == RightRect || TopRect == BottomRect) ? NULLREGION : SIMPLEREGION;
NtGdiSetRect(&(pRgnData->rdh.rcBound), LeftRect, TopRect, RightRect, BottomRect);
return hRgn;
/* use NtGdiCopyRect when implemented */
NtGdiSetRect(pRect, LeftRect, TopRect, RightRect, BottomRect);
RGNDATA_UnlockRgn(hRgn);
return hRgn;
}
NtGdiDeleteObject( hRgn );
}
DPRINT("NtGdiCreateRectRgn: can't allocate region\n");
NtGdiDeleteObject( hRgn );
}
DPRINT1("NtGdiCreateRectRgn: can't allocate region\n");
return NULL;
}
@ -1764,25 +1776,21 @@ INT STDCALL
NtGdiGetRgnBox(HRGN hRgn,
LPRECT pRect)
{
PROSRGNDATA rgn = RGNDATA_LockRgn(hRgn);
RECT SafeRect;
DWORD ret;
if (rgn)
ret = UnsafeIntGetRgnBox(hRgn, &SafeRect);
if (ERROR == ret)
{
RECT SafeRect;
SafeRect.left = rgn->rdh.rcBound.left;
SafeRect.top = rgn->rdh.rcBound.top;
SafeRect.right = rgn->rdh.rcBound.right;
SafeRect.bottom = rgn->rdh.rcBound.bottom;
ret = rgn->rdh.iType;
RGNDATA_UnlockRgn( hRgn );
if(!NT_SUCCESS(MmCopyToCaller(pRect, &SafeRect, sizeof(RECT))))
return 0;
return ret;
}
return 0; //if invalid region return zero
if (!NT_SUCCESS(MmCopyToCaller(pRect, &SafeRect, sizeof(RECT))))
{
return ERROR;
}
return ret;
}
BOOL
@ -1917,20 +1925,14 @@ NtGdiPtInRegion(HRGN hRgn,
}
BOOL
STDCALL
NtGdiRectInRegion(HRGN hRgn,
CONST LPRECT unsaferc)
FASTCALL
UnsafeIntRectInRegion(HRGN hRgn,
CONST LPRECT rc)
{
PROSRGNDATA rgn;
PRECT pCurRect, pRectEnd;
PRECT rc;
BOOL bRet = FALSE;
if( !NT_SUCCESS( MmCopyFromCaller( rc, unsaferc, sizeof( RECT ) ) ) ){
DPRINT("NtGdiRectInRegion: bogus rc\n");
return ERROR;
}
if( !( rgn = RGNDATA_LockRgn(hRgn) ) )
return ERROR;
@ -1951,6 +1953,22 @@ NtGdiRectInRegion(HRGN hRgn,
return bRet;
}
BOOL
STDCALL
NtGdiRectInRegion(HRGN hRgn,
CONST LPRECT unsaferc)
{
RECT rc;
if (!NT_SUCCESS(MmCopyFromCaller(&rc, unsaferc, sizeof(RECT))))
{
DPRINT1("NtGdiRectInRegion: bogus rc\n");
return ERROR;
}
return UnsafeIntRectInRegion(hRgn, &rc);
}
BOOL
STDCALL
NtGdiSetRectRgn(HRGN hRgn,