Fixes to UpdateRegion code, implement GetUpdateRgn() and ValidateRgn()

svn path=/trunk/; revision=4764
This commit is contained in:
Gé van Geldorp 2003-05-26 18:52:37 +00:00
parent bae47d7a0f
commit 3c0df75f7c
7 changed files with 340 additions and 178 deletions

View file

@ -149,12 +149,17 @@ NtUserCallOneParam(
DWORD Unknown0, DWORD Unknown0,
DWORD Unknown1); DWORD Unknown1);
#define TWOPARAM_ROUTINE_ENABLEWINDOW 0x53
#define TWOPARAM_ROUTINE_UNKNOWN 0x54
#define TWOPARAM_ROUTINE_SHOWOWNEDPOPUPS 0x55
#define TWOPARAM_ROUTINE_SWITCHTOTHISWINDOW 0x56
#define TWOPARAM_ROUTINE_VALIDATERGN 0x57
DWORD DWORD
STDCALL STDCALL
NtUserCallTwoParam( NtUserCallTwoParam(
DWORD Unknown0, DWORD Param1,
DWORD Unknown1, DWORD Param2,
DWORD Unknown2); DWORD Routine);
DWORD DWORD
STDCALL STDCALL
@ -808,12 +813,12 @@ NtUserGetUpdateRect(
DWORD Unknown1, DWORD Unknown1,
DWORD Unknown2); DWORD Unknown2);
DWORD int
STDCALL STDCALL
NtUserGetUpdateRgn( NtUserGetUpdateRgn(
DWORD Unknown0, HWND hWnd,
DWORD Unknown1, HRGN hRgn,
DWORD Unknown2); WINBOOL bErase);
DWORD DWORD
STDCALL STDCALL

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: paint.c,v 1.13 2003/05/12 19:30:00 jfilby Exp $ /* $Id: paint.c,v 1.14 2003/05/26 18:52:37 gvg Exp $
* *
* PROJECT: ReactOS user32.dll * PROJECT: ReactOS user32.dll
* FILE: lib/user32/windows/input.c * FILE: lib/user32/windows/input.c
@ -78,8 +78,7 @@ GetUpdateRgn(
HRGN hRgn, HRGN hRgn,
WINBOOL bErase) WINBOOL bErase)
{ {
UNIMPLEMENTED; return NtUserGetUpdateRgn(hWnd, hRgn, bErase);
return 0;
} }
WINBOOL WINBOOL
@ -170,8 +169,9 @@ ValidateRgn(
HWND hWnd, HWND hWnd,
HRGN hRgn) HRGN hRgn)
{ {
UNIMPLEMENTED; return (WINBOOL) NtUserCallTwoParam((DWORD) hWnd,
return FALSE; (DWORD) hRgn,
TWOPARAM_ROUTINE_VALIDATERGN);
} }
int int

View file

@ -22,4 +22,6 @@ BOOL STDCALL
PaintHaveToDelayNCPaint(PWINDOW_OBJECT Window, ULONG Flags); PaintHaveToDelayNCPaint(PWINDOW_OBJECT Window, ULONG Flags);
HRGN STDCALL HRGN STDCALL
PaintUpdateNCRegion(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags); PaintUpdateNCRegion(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags);
BOOL STDCALL
NtUserValidateRgn(HWND hWnd, HRGN hRgn);
#endif /* __WIN32K_PAINTING_H */ #endif /* __WIN32K_PAINTING_H */

View file

@ -1,4 +1,4 @@
# $Id: makefile,v 1.62 2003/05/18 17:16:17 ea Exp $ # $Id: makefile,v 1.63 2003/05/26 18:52:37 gvg Exp $
PATH_TO_TOP = ../.. PATH_TO_TOP = ../..
@ -50,7 +50,7 @@ NTUSER_OBJECTS = ntuser/class.o ntuser/guicheck.o ntuser/hook.o \
ntuser/input.o ntuser/keyboard.o ntuser/callback.o \ ntuser/input.o ntuser/keyboard.o ntuser/callback.o \
ntuser/winpos.o ntuser/painting.o ntuser/metric.o \ ntuser/winpos.o ntuser/painting.o ntuser/metric.o \
ntuser/windc.o ntuser/prop.o ntuser/scrollbar.o \ ntuser/windc.o ntuser/prop.o ntuser/scrollbar.o \
ntuser/timer.o ntuser/timer.o ntuser/misc.o
OBJECTS_OBJECTS = objects/bitmaps.o objects/brush.o objects/cliprgn.o \ OBJECTS_OBJECTS = objects/bitmaps.o objects/brush.o objects/cliprgn.o \
objects/color.o objects/coord.o objects/dc.o \ objects/color.o objects/coord.o objects/dc.o \

View file

