+/*
+ * 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.
+ */
/* $Id$
*
* COPYRIGHT: See COPYING in the top level directory
#include <include/rect.h>
#include <win32k/coord.h>
#include <win32k/region.h>
-
+#include <include/vis.h>
#define NDEBUG
#include <debug.h>
+
/* GLOBALS *******************************************************************/
-#define UNC_DELAY_NCPAINT (0x00000001)
-#define UNC_IN_BEGINPAINT (0x00000002)
-#define UNC_CHECK (0x00000004)
-#define UNC_REGION (0x00000008)
-#define UNC_ENTIRE (0x00000010)
-#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 *****************************************************************/
-HRGN STATIC
+HRGN STATIC STDCALL
PaintDoPaint(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags, ULONG ExFlags)
{
HDC hDC;
HWND hWnd = Window->Self;
- BOOL bIcon = (Window->Style & WS_MINIMIZE) &&
- NtUserGetClassLong(hWnd, GCL_HICON);
+ BOOL bIcon = (0 != (Window->Style & WS_MINIMIZE)) &&
+ (0 != IntGetClassLong(Window, GCL_HICON, FALSE));
- if (ExFlags & RDW_EX_DELAY_NCPAINT ||
+ if (0 != (ExFlags & RDW_EX_DELAY_NCPAINT) ||
PaintHaveToDelayNCPaint(Window, 0))
{
ExFlags |= RDW_EX_DELAY_NCPAINT;
if (Flags & RDW_UPDATENOW)
{
- if (Window->UpdateRegion != NULL)
+ if (NULL != Window->UpdateRegion)
{
- NtUserSendMessage(hWnd, bIcon ? WM_PAINTICON : WM_PAINT, bIcon, 0);
+ if (IntIsDesktopWindow(Window))
+ {
+ VIS_RepaintDesktop(Window->Self, Window->UpdateRegion);
+ }
+ else
+ {
+ NtUserSendMessage(hWnd, bIcon ? WM_PAINTICON : WM_PAINT, bIcon, 0);
+ }
}
}
else if (Flags & RDW_ERASENOW || ExFlags & RDW_EX_TOPFRAME)
((ExFlags & RDW_EX_TOPFRAME) ? UNC_ENTIRE : 0) |
((ExFlags & RDW_EX_DELAY_NCPAINT) ?
UNC_DELAY_NCPAINT : 0));
- if (hRgnRet != NULL)
+ if (NULL != hRgnRet)
{
- if (hRgnRet != (HRGN)1)
+ if ((HRGN) 1 < hRgnRet)
{
hRgn = hRgnRet;
}
{
hRgnRet = NULL;
}
- if (Window->Flags & WINDOWOBJECT_NEED_ERASEBACKGRD)
+ if (0 != (Window->Flags & WINDOWOBJECT_NEED_ERASEBACKGRD))
{
if (bIcon)
{
Dcx |= DCX_WINDOW;
}
- if (hRgnRet)
+ if (NULL != hRgnRet)
{
- W32kOffsetRgn(hRgnRet,
+ NtGdiOffsetRgn(hRgnRet,
Window->WindowRect.left -
Window->ClientRect.left,
Window->WindowRect.top -
{
Dcx &= ~DCX_INTERSECTRGN;
}
- if ((hDC = NtUserGetDCEx(hWnd, hRgnRet, Dcx)) != NULL)
+ if (NULL != (hDC = NtUserGetDCEx(hWnd, hRgnRet, Dcx)))
{
- LRESULT Result;
- Result = NtUserSendMessage(hWnd, bIcon ? WM_ICONERASEBKGND :
- WM_ERASEBKGND, (WPARAM)hDC, 0);
- Window->Flags &= ~WINDOWOBJECT_NEED_ERASEBACKGRD;
+ if (IntIsDesktopWindow(Window))
+ {
+ VIS_RepaintDesktop(Window->Self, Window->UpdateRegion);
+ NtGdiDeleteObject(Window->UpdateRegion);
+ Window->UpdateRegion = 0;
+ }
+ else
+ {
+ if (0 != NtUserSendMessage(hWnd, bIcon ? WM_ICONERASEBKGND :
+ WM_ERASEBKGND, (WPARAM)hDC, 0))
+ {
+ Window->Flags &= ~WINDOWOBJECT_NEED_ERASEBACKGRD;
+ }
+ }
NtUserReleaseDC(hWnd, hDC);
}
}
return(hRgn);
}
-VOID STATIC
+VOID STATIC FASTCALL
PaintUpdateInternalPaint(PWINDOW_OBJECT Window, ULONG Flags)
{
if (Flags & RDW_INTERNALPAINT)
}
}
-VOID STATIC
+VOID STATIC FASTCALL
PaintValidateParent(PWINDOW_OBJECT Child)
{
- HWND DesktopHandle = W32kGetDesktopWindow();
+ HWND DesktopHandle = IntGetDesktopWindow();
PWINDOW_OBJECT Parent = Child->Parent;
- PWINDOW_OBJECT Desktop = W32kGetWindowObject(DesktopHandle);
+ PWINDOW_OBJECT Desktop = IntGetWindowObject(DesktopHandle);
HRGN hRgn;
- if (Child->UpdateRegion == (HANDLE)1)
+ if ((HRGN) 1 == Child->UpdateRegion)
{
RECT Rect;
Rect.right = Child->WindowRect.right - Child->WindowRect.left;
Rect.bottom = Child->WindowRect.bottom - Child->WindowRect.top;
- hRgn = UnsafeW32kCreateRectRgnIndirect(&Rect);
+ hRgn = UnsafeIntCreateRectRgnIndirect(&Rect);
}
else
{
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;
- if (Parent->UpdateRegion == (HANDLE)1)
+ if ((HRGN) 1 == Parent->UpdateRegion)
{
RECT Rect1;
Parent->WindowRect.top;
Parent->UpdateRegion =
- UnsafeW32kCreateRectRgnIndirect(&Rect1);
+ UnsafeIntCreateRectRgnIndirect(&Rect1);
}
Offset.x = Child->WindowRect.left - Parent->WindowRect.left;
Offset.y = Child->WindowRect.top - Parent->WindowRect.top;
- W32kOffsetRgn(hRgn, Offset.x, Offset.y);
- W32kCombineRgn(Parent->UpdateRegion, Parent->UpdateRegion, hRgn,
+ NtGdiOffsetRgn(hRgn, Offset.x, Offset.y);
+ NtGdiCombineRgn(Parent->UpdateRegion, Parent->UpdateRegion, hRgn,
RGN_DIFF);
- W32kOffsetRgn(hRgn, -Offset.x, -Offset.y);
+ NtGdiOffsetRgn(hRgn, -Offset.x, -Offset.y);
}
}
Parent = Parent->Parent;
}
if (hRgn != Child->UpdateRegion)
{
- W32kDeleteObject(Child->UpdateRegion);
+ NtGdiDeleteObject(Child->UpdateRegion);
}
- W32kReleaseWindowObject(Desktop);
+ IntReleaseWindowObject(Desktop);
}
-VOID STATIC
+VOID STATIC STDCALL
PaintUpdateRgns(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags,
BOOL First)
{
- BOOL HadOne = Window->UpdateRegion != NULL && hRgn;
- BOOL HasChildren = !IsListEmpty(&Window->ChildrenListHead) &&
+ /*
+ * 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 = Window->FirstChild &&
!(Flags & RDW_NOCHILDREN) && !(Window->Style & WS_MINIMIZE) &&
((Flags & RDW_ALLCHILDREN) || !(Window->Style & WS_CLIPCHILDREN));
RECT Rect;
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,
- hRgn, RGN_OR);
- Window->UpdateRegion =
- REGION_CropRgn(Window->UpdateRegion,
- Window->UpdateRegion, &Rect, NULL);
- if (!HadOne)
+ if ((HRGN) 1 < Window->UpdateRegion)
{
- W32kGetRgnBox(Window->UpdateRegion, &Rect);
- if (W32kIsEmptyRect(&Rect))
- {
- W32kDeleteObject(Window->UpdateRegion);
- Window->UpdateRegion = NULL;
- PaintUpdateInternalPaint(Window, Flags);
- return;
- }
+ NtGdiCombineRgn(Window->UpdateRegion, Window->UpdateRegion,
+ hRgn, RGN_OR);
}
- }
- else if (Window->UpdateRegion == 0)
- {
Window->UpdateRegion =
- REGION_CropRgn(Window->UpdateRegion, hRgn, &Rect, NULL);
- if (!HadOne)
+ REGION_CropRgn(Window->UpdateRegion,
+ Window->UpdateRegion ? Window->UpdateRegion : hRgn,
+ &Rect, NULL);
+ if (! HadOne)
{
- W32kGetRgnBox(Window->UpdateRegion, &Rect);
- if (W32kIsEmptyRect(&Rect))
+ UnsafeIntGetRgnBox(Window->UpdateRegion, &Rect);
+ if (NtGdiIsEmptyRect(&Rect))
{
- W32kDeleteObject(Window->UpdateRegion);
+ NtGdiDeleteObject(Window->UpdateRegion);
Window->UpdateRegion = NULL;
PaintUpdateInternalPaint(Window, Flags);
return;
}
}
}
- else if (hRgn == (HANDLE)1)
+ else if ((HRGN) 1 == hRgn)
{
- if (Window->UpdateRegion > (HANDLE)1)
+ if ((HRGN) 1 < Window->UpdateRegion)
{
- W32kDeleteObject(Window->UpdateRegion);
+ NtGdiDeleteObject(Window->UpdateRegion);
}
- Window->UpdateRegion = (HANDLE)1;
+ Window->UpdateRegion = (HRGN) 1;
}
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) &&
+ !IntIsDesktopWindow(Window))
{
MsqIncPaintCountQueue(Window->MessageQueue);
}
}
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 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;
+ }
Window->UpdateRegion =
- UnsafeW32kCreateRectRgnIndirect(&Rect);
+ UnsafeIntCreateRectRgnIndirect(&Rect);
}
- if (W32kCombineRgn(Window->UpdateRegion,
+ if (NtGdiCombineRgn(Window->UpdateRegion,
Window->UpdateRegion, hRgn,
RGN_DIFF) == NULLREGION)
{
- if (Window->UpdateRegion > (HANDLE)1)
- {
- W32kDeleteObject(Window->UpdateRegion);
- }
+ NtGdiDeleteObject(Window->UpdateRegion);
Window->UpdateRegion = NULL;
}
}
- else
+ else /* validate everything */
{
- if (Window->UpdateRegion > (HANDLE)1)
+ if ((HRGN) 1 < Window->UpdateRegion)
{
- W32kDeleteObject(Window->UpdateRegion);
+ NtGdiDeleteObject(Window->UpdateRegion);
}
Window->UpdateRegion = NULL;
}
- if (Window->UpdateRegion == NULL)
+ if (NULL != Window->UpdateRegion)
{
Window->Flags &= ~WINDOWOBJECT_NEED_ERASEBACKGRD;
- if (!(Window->Flags & WINDOWOBJECT_NEED_INTERNALPAINT))
+ if (0 != (Window->Flags & WINDOWOBJECT_NEED_INTERNALPAINT))
{
- MsqIncPaintCountQueue(Window->MessageQueue);
+ MsqDecPaintCountQueue(Window->MessageQueue);
}
}
}
}
}
- 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 PrevOrign = {0, 0};
- POINT Client;
PWINDOW_OBJECT Child;
- PLIST_ENTRY ChildListEntry;
-
- Client.x = Window->ClientRect.left - Window->WindowRect.left;
- Client.y = Window->ClientRect.top - Window->WindowRect.top;
- ChildListEntry = Window->ChildrenListHead.Flink;
- while (ChildListEntry != &Window->ChildrenListHead)
+ ExAcquireFastMutexUnsafe(&Window->ChildrenListLock);
+ Child = Window->FirstChild;
+ while (Child)
{
- Child = CONTAINING_RECORD(ChildListEntry, WINDOW_OBJECT,
- SiblingListEntry);
- if (Child->Style & WS_VISIBLE)
+ if (0 != (Child->Style & WS_VISIBLE))
{
POINT Offset;
- 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;
+ 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;
Offset.x = Rect.left - PrevOrign.x;
Offset.y = Rect.top - PrevOrign.y;
- W32kOffsetRect(&Rect, -Total.x, -Total.y);
+ NtGdiOffsetRect(&Rect, -Total.x, -Total.y);
- if (W32kRectInRegion(hRgn, &Rect))
+ if (UnsafeIntRectInRegion(hRgn, &Rect))
{
- W32kOffsetRgn(hRgn, -Total.x, -Total.y);
+ NtGdiOffsetRgn(hRgn, -Offset.x, -Offset.y);
PaintUpdateRgns(Child, hRgn, Flags, FALSE);
PrevOrign.x = Rect.left + Total.x;
- PrevOrign.y = Rect.right + Total.y;
+ PrevOrign.y = Rect.top + Total.y;
Total.x += Offset.x;
Total.y += Offset.y;
}
}
+ Child = Child->NextSibling;
}
- W32kOffsetRgn(hRgn, Total.x, Total.y);
+ ExReleaseFastMutexUnsafe(&Window->ChildrenListLock);
+
+ NtGdiOffsetRgn(hRgn, Total.x, Total.y);
HasChildren = FALSE;
}
}
if (HasChildren)
- {
- PWINDOW_OBJECT Child;
- PLIST_ENTRY ChildListEntry;
+ {
+ PWINDOW_OBJECT Child;
- ChildListEntry = Window->ChildrenListHead.Flink;
- while (ChildListEntry != &Window->ChildrenListHead)
- {
- Child = CONTAINING_RECORD(ChildListEntry, WINDOW_OBJECT,
- SiblingListEntry);
- if (Child->Style & WS_VISIBLE)
- {
- PaintUpdateRgns(Child, hRgn, Flags, FALSE);
- }
- }
+ ExAcquireFastMutexUnsafe(&Window->ChildrenListLock);
+ Child = Window->FirstChild;
+ while (Child)
+ {
+ if (Child->Style & WS_VISIBLE)
+ {
+ PaintUpdateRgns(Child, hRgn, Flags, FALSE);
+ }
+ Child = Child->NextSibling;
}
+ ExReleaseFastMutexUnsafe(&Window->ChildrenListLock);
+ }
PaintUpdateInternalPaint(Window, Flags);
}
-BOOL
-PaintRedrawWindow(HWND hWnd, const RECT* UpdateRect, HRGN UpdateRgn,
- ULONG Flags, ULONG ExFlags)
+BOOL STDCALL
+PaintRedrawWindow( PWINDOW_OBJECT Window,
+ const RECT* UpdateRect,
+ HRGN UpdateRgn,
+ ULONG Flags,
+ ULONG ExFlags)
{
- PWINDOW_OBJECT Window;
RECT Rect, Rect2;
POINT Pt;
- HRGN hRgn;
-
- /* FIXME: Return if this is for a desktop. */
+ HRGN hRgn = NULL;
- Window = W32kGetWindowObject(hWnd);
- if (Window == NULL)
- {
- return(FALSE);
- }
+ DPRINT("[win32k.sys:painting] In PaintRedrawWindow()\n");
- 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;
}
if (ExFlags & RDW_EX_XYWINDOW)
{
Pt.x = Pt.y = 0;
- W32kOffsetRect(&Rect, -Window->WindowRect.left, -Window->WindowRect.top);
+ NtGdiOffsetRect(&Rect, -Window->WindowRect.left, -Window->WindowRect.top);
}
else
{
Pt.x = Window->ClientRect.left - Window->WindowRect.left;
Pt.y = Window->ClientRect.top - Window->WindowRect.top;
- W32kOffsetRect(&Rect, -Window->ClientRect.left, -Window->WindowRect.top);
+ NtGdiOffsetRect(&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
{
- 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 (! NtGdiIntersectRect(&Rect2, &Rect, UpdateRect))
{
- W32kReleaseWindowObject(Window);
- if (hRgn != NULL && hRgn != (HRGN)1)
+
+ if ((HRGN) 1 < hRgn && hRgn != UpdateRgn)
{
- W32kDeleteObject(hRgn);
+ NtGdiDeleteObject(hRgn);
}
- return(TRUE);
+ return TRUE;
}
- if (Window->UpdateRegion == NULL)
+ NtGdiOffsetRect(&Rect2, Pt.x, Pt.y);
+ if (NULL == Window->UpdateRegion)
{
- Window->UpdateRegion =
- UnsafeW32kCreateRectRgnIndirect(&Rect2);
+ Window->UpdateRegion =
+ UnsafeIntCreateRectRgnIndirect(&Rect2);
}
else
{
- hRgn = UnsafeW32kCreateRectRgnIndirect(&Rect2);
+ hRgn = UnsafeIntCreateRectRgnIndirect(&Rect2);
}
}
- else
+ else /* entire window or client depending on RDW_FRAME */
{
if (Flags & RDW_FRAME)
{
- hRgn = (HRGN)1;
+ if (NULL != Window->UpdateRegion)
+ {
+ hRgn = (HRGN) 1;
+ }
+ else
+ {
+ Window->UpdateRegion = (HRGN) 1;
+ }
}
else
{
- W32kGetClientRect(Window, &Rect2);
- hRgn = UnsafeW32kCreateRectRgnIndirect(&Rect2);
+ GETCLIENTRECTW(Window, Rect2);
+ if (NULL == Window->UpdateRegion)
+ {
+ Window->UpdateRegion = UnsafeIntCreateRectRgnIndirect(&Rect2);
+ }
+ else
+ {
+ hRgn = UnsafeIntCreateRectRgnIndirect(&Rect2);
+ }
}
}
}
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);
+ UnsafeIntGetRgnBox(hRgn, &Rect2);
+ if (NtGdiIsEmptyRect(&Rect2))
+ {
+
+ if ((HRGN) 1 < hRgn && hRgn != UpdateRgn)
+ {
+ NtGdiDeleteObject(hRgn);
+ }
+ return TRUE;
+ }
+ }
+ else if (NULL != UpdateRect)
+ {
+ if (! NtGdiIntersectRect(&Rect2, &Rect, UpdateRect))
+ {
+
+ if ((HRGN) 1 < hRgn && hRgn != UpdateRgn)
+ {
+ NtGdiDeleteObject(hRgn);
+ }
+ return TRUE;
+ }
+ NtGdiOffsetRect(&Rect2, Pt.x, Pt.y);
+ hRgn = UnsafeIntCreateRectRgnIndirect(&Rect2);
+ }
+ else /* entire window or client depending on RDW_NOFRAME */
+ {
+ if (0 != (Flags & RDW_NOFRAME))
+ {
+ hRgn = (HRGN) 1;
+ }
+ else
+ {
+ GETCLIENTRECTW(Window, Rect2);
+ hRgn = UnsafeIntCreateRectRgnIndirect(&Rect2);
+ }
+ }
}
+ /* At this point hRgn is either an update region in window coordinates or 1 or 0 */
+
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);
+ NtGdiDeleteObject(hRgn);
}
- W32kReleaseWindowObject(Window);
- return(TRUE);
+
+ return TRUE;
}
BOOL STDCALL
{
if (Window->Style & WS_CLIPCHILDREN && Window->UpdateRegion != NULL)
{
- return(TRUE);
+ return TRUE;
}
Window = Window->Parent;
}
- return(FALSE);
+
+ return FALSE;
}
HWND STDCALL
return(NULL);
}
- BaseWindow = W32kGetWindowObject(hWnd);
+ BaseWindow = IntGetWindowObject(hWnd);
if (BaseWindow == NULL)
{
return(NULL);
if (BaseWindow->UpdateRegion != NULL ||
BaseWindow->Flags & WINDOWOBJECT_NEED_INTERNALPAINT)
{
- W32kReleaseWindowObject(BaseWindow);
+ IntReleaseWindowObject(BaseWindow);
return(hWnd);
}
ExAcquireFastMutex(&BaseWindow->ChildrenListLock);
- current_entry = BaseWindow->ChildrenListHead.Flink;
- while (current_entry != &BaseWindow->ChildrenListHead)
+ Window = BaseWindow->FirstChild;
+ while (Window)
+ {
+ if (Window->Style & WS_VISIBLE)
{
- Window = CONTAINING_RECORD(current_entry, WINDOW_OBJECT,
- ChildrenListHead);
- if (Window->Style & WS_VISIBLE)
- {
- hFoundWnd = PaintingFindWinToRepaint(Window->Self, Thread);
- if (hFoundWnd != NULL)
- {
- break;
- }
- }
- current_entry = current_entry->Flink;
+ hFoundWnd = PaintingFindWinToRepaint(Window->Self, Thread);
+ if (hFoundWnd != NULL)
+ {
+ break;
+ }
}
+ Window = Window->NextSibling;
+ }
ExReleaseFastMutex(&BaseWindow->ChildrenListLock);
- W32kReleaseWindowObject(BaseWindow);
+
+ IntReleaseWindowObject(BaseWindow);
return(hFoundWnd);
}
if (Window->Parent == NULL)
{
Window->Flags &= ~WINDOWOBJECT_NEED_NCPAINT;
- if (Window->UpdateRegion > (HANDLE)1)
+ if ((HRGN) 1 < Window->UpdateRegion)
{
hRgnRet = REGION_CropRgn(hRgn, Window->UpdateRegion, NULL, NULL);
}
return(hRgnRet);
}
- if (Window->Flags & WINDOWOBJECT_NEED_NCPAINT &&
- !PaintHaveToDelayNCPaint(Window, Flags))
+#if 0 /* NtUserGetFOregroundWindow() not implemented yet */
+ 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 Rect;
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);
- W32kUnionRect(&Rect, &ClientRect, &UpdateRegionBox);
+ 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;
if (Flags & UNC_CHECK)
{
- W32kGetRgnBox(Window->UpdateRegion, &UpdateRegionBox);
- if (W32kIsEmptyRect(&UpdateRegionBox))
+ UnsafeIntGetRgnBox(Window->UpdateRegion, &UpdateRegionBox);
+ if (NtGdiIsEmptyRect(&UpdateRegionBox))
{
- W32kDeleteObject(Window->UpdateRegion);
+ NtGdiDeleteObject(Window->UpdateRegion);
Window->UpdateRegion = NULL;
- MsqDecPaintCountQueue(Window->MessageQueue);
+ if (0 == (Window->Flags & WINDOWOBJECT_NEED_INTERNALPAINT))
+ {
+ MsqDecPaintCountQueue(Window->MessageQueue);
+ }
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,
- NULL);
+ goto copyrgn;
}
}
- else if (Window->UpdateRegion == (HRGN)1)
+ else if ((HRGN) 1 == Window->UpdateRegion)
{
- if (Flags & UNC_UPDATE)
+ if (0 != (Flags & UNC_UPDATE))
{
Window->UpdateRegion =
- UnsafeW32kCreateRectRgnIndirect(&ClientRect);
+ UnsafeIntCreateRectRgnIndirect(&ClientRect);
}
if (Flags & UNC_REGION)
{
- hRgnRet = (HANDLE)1;
+ hRgnRet = (HRGN) 1;
}
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 =
- UnsafeW32kCreateRectRgnIndirect(&ClientRect);
+ UnsafeIntCreateRectRgnIndirect(&ClientRect);
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,
sizeof(RECT)) != sizeof(RECT))
{
- hClip = (HANDLE)1;
+ hClip = (HRGN) 1;
}
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);
- W32kCombineRgn(hClip, hRgnRet, 0, RGN_COPY);
+ hClip = NtGdiCreateRectRgn(0, 0, 0, 0);
+ NtGdiCombineRgn(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);
- /* FIXME: Need to check the window is still valid. */
+ NtGdiDeleteObject(hClip);
}
+
+ /* FIXME: Need to check the window is still valid. */
}
return(hRgnRet);
}
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)
{
HRGN UpdateRegion;
RECT ClientRect;
RECT ClipRect;
- NTSTATUS Status;
-
- Status =
- ObmReferenceObjectByHandle(PsGetWin32Process()->WindowStation->HandleTable,
- hWnd,
- otWindow,
- (PVOID*)&Window);
- if (!NT_SUCCESS(Status))
- {
- return(NULL);
- }
- IsIcon = Window->Style & WS_MINIMIZE &&
- NtUserGetClassLong(Window->Self, GCL_HICON);
-
- Window->Flags &= ~WINDOWOBJECT_NEED_BEGINPAINT;
-
+ //NTSTATUS Status;
+ INT DcxFlags;
+
+ if (!(Window = IntGetWindowObject(hWnd)))
+ {
+ SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
+ return NULL;
+ }
+
/* Send WM_NCPAINT */
PaintUpdateNCRegion(Window, 0, UNC_UPDATE | UNC_IN_BEGINPAINT);
- /* FIXME: Check the window is still valid. */
+ /* Check ifthe window is still valid. */
+ if (!IntGetWindowObject(hWnd))
+ {
+ return 0;
+ }
- UpdateRegion = Window->UpdateRegion;
+ /* retrieve update region */
+ UpdateRegion = GetClientUpdateRegion(Window);
+ if (1 < (DWORD) Window->UpdateRegion)
+ {
+ NtGdiDeleteObject(Window->UpdateRegion);
+ }
Window->UpdateRegion = 0;
- if (UpdateRegion != NULL ||
- (Window->Flags & WINDOWOBJECT_NEED_INTERNALPAINT))
+ if (UpdateRegion != NULL || (Window->Flags & WINDOWOBJECT_NEED_INTERNALPAINT))
{
MsqDecPaintCountQueue(Window->MessageQueue);
}
Window->Flags &= ~WINDOWOBJECT_NEED_INTERNALPAINT;
- /* FIXME: Hide claret. */
+ /* FIXME: Hide caret. */
+ IsIcon = (Window->Style & WS_MINIMIZE) && IntGetClassLong(Window, GCL_HICON, FALSE);
- if (NtUserGetClassLong(Window->Self, GCL_STYLE) & CS_PARENTDC)
+ DcxFlags = DCX_INTERSECTRGN | DCX_WINDOWPAINT | DCX_USESTYLE;
+ if (IsIcon)
+ {
+ DcxFlags |= DCX_WINDOW;
+ }
+ if (IntGetClassLong(Window, GCL_STYLE, FALSE) & CS_PARENTDC)
{
- if (UpdateRegion != NULL)
+ /* Don't clip the output to the update region for CS_PARENTDC window */
+ if ((HRGN) 1 < UpdateRegion)
{
- W32kDeleteObject(UpdateRegion);
+ NtGdiDeleteObject(UpdateRegion);
}
- lPs->hdc = NtUserGetDCEx(hWnd, 0, DCX_WINDOWPAINT | DCX_USESTYLE |
- (IsIcon ? DCX_WINDOW : 0));
+ UpdateRegion = NULL;
+ DcxFlags &= ~DCX_INTERSECTRGN;
}
else
{
- if (UpdateRegion != NULL)
+ if (NULL == UpdateRegion) /* empty region, clip everything */
+ {
+ UpdateRegion = NtGdiCreateRectRgn(0, 0, 0, 0);
+ }
+ else if ((HRGN) 1 == UpdateRegion) /* whole client area, don't clip */
{
- W32kOffsetRgn(UpdateRegion,
- Window->WindowRect.left -
- Window->ClientRect.left,
- Window->WindowRect.top -
- Window->ClientRect.top);
+ UpdateRegion = NULL;
+ DcxFlags &= ~DCX_INTERSECTRGN;
}
- lPs->hdc = NtUserGetDCEx(hWnd, UpdateRegion, DCX_INTERSECTRGN |
- DCX_WINDOWPAINT | DCX_USESTYLE |
- (IsIcon ? DCX_WINDOW : 0));
}
+ lPs->hdc = NtUserGetDCEx(hWnd, UpdateRegion, DcxFlags);
/* FIXME: Check for DC creation failure. */
- W32kGetClientRect(Window, &ClientRect);
- W32kGetClipBox(lPs->hdc, &ClipRect);
- W32kLPtoDP(lPs->hdc, (LPPOINT)&ClipRect, 2);
- W32kIntersectRect(&lPs->rcPaint, &ClientRect, &ClipRect);
- W32kDPtoLP(lPs->hdc, (LPPOINT)&lPs->rcPaint, 2);
+ IntGetClientRect(Window, &ClientRect);
+ NtGdiGetClipBox(lPs->hdc, &ClipRect);
+ NtGdiLPtoDP(lPs->hdc, (LPPOINT)&ClipRect, 2);
+ NtGdiIntersectRect(&lPs->rcPaint, &ClientRect, &ClipRect);
+ NtGdiDPtoLP(lPs->hdc, (LPPOINT)&lPs->rcPaint, 2);
if (Window->Flags & WINDOWOBJECT_NEED_ERASEBACKGRD)
{
STDCALL
NtUserInvalidateRect(
HWND hWnd,
- CONST RECT *lpRect,
- WINBOOL bErase)
+ CONST RECT *Rect,
+ WINBOOL Erase)
{
- HRGN hRGN;
- hRGN = W32kCreateRectRgnIndirect(lpRect);
- return NtUserInvalidateRgn(hWnd, hRGN, bErase);
+ return NtUserRedrawWindow(hWnd, Rect, 0, RDW_INVALIDATE | (Erase ? RDW_ERASE : 0));
}
DWORD
STDCALL
NtUserInvalidateRgn(
HWND hWnd,
+ HRGN Rgn,
+ WINBOOL Erase)
+{
+ return NtUserRedrawWindow(hWnd, NULL, Rgn, RDW_INVALIDATE | (Erase ? RDW_ERASE : 0));
+}
+
+BOOL
+STDCALL
+NtUserValidateRgn(
+ HWND hWnd,
+ HRGN hRgn)
+{
+ return NtUserRedrawWindow(hWnd, NULL, hRgn, RDW_VALIDATE | RDW_NOCHILDREN);
+}
+
+int
+STDCALL
+NtUserGetUpdateRgn(
+ HWND hWnd,
HRGN hRgn,
WINBOOL bErase)
{
- PWINDOW_OBJECT WindowObject;
+ PWINDOW_OBJECT Window;
+ int RegionType;
- WindowObject = W32kGetWindowObject(hWnd);
- if (WindowObject == NULL)
+ if (!(Window = IntGetWindowObject(hWnd)))
+ {
+ SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
+ return ERROR;
+ }
+
+ if (NULL == Window->UpdateRegion)
{
- return(FALSE);
+ RegionType = (NtGdiSetRectRgn(hRgn, 0, 0, 0, 0) ? NULLREGION : ERROR);
}
-
- if( WindowObject->UpdateRegion == NULL )
+ else if ((HRGN) 1 == Window->UpdateRegion)
{
- WindowObject->UpdateRegion = W32kCreateRectRgn (0, 0, 1, 1);
- if (!W32kCombineRgn(WindowObject->UpdateRegion, hRgn, hRgn, RGN_COPY ))
- {
- W32kReleaseWindowObject(WindowObject);
- return(FALSE);
- }
+ RegionType = (NtGdiSetRectRgn(hRgn,
+ 0, 0,
+ Window->ClientRect.right - Window->ClientRect.left,
+ Window->ClientRect.bottom - Window->ClientRect.top) ?
+ SIMPLEREGION : ERROR);
+ }
+ else
+ {
+ RegionType = NtGdiCombineRgn(hRgn, Window->UpdateRegion, hRgn, RGN_COPY);
+ NtGdiOffsetRgn(hRgn, Window->WindowRect.left - Window->ClientRect.left,
+ Window->WindowRect.top - Window->ClientRect.top );
}
- if (!W32kCombineRgn(WindowObject->UpdateRegion, WindowObject->UpdateRegion, hRgn, RGN_OR ))
+ if (bErase &&
+ (SIMPLEREGION == RegionType || COMPLEXREGION == RegionType))
{
- W32kReleaseWindowObject(WindowObject);
- return(FALSE);
+ PaintRedrawWindow(Window, NULL, NULL, RDW_ERASENOW | RDW_NOCHILDREN, 0);
}
+
+ IntReleaseWindowObject(Window);
- W32kReleaseWindowObject(WindowObject);
- W32kSendMessage(hWnd, WM_PAINT, 0, 0, FALSE);
- return(TRUE);
+ return RegionType;
}
+/* EOF */