@ -0,0 +1,60 @@
/* $Id: misc.c,v 1.1 2003/05/26 18:52:37 gvg Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PURPOSE: Misc User funcs
* FILE: subsys/win32k/ntuser/misc.c
* PROGRAMER: Ge van Geldorp (ge@gse.nl)
* REVISION HISTORY:
* 2003/05/22 Created
*/
#include <ddk/ntddk.h>
#include <win32k/win32k.h>
#include <include/error.h>
#include <include/window.h>
#include <include/painting.h>
#define NDEBUG
#include <debug.h>
DWORD
STDCALL
NtUserCallTwoParam(
DWORD Param1,
DWORD Param2,
DWORD Routine)
{
DWORD Result;
switch(Routine)
{
case TWOPARAM_ROUTINE_ENABLEWINDOW:
UNIMPLEMENTED
break;
case TWOPARAM_ROUTINE_UNKNOWN:
UNIMPLEMENTED
break;
case TWOPARAM_ROUTINE_SHOWOWNEDPOPUPS:
UNIMPLEMENTED
break;
case TWOPARAM_ROUTINE_SWITCHTOTHISWINDOW:
UNIMPLEMENTED
break;
case TWOPARAM_ROUTINE_VALIDATERGN:
Result = (DWORD) NtUserValidateRgn((HWND) Param1, (HRGN) Param2);
break;
default:
DPRINT1("Calling invalid routine number 0x%x in NtUserCallTwoParam\n");
SetLastWin32Error(ERROR_INVALID_PARAMETER);
Result = 0;
break;
}
return Result;
}

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: painting.c,v 1.14 2003/05/18 22:07:02 gvg Exp $ /* $Id: painting.c,v 1.15 2003/05/26 18:52:37 gvg Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -56,6 +56,13 @@
#define UNC_ENTIRE (0x00000010) #define UNC_ENTIRE (0x00000010)
#define UNC_UPDATE (0x00000020) #define UNC_UPDATE (0x00000020)
/* client rect in window coordinates */
#define GETCLIENTRECTW(wnd, r) (r).left = (wnd)->ClientRect.left - (wnd)->WindowRect.left; \
(r).top = (wnd)->ClientRect.top - (wnd)->WindowRect.top; \
(r).right = (wnd)->ClientRect.right - (wnd)->WindowRect.left; \
(r).bottom = (wnd)->ClientRect.bottom - (wnd)->WindowRect.top
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
HRGN STATIC STDCALL HRGN STATIC STDCALL
@ -63,10 +70,10 @@ PaintDoPaint(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags, ULONG ExFlags)
{ {
HDC hDC; HDC hDC;
HWND hWnd = Window->Self; HWND hWnd = Window->Self;
BOOL bIcon = (Window->Style & WS_MINIMIZE) && BOOL bIcon = (0 != (Window->Style & WS_MINIMIZE)) &&
NtUserGetClassLong(hWnd, GCL_HICON); (0 != NtUserGetClassLong(hWnd, GCL_HICON));
if (ExFlags & RDW_EX_DELAY_NCPAINT || if (0 != (ExFlags & RDW_EX_DELAY_NCPAINT) ||
PaintHaveToDelayNCPaint(Window, 0)) PaintHaveToDelayNCPaint(Window, 0))
{ {
ExFlags |= RDW_EX_DELAY_NCPAINT; ExFlags |= RDW_EX_DELAY_NCPAINT;
@ -74,7 +81,7 @@ PaintDoPaint(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags, ULONG ExFlags)
if (Flags & RDW_UPDATENOW) if (Flags & RDW_UPDATENOW)
{ {
if (Window->UpdateRegion != NULL) if (NULL != Window->UpdateRegion)
{ {
NtUserSendMessage(hWnd, bIcon ? WM_PAINTICON : WM_PAINT, bIcon, 0); NtUserSendMessage(hWnd, bIcon ? WM_PAINTICON : WM_PAINT, bIcon, 0);
} }
@ -92,9 +99,9 @@ PaintDoPaint(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags, ULONG ExFlags)
((ExFlags & RDW_EX_TOPFRAME) ? UNC_ENTIRE : 0) | ((ExFlags & RDW_EX_TOPFRAME) ? UNC_ENTIRE : 0) |
((ExFlags & RDW_EX_DELAY_NCPAINT) ? ((ExFlags & RDW_EX_DELAY_NCPAINT) ?
UNC_DELAY_NCPAINT : 0)); UNC_DELAY_NCPAINT : 0));
if (hRgnRet != NULL) if (NULL != hRgnRet)
{ {
if (hRgnRet != (HRGN)1) if ((HRGN) 1 < hRgnRet)
{ {
hRgn = hRgnRet; hRgn = hRgnRet;
} }
@ -102,13 +109,13 @@ PaintDoPaint(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags, ULONG ExFlags)
{ {
hRgnRet = NULL; hRgnRet = NULL;
} }
if (Window->Flags & WINDOWOBJECT_NEED_ERASEBACKGRD) if (0 != (Window->Flags & WINDOWOBJECT_NEED_ERASEBACKGRD))
{ {
if (bIcon) if (bIcon)
{ {
Dcx |= DCX_WINDOW; Dcx |= DCX_WINDOW;
} }
if (hRgnRet) if (NULL != hRgnRet)
{ {
W32kOffsetRgn(hRgnRet, W32kOffsetRgn(hRgnRet,
Window->WindowRect.left - Window->WindowRect.left -
@ -120,12 +127,13 @@ PaintDoPaint(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags, ULONG ExFlags)
{ {
Dcx &= ~DCX_INTERSECTRGN; Dcx &= ~DCX_INTERSECTRGN;
} }
if ((hDC = NtUserGetDCEx(hWnd, hRgnRet, Dcx)) != NULL) if (NULL != (hDC = NtUserGetDCEx(hWnd, hRgnRet, Dcx)))
{ {
LRESULT Result; if (0 != NtUserSendMessage(hWnd, bIcon ? WM_ICONERASEBKGND :
Result = NtUserSendMessage(hWnd, bIcon ? WM_ICONERASEBKGND : WM_ERASEBKGND, (WPARAM)hDC, 0))
WM_ERASEBKGND, (WPARAM)hDC, 0); {
Window->Flags &= ~WINDOWOBJECT_NEED_ERASEBACKGRD; Window->Flags &= ~WINDOWOBJECT_NEED_ERASEBACKGRD;
}
NtUserReleaseDC(hWnd, hDC); NtUserReleaseDC(hWnd, hDC);
} }
} }
@ -172,7 +180,7 @@ PaintValidateParent(PWINDOW_OBJECT Child)
PWINDOW_OBJECT Desktop = W32kGetWindowObject(DesktopHandle); PWINDOW_OBJECT Desktop = W32kGetWindowObject(DesktopHandle);
HRGN hRgn; HRGN hRgn;
if (Child->UpdateRegion == (HANDLE)1) if ((HRGN) 1 == Child->UpdateRegion)
{ {
RECT Rect; RECT Rect;
@ -187,15 +195,15 @@ PaintValidateParent(PWINDOW_OBJECT Child)
hRgn = Child->UpdateRegion; hRgn = Child->UpdateRegion;
} }
while (Parent != NULL && Parent != Desktop) while (NULL != Parent && Parent != Desktop)
{ {
if (!(Parent->Style & WS_CLIPCHILDREN)) if (0 == (Parent->Style & WS_CLIPCHILDREN))
{ {
if (Parent->UpdateRegion != (HANDLE)0) if (NULL != Parent->UpdateRegion)
{ {
POINT Offset; POINT Offset;
if (Parent->UpdateRegion == (HANDLE)1) if ((HRGN) 1 == Parent->UpdateRegion)
{ {
RECT Rect1; RECT Rect1;
@ -229,7 +237,12 @@ VOID STATIC STDCALL
PaintUpdateRgns(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags, PaintUpdateRgns(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags,
BOOL First) BOOL First)
{ {
BOOL HadOne = Window->UpdateRegion != NULL && hRgn; /*
* Called only when one of the following is set:
* (RDW_INVALIDATE | RDW_VALIDATE | RDW_INTERNALPAINT | RDW_NOINTERNALPAINT)
*/
BOOL HadOne = NULL != Window->UpdateRegion && NULL != hRgn;
BOOL HasChildren = !IsListEmpty(&Window->ChildrenListHead) && BOOL HasChildren = !IsListEmpty(&Window->ChildrenListHead) &&
!(Flags & RDW_NOCHILDREN) && !(Window->Style & WS_MINIMIZE) && !(Flags & RDW_NOCHILDREN) && !(Window->Style & WS_MINIMIZE) &&
((Flags & RDW_ALLCHILDREN) || !(Window->Style & WS_CLIPCHILDREN)); ((Flags & RDW_ALLCHILDREN) || !(Window->Style & WS_CLIPCHILDREN));
@ -241,34 +254,21 @@ PaintUpdateRgns(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags,
if (Flags & RDW_INVALIDATE) if (Flags & RDW_INVALIDATE)
{ {
if (hRgn > (HANDLE)1) if ((HRGN) 1 < hRgn)
{ {
if (Window->UpdateRegion > (HANDLE)1) if ((HRGN) 1 != Window->UpdateRegion)
{ {
W32kCombineRgn(Window->UpdateRegion, Window->UpdateRegion, if ((HRGN) 1 < Window->UpdateRegion)
hRgn, RGN_OR); {
W32kCombineRgn(Window->UpdateRegion, Window->UpdateRegion,
hRgn, RGN_OR);
}
Window->UpdateRegion = Window->UpdateRegion =
REGION_CropRgn(Window->UpdateRegion, REGION_CropRgn(Window->UpdateRegion,
Window->UpdateRegion, &Rect, NULL); Window->UpdateRegion, &Rect, NULL);
if (!HadOne) if (! HadOne)
{ {
W32kGetRgnBox(Window->UpdateRegion, &Rect); UnsafeW32kGetRgnBox(Window->UpdateRegion, &Rect);
if (W32kIsEmptyRect(&Rect))
{
W32kDeleteObject(Window->UpdateRegion);
Window->UpdateRegion = NULL;
PaintUpdateInternalPaint(Window, Flags);
return;
}
}
}
else if (Window->UpdateRegion == 0)
{
Window->UpdateRegion =
REGION_CropRgn(Window->UpdateRegion, hRgn, &Rect, NULL);
if (!HadOne)
{
W32kGetRgnBox(Window->UpdateRegion, &Rect);
if (W32kIsEmptyRect(&Rect)) if (W32kIsEmptyRect(&Rect))
{ {
W32kDeleteObject(Window->UpdateRegion); W32kDeleteObject(Window->UpdateRegion);
@ -279,20 +279,20 @@ PaintUpdateRgns(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags,
} }
} }
} }
else if (hRgn == (HANDLE)1) else if ((HRGN) 1 == hRgn)
{ {
if (Window->UpdateRegion > (HANDLE)1) if ((HRGN) 1 < Window->UpdateRegion)
{ {
W32kDeleteObject(Window->UpdateRegion); W32kDeleteObject(Window->UpdateRegion);
} }
Window->UpdateRegion = (HANDLE)1; Window->UpdateRegion = (HRGN) 1;
} }
else else
{ {
hRgn = Window->UpdateRegion; hRgn = Window->UpdateRegion; /* this is a trick that depends on code in PaintRedrawWindow() */
} }
if (!HadOne && !(Window->Flags & WINDOWOBJECT_NEED_INTERNALPAINT)) if (! HadOne && 0 == (Window->Flags & WINDOWOBJECT_NEED_INTERNALPAINT))
{ {
MsqIncPaintCountQueue(Window->MessageQueue); MsqIncPaintCountQueue(Window->MessageQueue);
} }
@ -309,12 +309,24 @@ PaintUpdateRgns(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags,
} }
else if (Flags & RDW_VALIDATE) else if (Flags & RDW_VALIDATE)
{ {
if (Window->UpdateRegion != NULL) if (NULL != Window->UpdateRegion)
{ {
if (hRgn > (HANDLE)1) if ((HRGN) 1 < hRgn)
{ {
if (Window->UpdateRegion == (HANDLE)1) if ((HRGN) 1 == Window->UpdateRegion)
{ {
#if 0
/* If no NCPAINT needed or if we're going to turn it off
the special value 1 means the whole client rect */
if (0 == (Window->Flags & WINDOWOBJECT_NEED_NCPAINT) ||
0 != (Flags & RDW_NOFRAME))
{
Rect.left = Window->ClientRect.left - Window->WindowRect.left;
Rect.top = Window->ClientRect.top - Window->WindowRect.top;
Rect.right = Window->ClientRect.right - Window->WindowRect.left;
Rect.bottom = Window->ClientRect.bottom - Window->WindowRect.top;
}
#endif
Window->UpdateRegion = Window->UpdateRegion =
UnsafeW32kCreateRectRgnIndirect(&Rect); UnsafeW32kCreateRectRgnIndirect(&Rect);
} }
@ -322,28 +334,25 @@ PaintUpdateRgns(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags,
Window->UpdateRegion, hRgn, Window->UpdateRegion, hRgn,
RGN_DIFF) == NULLREGION) RGN_DIFF) == NULLREGION)
{ {
if (Window->UpdateRegion > (HANDLE)1) W32kDeleteObject(Window->UpdateRegion);
{
W32kDeleteObject(Window->UpdateRegion);
}
Window->UpdateRegion = NULL; Window->UpdateRegion = NULL;
} }
} }
else else /* validate everything */
{ {
if (Window->UpdateRegion > (HANDLE)1) if ((HRGN) 1 < Window->UpdateRegion)
{ {
W32kDeleteObject(Window->UpdateRegion); W32kDeleteObject(Window->UpdateRegion);
} }
Window->UpdateRegion = NULL; Window->UpdateRegion = NULL;
} }
if (Window->UpdateRegion == NULL) if (NULL != Window->UpdateRegion)
{ {
Window->Flags &= ~WINDOWOBJECT_NEED_ERASEBACKGRD; Window->Flags &= ~WINDOWOBJECT_NEED_ERASEBACKGRD;
if (!(Window->Flags & WINDOWOBJECT_NEED_INTERNALPAINT)) if (0 != (Window->Flags & WINDOWOBJECT_NEED_INTERNALPAINT))
{ {
MsqIncPaintCountQueue(Window->MessageQueue); MsqDecPaintCountQueue(Window->MessageQueue);
} }
} }
} }
@ -358,14 +367,17 @@ PaintUpdateRgns(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags,
} }
} }
if (First && Window->UpdateRegion != NULL && (Flags & RDW_UPDATENOW)) if (First && NULL != Window->UpdateRegion && 0 != (Flags & RDW_UPDATENOW))
{ {
PaintValidateParent(Window); PaintValidateParent(Window); /* validate parent covered by region */
} }
if (Flags & (RDW_INVALIDATE | RDW_VALIDATE)) /* in/validate child windows that intersect with the region if it
* is a valid handle. */
if (0 != (Flags & (RDW_INVALIDATE | RDW_VALIDATE)))
{ {
if (hRgn > (HANDLE)1 && HasChildren) if ((HRGN) 1 < hRgn && HasChildren)
{ {
POINT Total = {0, 0}; POINT Total = {0, 0};
POINT PrevOrign = {0, 0}; POINT PrevOrign = {0, 0};
@ -381,7 +393,7 @@ PaintUpdateRgns(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags,
{ {
Child = CONTAINING_RECORD(ChildListEntry, WINDOW_OBJECT, Child = CONTAINING_RECORD(ChildListEntry, WINDOW_OBJECT,
SiblingListEntry); SiblingListEntry);
if (Child->Style & WS_VISIBLE) if (0 != (Child->Style & WS_VISIBLE))
{ {
POINT Offset; POINT Offset;
@ -437,17 +449,18 @@ PaintRedrawWindow(HWND hWnd, const RECT* UpdateRect, HRGN UpdateRgn,
PWINDOW_OBJECT Window; PWINDOW_OBJECT Window;
RECT Rect, Rect2; RECT Rect, Rect2;
POINT Pt; POINT Pt;
HRGN hRgn; HRGN hRgn = NULL;
/* FIXME: Return if this is for a desktop. */ /* FIXME: Return if this is for a desktop. */
Window = W32kGetWindowObject(hWnd); Window = W32kGetWindowObject(hWnd);
if (Window == NULL) if (Window == NULL)
{ {
return(FALSE); return FALSE;
} }
if (Flags & RDW_FRAME) if ((RDW_INVALIDATE | RDW_FRAME) == (Flags & (RDW_INVALIDATE | RDW_FRAME)) ||
(RDW_VALIDATE | RDW_NOFRAME) == (Flags & (RDW_VALIDATE | RDW_NOFRAME)))
{ {
Rect = Window->WindowRect; Rect = Window->WindowRect;
} }
@ -465,34 +478,34 @@ PaintRedrawWindow(HWND hWnd, const RECT* UpdateRect, HRGN UpdateRgn,
{ {
Pt.x = Window->ClientRect.left - Window->WindowRect.left; Pt.x = Window->ClientRect.left - Window->WindowRect.left;
Pt.y = Window->ClientRect.top - Window->WindowRect.top; Pt.y = Window->ClientRect.top - Window->WindowRect.top;
W32kOffsetRect(&Rect, -Window->ClientRect.left, -Window->WindowRect.top); W32kOffsetRect(&Rect, -Window->ClientRect.left, -Window->ClientRect.top);
} }
if (Flags & RDW_INVALIDATE) if (0 != (Flags & RDW_INVALIDATE)) /* ------------------------- Invalidate */
{ {
if (UpdateRgn != NULL) if (NULL != UpdateRgn)
{ {
if (Window->UpdateRegion != NULL) if (NULL != Window->UpdateRegion)
{ {
hRgn = REGION_CropRgn(0, UpdateRgn, NULL, &Pt); hRgn = REGION_CropRgn(NULL, UpdateRgn, NULL, &Pt);
} }
else else
{ {
Window->UpdateRegion = REGION_CropRgn(0, UpdateRgn, &Rect, &Pt); Window->UpdateRegion = REGION_CropRgn(NULL, UpdateRgn, &Rect, &Pt);
} }
} }
else if (UpdateRect != NULL) else if (NULL != UpdateRect)
{ {
if (!W32kIntersectRect(&Rect2, &Rect, UpdateRect)) if (! W32kIntersectRect(&Rect2, &Rect, UpdateRect))
{ {
W32kReleaseWindowObject(Window); W32kReleaseWindowObject(Window);
if (hRgn != NULL && hRgn != (HRGN)1) if ((HRGN) 1 < hRgn && hRgn != UpdateRgn)
{ {
W32kDeleteObject(hRgn); W32kDeleteObject(hRgn);
} }
return(TRUE); return TRUE;
} }
if (Window->UpdateRegion == NULL) if (NULL == Window->UpdateRegion)
{ {
Window->UpdateRegion = Window->UpdateRegion =
UnsafeW32kCreateRectRgnIndirect(&Rect2); UnsafeW32kCreateRectRgnIndirect(&Rect2);
@ -502,34 +515,92 @@ PaintRedrawWindow(HWND hWnd, const RECT* UpdateRect, HRGN UpdateRgn,
hRgn = UnsafeW32kCreateRectRgnIndirect(&Rect2); hRgn = UnsafeW32kCreateRectRgnIndirect(&Rect2);
} }
} }
else else /* entire window or client depending on RDW_FRAME */
{ {
if (Flags & RDW_FRAME) if (Flags & RDW_FRAME)
{ {
hRgn = (HRGN)1; if (NULL != Window->UpdateRegion)
{
hRgn = (HRGN) 1;
}
else
{
Window->UpdateRegion = (HRGN) 1;
}
} }
else else
{ {
W32kGetClientRect(Window, &Rect2); GETCLIENTRECTW(Window, Rect2);
hRgn = UnsafeW32kCreateRectRgnIndirect(&Rect2); if (NULL == Window->UpdateRegion)
{
Window->UpdateRegion = UnsafeW32kCreateRectRgnIndirect(&Rect2);
}
else
{
hRgn = UnsafeW32kCreateRectRgnIndirect(&Rect2);
}
} }
} }
} }
else if (Flags & RDW_VALIDATE) else if (Flags & RDW_VALIDATE)
{ {
/* FIXME: Implement this. */ /* In this we cannot leave with zero hRgn */
if (NULL != UpdateRgn)
{
hRgn = REGION_CropRgn(hRgn, UpdateRgn, &Rect, &Pt);
UnsafeW32kGetRgnBox(hRgn, &Rect2);
if (W32kIsEmptyRect(&Rect2))
{
W32kReleaseWindowObject(Window);
if ((HRGN) 1 < hRgn && hRgn != UpdateRgn)
{
W32kDeleteObject(hRgn);
}
return TRUE;
}
}
else if (NULL != UpdateRect)
{
if (! W32kIntersectRect(&Rect2, &Rect, UpdateRect))
{
W32kReleaseWindowObject(Window);
if ((HRGN) 1 < hRgn && hRgn != UpdateRgn)
{
W32kDeleteObject(hRgn);
}
return TRUE;
}
W32kOffsetRect(&Rect2, Pt.x, Pt.y);
hRgn = UnsafeW32kCreateRectRgnIndirect(&Rect2);
}
else /* entire window or client depending on RDW_NOFRAME */
{
if (0 != (Flags & RDW_NOFRAME))
{
hRgn = (HRGN) 1;
}
else
{
GETCLIENTRECTW(Window, Rect2);
hRgn = UnsafeW32kCreateRectRgnIndirect(&Rect2);
}
}
} }
/* At this point hRgn is either an update region in window coordinates or 1 or 0 */
PaintUpdateRgns(Window, hRgn, Flags, TRUE); PaintUpdateRgns(Window, hRgn, Flags, TRUE);
hRgn = PaintDoPaint(Window, hRgn == (HANDLE)1 ? 0 : hRgn, Flags, ExFlags); /* Erase/update windows, from now on hRgn is a scratch region */
if (hRgn != (HANDLE)1 && hRgn != UpdateRgn) hRgn = PaintDoPaint(Window, (HRGN) 1 == hRgn ? NULL : hRgn, Flags, ExFlags);
if ((HRGN) 1 < hRgn && hRgn != UpdateRgn)
{ {
W32kDeleteObject(hRgn); W32kDeleteObject(hRgn);
} }
W32kReleaseWindowObject(Window); W32kReleaseWindowObject(Window);
return(TRUE); return TRUE;
} }
BOOL STDCALL BOOL STDCALL
@ -550,11 +621,12 @@ PaintHaveToDelayNCPaint(PWINDOW_OBJECT Window, ULONG Flags)
{ {
if (Window->Style & WS_CLIPCHILDREN && Window->UpdateRegion != NULL) if (Window->Style & WS_CLIPCHILDREN && Window->UpdateRegion != NULL)
{ {
return(TRUE); return TRUE;
} }
Window = Window->Parent; Window = Window->Parent;
} }
return(FALSE);
return FALSE;
} }
HWND STDCALL HWND STDCALL
@ -633,7 +705,7 @@ PaintUpdateNCRegion(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags)
if (Window->Parent == NULL) if (Window->Parent == NULL)
{ {
Window->Flags &= ~WINDOWOBJECT_NEED_NCPAINT; Window->Flags &= ~WINDOWOBJECT_NEED_NCPAINT;
if (Window->UpdateRegion > (HANDLE)1) if ((HRGN) 1 < Window->UpdateRegion)
{ {
hRgnRet = REGION_CropRgn(hRgn, Window->UpdateRegion, NULL, NULL); hRgnRet = REGION_CropRgn(hRgn, Window->UpdateRegion, NULL, NULL);
} }
@ -644,18 +716,30 @@ PaintUpdateNCRegion(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags)
return(hRgnRet); return(hRgnRet);
} }
if (Window->Flags & WINDOWOBJECT_NEED_NCPAINT && #if 0 /* NtUserGetFOregroundWindow() not implemented yet */
!PaintHaveToDelayNCPaint(Window, Flags)) if ((Window->Self == NtUserGetForegroundWindow()) &&
0 == (Window->Flags & WIN_NCACTIVATED) )
{
Window->Flags |= WIN_NCACTIVATED;
Flags |= UNC_ENTIRE;
}
#endif
/*
* If the window's non-client area needs to be painted,
*/
if (0 != (Window->Flags & WINDOWOBJECT_NEED_NCPAINT) &&
! PaintHaveToDelayNCPaint(Window, Flags))
{ {
RECT UpdateRegionBox; RECT UpdateRegionBox;
RECT Rect; RECT Rect;
Window->Flags &= ~WINDOWOBJECT_NEED_NCPAINT; Window->Flags &= ~WINDOWOBJECT_NEED_NCPAINT;
W32kGetClientRect(Window, &ClientRect); GETCLIENTRECTW(Window, ClientRect);
if (Window->UpdateRegion > (HRGN)1) if ((HRGN) 1 < Window->UpdateRegion)
{ {
W32kGetRgnBox(Window->UpdateRegion, &UpdateRegionBox); UnsafeW32kGetRgnBox(Window->UpdateRegion, &UpdateRegionBox);
W32kUnionRect(&Rect, &ClientRect, &UpdateRegionBox); W32kUnionRect(&Rect, &ClientRect, &UpdateRegionBox);
if (Rect.left != ClientRect.left || Rect.top != ClientRect.top || if (Rect.left != ClientRect.left || Rect.top != ClientRect.top ||
Rect.right != ClientRect.right || Rect.right != ClientRect.right) Rect.right != ClientRect.right || Rect.right != ClientRect.right)
@ -671,82 +755,89 @@ PaintUpdateNCRegion(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags)
if (Flags & UNC_CHECK) if (Flags & UNC_CHECK)
{ {
W32kGetRgnBox(Window->UpdateRegion, &UpdateRegionBox); UnsafeW32kGetRgnBox(Window->UpdateRegion, &UpdateRegionBox);
if (W32kIsEmptyRect(&UpdateRegionBox)) if (W32kIsEmptyRect(&UpdateRegionBox))
{ {
W32kDeleteObject(Window->UpdateRegion); W32kDeleteObject(Window->UpdateRegion);
Window->UpdateRegion = NULL; Window->UpdateRegion = NULL;
MsqDecPaintCountQueue(Window->MessageQueue); if (0 == (Window->Flags & WINDOWOBJECT_NEED_INTERNALPAINT))
{
MsqDecPaintCountQueue(Window->MessageQueue);
}
Window->Flags &= ~WINDOWOBJECT_NEED_ERASEBACKGRD; Window->Flags &= ~WINDOWOBJECT_NEED_ERASEBACKGRD;
} }
} }
if (!hClip && Window->UpdateRegion && Flags & UNC_REGION) if (0 == hClip && 0 != Window->UpdateRegion)
{ {
hRgnRet = REGION_CropRgn(hRgn, Window->UpdateRegion, NULL, goto copyrgn;
NULL);
} }
} }
else if (Window->UpdateRegion == (HRGN)1) else if ((HRGN) 1 == Window->UpdateRegion)
{ {
if (Flags & UNC_UPDATE) if (0 != (Flags & UNC_UPDATE))
{ {
Window->UpdateRegion = Window->UpdateRegion =
UnsafeW32kCreateRectRgnIndirect(&ClientRect); UnsafeW32kCreateRectRgnIndirect(&ClientRect);
} }
if (Flags & UNC_REGION) if (Flags & UNC_REGION)
{ {
hRgnRet = (HANDLE)1; hRgnRet = (HRGN) 1;
} }
Flags |= UNC_ENTIRE; Flags |= UNC_ENTIRE;
} }
} }
else else /* no WM_NCPAINT unless forced */
{ {
if (Window->UpdateRegion > (HANDLE)1 && Flags & UNC_REGION) if ((HRGN) 1 < Window->UpdateRegion)
{ {
hRgnRet = REGION_CropRgn(hRgn, Window->UpdateRegion, NULL, NULL); copyrgn:
if (0 != (Flags & UNC_REGION))
{
hRgnRet = REGION_CropRgn(hRgn, Window->UpdateRegion, NULL, NULL);
}
} }
else if (Window->UpdateRegion == (HANDLE)1 && Flags & UNC_UPDATE) else if ((HRGN) 1 == Window->UpdateRegion && 0 != (Flags & UNC_UPDATE))
{ {
W32kGetClientRect(Window, &ClientRect); GETCLIENTRECTW(Window, ClientRect);
Window->UpdateRegion = Window->UpdateRegion =
UnsafeW32kCreateRectRgnIndirect(&ClientRect); UnsafeW32kCreateRectRgnIndirect(&ClientRect);
if (Flags & UNC_REGION) if (Flags & UNC_REGION)
{ {
hRgnRet = (HANDLE)1; hRgnRet = (HRGN) 1;
} }
} }
} }
if (hClip == NULL && Flags & UNC_ENTIRE) if (NULL == hClip && 0 != (Flags & UNC_ENTIRE))
{ {
if (RtlCompareMemory(&Window->WindowRect, &Window->ClientRect, if (RtlCompareMemory(&Window->WindowRect, &Window->ClientRect,
sizeof(RECT)) != sizeof(RECT)) sizeof(RECT)) != sizeof(RECT))
{ {
hClip = (HANDLE)1; hClip = (HRGN) 1;
} }
else else
{ {
hClip = 0; hClip = NULL;
} }
} }
if (hClip != 0) if (NULL != hClip) /* NOTE: WM_NCPAINT allows wParam to be 1 */
{ {
if (hClip == hRgnRet && hRgnRet > (HANDLE)1) if (hClip == hRgnRet && (HRGN) 1 < hRgnRet)
{ {
hClip = W32kCreateRectRgn(0, 0, 0, 0); hClip = W32kCreateRectRgn(0, 0, 0, 0);
W32kCombineRgn(hClip, hRgnRet, 0, RGN_COPY); W32kCombineRgn(hClip, hRgnRet, 0, RGN_COPY);
} }
NtUserSendMessage(Window->Self, WM_NCPAINT, (WPARAM)hClip, 0); NtUserSendMessage(Window->Self, WM_NCPAINT, (WPARAM) hClip, 0);
if (hClip > (HANDLE)1 && hClip != hRgn && hClip != hRgnRet) if ((HRGN) 1 < hClip && hClip != hRgn && hClip != hRgnRet)
{ {
W32kDeleteObject(hClip); W32kDeleteObject(hClip);
/* FIXME: Need to check the window is still valid. */
} }
/* FIXME: Need to check the window is still valid. */
} }
return(hRgnRet); return(hRgnRet);
} }
@ -852,48 +943,76 @@ NtUserBeginPaint(HWND hWnd, PAINTSTRUCT* lPs)
DWORD DWORD
STDCALL STDCALL
NtUserInvalidateRect( NtUserInvalidateRect(
HWND hWnd, HWND Wnd,
CONST RECT *lpRect, CONST RECT *Rect,
WINBOOL bErase) WINBOOL Erase)
{ {
HRGN hRGN; return PaintRedrawWindow(Wnd, Rect, 0, RDW_INVALIDATE | (Erase ? RDW_ERASE : 0), 0);
hRGN = W32kCreateRectRgnIndirect((PRECT)lpRect);
return NtUserInvalidateRgn(hWnd, hRGN, bErase);
} }
DWORD DWORD
STDCALL STDCALL
NtUserInvalidateRgn( NtUserInvalidateRgn(
HWND Wnd,
HRGN Rgn,
WINBOOL Erase)
{
return PaintRedrawWindow(Wnd, NULL, Rgn, RDW_INVALIDATE | (Erase ? RDW_ERASE : 0), 0);
}
BOOL
STDCALL
NtUserValidateRgn(
HWND hWnd,
HRGN hRgn)
{
return PaintRedrawWindow(hWnd, NULL, hRgn, RDW_VALIDATE | RDW_NOCHILDREN, 0);
}
int
STDCALL
NtUserGetUpdateRgn(
HWND hWnd, HWND hWnd,
HRGN hRgn, HRGN hRgn,
WINBOOL bErase) WINBOOL bErase)
{ {
PWINDOW_OBJECT WindowObject; PWINDOW_OBJECT Window;
int RegionType;
WindowObject = W32kGetWindowObject(hWnd); Window = W32kGetWindowObject(hWnd);
if (WindowObject == NULL) if (NULL == Window)
{ {
return(FALSE); return ERROR;
} }
if( WindowObject->UpdateRegion == NULL ) if (NULL == Window->UpdateRegion)
{ {
WindowObject->UpdateRegion = W32kCreateRectRgn (0, 0, 1, 1); RegionType = (W32kSetRectRgn(hRgn, 0, 0, 0, 0) ? NULLREGION : ERROR);
if (!W32kCombineRgn(WindowObject->UpdateRegion, hRgn, hRgn, RGN_COPY )) }
{ else if ((HRGN) 1 == Window->UpdateRegion)
W32kReleaseWindowObject(WindowObject); {
return(FALSE); RegionType = (W32kSetRectRgn(hRgn,
} 0, 0,
Window->ClientRect.right - Window->ClientRect.left,
Window->ClientRect.bottom - Window->ClientRect.top) ?
SIMPLEREGION : ERROR);
}
else
{
RegionType = W32kCombineRgn(hRgn, Window->UpdateRegion, hRgn, RGN_COPY);
W32kOffsetRgn(hRgn, Window->WindowRect.left - Window->ClientRect.left,
Window->WindowRect.top - Window->ClientRect.top );
} }
if (!W32kCombineRgn(WindowObject->UpdateRegion, WindowObject->UpdateRegion, hRgn, RGN_OR )) W32kReleaseWindowObject(Window);
if (bErase &&
(SIMPLEREGION == RegionType || COMPLEXREGION == RegionType))
{ {
W32kReleaseWindowObject(WindowObject); PaintRedrawWindow(hWnd, NULL, NULL, RDW_ERASENOW | RDW_NOCHILDREN, 0);
return(FALSE);
} }
W32kReleaseWindowObject(WindowObject); return RegionType;
W32kSendMessage(hWnd, WM_PAINT, 0, 0, FALSE);
return(TRUE);
} }
/* EOF */ /* EOF */

View file

@ -1,4 +1,4 @@
/* $Id: stubs.c,v 1.10 2003/05/18 17:16:17 ea Exp $ /* $Id: stubs.c,v 1.11 2003/05/26 18:52:37 gvg Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -183,18 +183,6 @@ NtUserCallOneParam(
return 0; return 0;
} }
DWORD
STDCALL
NtUserCallTwoParam(
DWORD Unknown0,
DWORD Unknown1,
DWORD Unknown2)
{
UNIMPLEMENTED
return 0;
}
DWORD DWORD
STDCALL STDCALL
NtUserChangeClipboardChain( NtUserChangeClipboardChain(
@ -1032,18 +1020,6 @@ NtUserGetUpdateRect(
return 0; return 0;
} }
DWORD
STDCALL
NtUserGetUpdateRgn(
DWORD Unknown0,
DWORD Unknown1,
DWORD Unknown2)
{
UNIMPLEMENTED
return 0;
}
DWORD DWORD
STDCALL STDCALL
NtUserHideCaret( NtUserHideCaret(