Partial clean-up of the painting functions: - Get rid of the DCX_WINDOWPAINT flag (it wasn't used anyway). - Remove the PaintPosted field from message queue, we don't need it. - Use screen cooridnates for the WindowUpdate region instead of window relative ones. - Fix the algorithm for retrieving paint messages to respect the painting order. - Remove the NCUpdateRegion field from window object and calculate it on demand. - Fix GetDCEx to take region in screen coordinates. Modified: trunk/reactos/subsys/win32k/include/dce.h Modified: trunk/reactos/subsys/win32k/include/msgqueue.h Modified: trunk/reactos/subsys/win32k/include/window.h Modified: trunk/reactos/subsys/win32k/ntuser/msgqueue.c Modified: trunk/reactos/subsys/win32k/ntuser/painting.c Modified: trunk/reactos/subsys/win32k/ntuser/vis.c Modified: trunk/reactos/subsys/win32k/ntuser/windc.c Modified: trunk/reactos/subsys/win32k/ntuser/winpos.c Modified: trunk/reactos/subsys/win32k/objects/cliprgn.c _____
Modified: trunk/reactos/subsys/win32k/include/dce.h --- trunk/reactos/subsys/win32k/include/dce.h 2005-09-19 10:04:07 UTC (rev 17930) +++ trunk/reactos/subsys/win32k/include/dce.h 2005-09-19 10:39:26 UTC (rev 17931) @@ -39,7 +39,7 @@
#define DCX_DCEEMPTY 0x00000800 #define DCX_DCEBUSY 0x00001000 #define DCX_DCEDIRTY 0x00002000 -#define DCX_WINDOWPAINT 0x00020000 +#define DCX_USESTYLE 0x00010000 #define DCX_KEEPCLIPRGN 0x00040000 #define DCX_NOCLIPCHILDREN 0x00080000
_____
Modified: trunk/reactos/subsys/win32k/include/msgqueue.h --- trunk/reactos/subsys/win32k/include/msgqueue.h 2005-09-19 10:04:07 UTC (rev 17930) +++ trunk/reactos/subsys/win32k/include/msgqueue.h 2005-09-19 10:39:26 UTC (rev 17931) @@ -81,8 +81,6 @@
ULONG LastMsgRead; /* Current window with focus (ie. receives keyboard input) for this queue. */ HWND FocusWindow; - /* True if a window needs painting. */ - BOOLEAN PaintPosted; /* Count of paints pending. */ ULONG PaintCount; /* Current active window for this queue. */ _____
Modified: trunk/reactos/subsys/win32k/include/window.h --- trunk/reactos/subsys/win32k/include/window.h 2005-09-19 10:04:07 UTC (rev 17930) +++ trunk/reactos/subsys/win32k/include/window.h 2005-09-19 10:39:26 UTC (rev 17931) @@ -60,7 +60,6 @@
UINT IDMenu; /* Handle of region of the window to be updated. */ HANDLE UpdateRegion; - HANDLE NCUpdateRegion; /* Handle of the window region. */ HANDLE WindowRegion; /* Pointer to the owning thread's message queue. */ _____
Modified: trunk/reactos/subsys/win32k/ntuser/msgqueue.c --- trunk/reactos/subsys/win32k/ntuser/msgqueue.c 2005-09-19 10:04:07 UTC (rev 17930) +++ trunk/reactos/subsys/win32k/ntuser/msgqueue.c 2005-09-19 10:39:26 UTC (rev 17931) @@ -103,7 +103,6 @@
MsqIncPaintCountQueue(PUSER_MESSAGE_QUEUE Queue) { Queue->PaintCount++; - Queue->PaintPosted = TRUE; Queue->QueueBits |= QS_PAINT; Queue->ChangedBits |= QS_PAINT; if (Queue->WakeMask & QS_PAINT) @@ -114,10 +113,6 @@ MsqDecPaintCountQueue(PUSER_MESSAGE_QUEUE Queue) { Queue->PaintCount--; - if (Queue->PaintCount == 0) - { - Queue->PaintPosted = FALSE; - } }
@@ -1341,7 +1336,6 @@ KeQueryTickCount(&LargeTickCount); MessageQueue->LastMsgRead = LargeTickCount.u.LowPart; MessageQueue->FocusWindow = NULL; - MessageQueue->PaintPosted = FALSE; MessageQueue->PaintCount = 0; MessageQueue->WakeMask = ~0; MessageQueue->NewMessagesHandle = NULL; _____
Modified: trunk/reactos/subsys/win32k/ntuser/painting.c --- trunk/reactos/subsys/win32k/ntuser/painting.c 2005-09-19 10:04:07 UTC (rev 17930) +++ trunk/reactos/subsys/win32k/ntuser/painting.c 2005-09-19 10:39:26 UTC (rev 17931) @@ -35,10 +35,52 @@
#define NDEBUG #include <debug.h>
-#define DCX_USESTYLE 0x10000 - /* PRIVATE FUNCTIONS **********************************************************/
+/** + * @name IntIntersectWithParents + * + * Intersect window rectangle with all parent client rectangles. + * + * @param Child + * Pointer to child window to start intersecting from. + * @param WindowRect + * Pointer to rectangle that we want to intersect in screen + * coordinates on input and intersected rectangle on output (if TRUE + * is returned). + * + * @return + * If any parent is minimized or invisible or the resulting rectangle + * is empty then FALSE is returned. Otherwise TRUE is returned. + */ + +BOOL FASTCALL +IntIntersectWithParents(PWINDOW_OBJECT Child, PRECT WindowRect) +{ + PWINDOW_OBJECT ParentWindow; + + ParentWindow = Child->Parent; + while (ParentWindow != NULL) + { + if (!(ParentWindow->Style & WS_VISIBLE) || + (ParentWindow->Style & WS_MINIMIZE)) + { + return FALSE; + } + + if (!IntGdiIntersectRect(WindowRect, WindowRect, &ParentWindow->ClientRect)) + { + return FALSE; + } + + /* FIXME: Layered windows. */ + + ParentWindow = ParentWindow->Parent; + } + + return TRUE; +} + VOID FASTCALL IntValidateParent(PWINDOW_OBJECT Child, HRGN ValidRegion) { @@ -46,28 +88,128 @@
while (ParentWindow) { - if (!(ParentWindow->Style & WS_CLIPCHILDREN)) + if (ParentWindow->Style & WS_CLIPCHILDREN) + break; + + if (ParentWindow->UpdateRegion != 0) { - if (ParentWindow->UpdateRegion != 0) + NtGdiCombineRgn(ParentWindow->UpdateRegion, ParentWindow->UpdateRegion, + ValidRegion, RGN_DIFF); + /* FIXME: If the resulting region is empty, remove fake posted paint message */ + } + + ParentWindow = ParentWindow->Parent; + } +} + +/** + * @name IntCalcWindowRgn + * + * Get a window or client region. + */ + +HRGN FASTCALL +IntCalcWindowRgn(PWINDOW_OBJECT Window, BOOL Client) +{ + HRGN hRgnWindow; + UINT RgnType; + + if (Client) + hRgnWindow = UnsafeIntCreateRectRgnIndirect(&Window->ClientRect); + else + hRgnWindow = UnsafeIntCreateRectRgnIndirect(&Window->WindowRect); + + if (Window->WindowRegion != NULL && !(Window->Style & WS_MINIMIZE)) + { + NtGdiOffsetRgn(hRgnWindow, + -Window->WindowRect.left, + -Window->WindowRect.top); + RgnType = NtGdiCombineRgn(hRgnWindow, hRgnWindow, Window->WindowRegion, RGN_AND); + NtGdiOffsetRgn(hRgnWindow, + Window->WindowRect.left, + Window->WindowRect.top); + } + + return hRgnWindow; +} + +/** + * @name IntGetNCUpdateRgn + * + * Get non-client update region of a window and optionally validate it. + * + * @param Window + * Pointer to window to get the NC update region from. + * @param Validate + * Set to TRUE to force validating the NC update region. + * + * @return + * Handle to NC update region. The caller is responsible for deleting + * it. + */ + +HRGN FASTCALL +IntGetNCUpdateRgn(PWINDOW_OBJECT Window, BOOL Validate) +{ + HRGN hRgnNonClient; + HRGN hRgnWindow; + UINT RgnType; + + if (Window->UpdateRegion != NULL && + Window->UpdateRegion != (HRGN)1) + { + hRgnNonClient = NtGdiCreateRectRgn(0, 0, 0, 0); + hRgnWindow = IntCalcWindowRgn(Window, TRUE); + + /* + * If region creation fails it's safe to fallback to whole + * window region. + */ + + if (hRgnNonClient == NULL) + { + return (HRGN)1; + } + + RgnType = NtGdiCombineRgn(hRgnNonClient, Window->UpdateRegion, + hRgnWindow, RGN_DIFF); + if (RgnType == ERROR) + { + NtGdiDeleteObject(hRgnNonClient); + return (HRGN)1; + } + else if (RgnType == NULLREGION) + { + NtGdiDeleteObject(hRgnNonClient); + return NULL; + } + + /* + * Remove the nonclient region from the standard update region if + * we were asked for it. + */ + + if (Validate) + { + if (NtGdiCombineRgn(Window->UpdateRegion, Window->UpdateRegion, + hRgnWindow, RGN_AND) == NULLREGION) { - INT OffsetX, OffsetY; - - /* - * We must offset the child region by the offset of the - * child rect in the parent. - */ - OffsetX = Child->WindowRect.left - ParentWindow->WindowRect.left; - OffsetY = Child->WindowRect.top - ParentWindow->WindowRect.top; - NtGdiOffsetRgn(ValidRegion, OffsetX, OffsetY); - NtGdiCombineRgn(ParentWindow->UpdateRegion, ParentWindow->UpdateRegion, - ValidRegion, RGN_DIFF); - /* FIXME: If the resulting region is empty, remove fake posted paint message */ - NtGdiOffsetRgn(ValidRegion, -OffsetX, -OffsetY); + GDIOBJ_SetOwnership(Window->UpdateRegion, PsGetCurrentProcess()); + NtGdiDeleteObject(Window->UpdateRegion); + Window->UpdateRegion = NULL; + if (!(Window->Flags & WINDOWOBJECT_NEED_INTERNALPAINT)) + MsqDecPaintCountQueue(Window->MessageQueue); } }
- ParentWindow = ParentWindow->Parent; + NtGdiDeleteObject(hRgnWindow); + + return hRgnNonClient; } + else + { + return Window->UpdateRegion; + } }
/* @@ -85,44 +227,37 @@
if (Flags & (RDW_ERASENOW | RDW_UPDATENOW)) { - if (Window->Flags & WINDOWOBJECT_NEED_NCPAINT) + if (Window->UpdateRegion) { - if (Window->NCUpdateRegion) + IntValidateParent(Window, Window->UpdateRegion); + } + + if (Flags & RDW_UPDATENOW) + { + if (Window->UpdateRegion != NULL || + Window->Flags & WINDOWOBJECT_NEED_INTERNALPAINT) { - IntValidateParent(Window, Window->NCUpdateRegion); + co_IntSendMessage(hWnd, WM_PAINT, 0, 0); } - TempRegion = Window->NCUpdateRegion; - if ((HANDLE) 1 != TempRegion && NULL != TempRegion) + } + else + { + if (Window->Flags & WINDOWOBJECT_NEED_NCPAINT) { - GDIOBJ_SetOwnership(TempRegion, PsGetCurrentProcess()); + TempRegion = IntGetNCUpdateRgn(Window, TRUE); + Window->Flags &= ~WINDOWOBJECT_NEED_NCPAINT; + MsqDecPaintCountQueue(Window->MessageQueue); + co_IntSendMessage(hWnd, WM_NCPAINT, (WPARAM)TempRegion, 0); + if ((HANDLE) 1 != TempRegion && NULL != TempRegion) + { + /* NOTE: The region can already be deleted! */ + GDIOBJ_FreeObj(TempRegion, GDI_OBJECT_TYPE_REGION | GDI_OBJECT_TYPE_SILENT); + } } - Window->NCUpdateRegion = NULL; - Window->Flags &= ~WINDOWOBJECT_NEED_NCPAINT; - MsqDecPaintCountQueue(Window->MessageQueue); - co_IntSendMessage(hWnd, WM_NCPAINT, (WPARAM)TempRegion, 0); - if ((HANDLE) 1 != TempRegion && NULL != TempRegion) - { - /* NOTE: The region can already be deleted! */ - GDIOBJ_FreeObj(TempRegion, GDI_OBJECT_TYPE_REGION | GDI_OBJECT_TYPE_SILENT); - } - }
- if (Window->Flags & WINDOWOBJECT_NEED_ERASEBKGND) - { - if (Window->UpdateRegion) + if (Window->Flags & WINDOWOBJECT_NEED_ERASEBKGND) { - /* - * This surely wrong! Why we would want to validate the parent? - * It breaks quite a few things including dummy WM_ERASEBKGND - * implementations that return only TRUE and have corresponding - * WM_PAINT that doesn't paint the whole client area. - * I left the code here so that no one will readd it again! - * - Filip - */ - /* IntValidateParent(Window, Window->UpdateRegion); */ - hDC = UserGetDCEx(Window, 0, DCX_CACHE | DCX_USESTYLE | - DCX_INTERSECTUPDATE); - if (hDC != NULL) + if (Window->UpdateRegion) { if (co_IntSendMessage(hWnd, WM_ERASEBKGND, (WPARAM)hDC, 0)) { @@ -132,22 +267,12 @@ } } } - - if (Flags & RDW_UPDATENOW) - { - if (Window->UpdateRegion != NULL || - Window->Flags & WINDOWOBJECT_NEED_INTERNALPAINT) - { - co_IntSendMessage(hWnd, WM_PAINT, 0, 0); - } - } }
/* * Check that the window is still valid at this point */ - - if (! IntIsWindow(hWnd)) + if (!IntIsWindow(hWnd)) { return; } @@ -156,7 +281,7 @@ * Paint child windows. */ if (!(Flags & RDW_NOCHILDREN) && !(Window->Style & WS_MINIMIZE) && - ((Flags & RDW_ALLCHILDREN) || !(Window->Style & WS_CLIPCHILDREN))) + ((Flags & RDW_ALLCHILDREN) || !(Window->Style & WS_CLIPCHILDREN))) { HWND *List, *phWnd;
@@ -164,13 +289,11 @@ { for (phWnd = List; *phWnd; ++phWnd) { - Window = UserGetWindowObject(*phWnd); + Window = IntGetWindowObject(*phWnd); if (Window && (Window->Style & WS_VISIBLE)) { - UserRefObjectCo(Window); co_IntPaintWindows(Window, Flags); - UserDerefObjectCo(Window); - + ObmDereferenceObject(Window); } } ExFreePool(List); @@ -200,15 +323,18 @@ HRGN hRgnWindow;
hRgnWindow = UnsafeIntCreateRectRgnIndirect(&Window->WindowRect); - NtGdiOffsetRgn(hRgnWindow, - -Window->WindowRect.left, - -Window->WindowRect.top); RgnType = NtGdiCombineRgn(hRgn, hRgn, hRgnWindow, RGN_AND); NtGdiDeleteObject(hRgnWindow); } else { + NtGdiOffsetRgn(hRgn, + -Window->WindowRect.left, + -Window->WindowRect.top); RgnType = NtGdiCombineRgn(hRgn, hRgn, Window->WindowRegion, RGN_AND); + NtGdiOffsetRgn(hRgn, + Window->WindowRect.left, + Window->WindowRect.top); }
/* @@ -279,60 +405,6 @@ }
/* - * Split the nonclient update region. - */ - - if (NULL != Window->UpdateRegion) - { - HRGN hRgnWindow, hRgnNonClient; - - hRgnWindow = UnsafeIntCreateRectRgnIndirect(&Window->ClientRect); - NtGdiOffsetRgn(hRgnWindow, - -Window->WindowRect.left, - -Window->WindowRect.top); - - hRgnNonClient = NtGdiCreateRectRgn(0, 0, 0, 0); - if (NtGdiCombineRgn(hRgnNonClient, Window->UpdateRegion, - hRgnWindow, RGN_DIFF) == NULLREGION) - { - NtGdiDeleteObject(hRgnNonClient); - hRgnNonClient = NULL; - } - else - { - GDIOBJ_SetOwnership(hRgnNonClient, NULL); - } - - /* - * Remove the nonclient region from the standard update region. - */ - if (NtGdiCombineRgn(Window->UpdateRegion, Window->UpdateRegion, - hRgnWindow, RGN_AND) == NULLREGION) - { - GDIOBJ_SetOwnership(Window->UpdateRegion, PsGetCurrentProcess()); - NtGdiDeleteObject(Window->UpdateRegion); - Window->UpdateRegion = NULL; - } - - if (Window->NCUpdateRegion == NULL) - { - Window->NCUpdateRegion = hRgnNonClient; - } - else - { - if(NULL != hRgnNonClient) - { - NtGdiCombineRgn(Window->NCUpdateRegion, Window->NCUpdateRegion, - hRgnNonClient, RGN_OR); - GDIOBJ_SetOwnership(hRgnNonClient, PsGetCurrentProcess()); - NtGdiDeleteObject(hRgnNonClient); - } - } - - NtGdiDeleteObject(hRgnWindow); - } - - /* * Process children if needed */
@@ -358,9 +430,6 @@ */ HRGN hRgnTemp = NtGdiCreateRectRgn(0, 0, 0, 0); NtGdiCombineRgn(hRgnTemp, hRgn, 0, RGN_COPY); - NtGdiOffsetRgn(hRgnTemp, - Window->WindowRect.left - Child->WindowRect.left, - Window->WindowRect.top - Child->WindowRect.top); IntInvalidateWindows(Child, hRgnTemp, Flags); NtGdiDeleteObject(hRgnTemp); } @@ -407,20 +476,16 @@ BOOL FASTCALL IntIsWindowDrawable(PWINDOW_OBJECT Window) { - PWINDOW_OBJECT Wnd = Window; + PWINDOW_OBJECT Wnd;
- do + for (Wnd = Window; Wnd != NULL; Wnd = Wnd->Parent) { if (!(Wnd->Style & WS_VISIBLE) || ((Wnd->Style & WS_MINIMIZE) && (Wnd != Window))) { return FALSE; } - - Wnd = Wnd->Parent; - } - while(Wnd);
return TRUE; } @@ -453,7 +518,7 @@ /* * Step 2. * Transform the parameters UpdateRgn and UpdateRect into - * a region hRgn specified in window coordinates. + * a region hRgn specified in screen coordinates. */
if (Flags & (RDW_INVALIDATE | RDW_VALIDATE)) @@ -461,35 +526,30 @@ if (UpdateRgn != NULL) { hRgn = NtGdiCreateRectRgn(0, 0, 0, 0); - NtGdiCombineRgn(hRgn, UpdateRgn, NULL, RGN_COPY); - NtGdiOffsetRgn(hRgn, - Window->ClientRect.left - Window->WindowRect.left, - Window->ClientRect.top - Window->WindowRect.top); + if (NtGdiCombineRgn(hRgn, UpdateRgn, NULL, RGN_COPY) == NULLREGION) + NtGdiDeleteObject(hRgn); + else + NtGdiOffsetRgn(hRgn, Window->ClientRect.left, Window->ClientRect.top); } - else - if (UpdateRect != NULL) + else if (UpdateRect != NULL) + { + if (!IntGdiIsEmptyRect(UpdateRect)) { hRgn = UnsafeIntCreateRectRgnIndirect((RECT *)UpdateRect); - NtGdiOffsetRgn(hRgn, - Window->ClientRect.left - Window->WindowRect.left, - Window->ClientRect.top - Window->WindowRect.top); + NtGdiOffsetRgn(hRgn, Window->ClientRect.left, Window->ClientRect.top); } - else - if ((Flags & (RDW_INVALIDATE | RDW_FRAME)) == (RDW_INVALIDATE | RDW_FRAME) || - (Flags & (RDW_VALIDATE | RDW_NOFRAME)) == (RDW_VALIDATE | RDW_NOFRAME)) - { - hRgn = UnsafeIntCreateRectRgnIndirect(&Window->WindowRect); - NtGdiOffsetRgn(hRgn, - -Window->WindowRect.left, - -Window->WindowRect.top); - } - else - { - hRgn = UnsafeIntCreateRectRgnIndirect(&Window->ClientRect); - NtGdiOffsetRgn(hRgn, - -Window->WindowRect.left, - -Window->WindowRect.top); - } + } + else if ((Flags & (RDW_INVALIDATE | RDW_FRAME)) == (RDW_INVALIDATE | RDW_FRAME) || + (Flags & (RDW_VALIDATE | RDW_NOFRAME)) == (RDW_VALIDATE | RDW_NOFRAME)) + { + if (!IntGdiIsEmptyRect(&Window->WindowRect)) + hRgn = UnsafeIntCreateRectRgnIndirect(&Window->WindowRect); + } + else + { + if (!IntGdiIsEmptyRect(&Window->ClientRect)) + hRgn = UnsafeIntCreateRectRgnIndirect(&Window->ClientRect); + } }
/* @@ -497,7 +557,8 @@ * Adjust the window update region depending on hRgn and flags. */
- if (Flags & (RDW_INVALIDATE | RDW_VALIDATE | RDW_INTERNALPAINT | RDW_NOINTERNALPAINT)) + if (Flags & (RDW_INVALIDATE | RDW_VALIDATE | RDW_INTERNALPAINT | RDW_NOINTERNALPAINT) && + hRgn != NULL) { IntInvalidateWindows(Window, hRgn, Flags); } @@ -534,84 +595,55 @@ (Window->Flags & WINDOWOBJECT_NEED_NCPAINT)); }
-HWND STDCALL -IntFindWindowToRepaint(HWND hWnd, PW32THREAD Thread) +HWND FASTCALL +IntFindWindowToRepaint(PWINDOW_OBJECT Window, PW32THREAD Thread) { - PWINDOW_OBJECT Window; - PWINDOW_OBJECT Child; - HWND hFoundWnd = NULL; + HWND hChild;
- if (!(Window = UserGetWindowObject(hWnd))) - return NULL; - - if (IntIsWindowDirty(Window) && - IntWndBelongsToThread(Window, Thread)) + while (Window != NULL) { - return hWnd; - } - - for (Child = Window->FirstChild; Child; Child = Child->NextSibling) - { - if (IntIsWindowDirty(Child) && - IntWndBelongsToThread(Child, Thread)) + /* FIXME: Transparent windows. */ + if (IntIsWindowDirty(Window) && + IntWndBelongsToThread(Window, Thread)) { - hFoundWnd = Child->hSelf; - break; + return Window->hSelf; } - }
- if (hFoundWnd == NULL) - { - HWND *List; - INT i; - - List = IntWinListChildren(Window); - if (List != NULL) + if (Window->FirstChild) { - for (i = 0; List[i]; i++) - { - hFoundWnd = IntFindWindowToRepaint(List[i], Thread); - if (hFoundWnd != NULL) - break; - } - ExFreePool(List); + hChild = IntFindWindowToRepaint(Window->FirstChild, Thread); + if (hChild != NULL) + return hChild; } + + Window = Window->NextSibling; }
- return hFoundWnd; + return NULL; }
BOOL FASTCALL IntGetPaintMessage(HWND hWnd, UINT MsgFilterMin, UINT MsgFilterMax, PW32THREAD Thread, MSG *Message, BOOL Remove) { - PWINDOW_OBJECT Window; PUSER_MESSAGE_QUEUE MessageQueue = (PUSER_MESSAGE_QUEUE)Thread->MessageQueue;
- if (!MessageQueue->PaintPosted) + if (!MessageQueue->PaintCount) return FALSE;
if ((MsgFilterMin != 0 || MsgFilterMax != 0) && (MsgFilterMin > WM_PAINT || MsgFilterMax < WM_PAINT)) return FALSE;
- if (hWnd) - Message->hwnd = IntFindWindowToRepaint(hWnd, PsGetWin32Thread()); - else - Message->hwnd = IntFindWindowToRepaint(IntGetDesktopWindow(), PsGetWin32Thread()); + Message->hwnd = IntFindWindowToRepaint(UserGetDesktopWindow(), PsGetWin32Thread());
if (Message->hwnd == NULL) { - if (NULL == hWnd) - { - DPRINT1("PAINTING BUG: Thread marked as containing dirty windows, but no dirty windows found!\n"); - MessageQueue->PaintPosted = 0; - MessageQueue->PaintCount = 0; - } + DPRINT1("PAINTING BUG: Thread marked as containing dirty windows, but no dirty windows found!\n"); return FALSE; }
- if (!(Window = UserGetWindowObject(Message->hwnd))) + if (hWnd != NULL && Message->hwnd != hWnd) return FALSE;
Message->message = WM_PAINT; @@ -700,14 +732,7 @@ { HRGN hRgn;
- if (Window->NCUpdateRegion != (HANDLE)1 && - Window->NCUpdateRegion != NULL) - { - GDIOBJ_SetOwnership(Window->NCUpdateRegion, PsGetCurrentProcess()); - } - hRgn = Window->NCUpdateRegion; - IntValidateParent(Window, Window->NCUpdateRegion); - Window->NCUpdateRegion = NULL; + hRgn = IntGetNCUpdateRgn(Window, FALSE); Window->Flags &= ~WINDOWOBJECT_NEED_NCPAINT; MsqDecPaintCountQueue(Window->MessageQueue); co_IntSendMessage(hWnd, WM_NCPAINT, (WPARAM)hRgn, 0); @@ -720,8 +745,7 @@
RtlZeroMemory(&Ps, sizeof(PAINTSTRUCT));
- Ps.hdc = UserGetDCEx(Window, 0, DCX_INTERSECTUPDATE | DCX_WINDOWPAINT | DCX_USESTYLE); - + Ps.hdc = UserGetDCEx(Window, Window->UpdateRegion, DCX_INTERSECTRGN | DCX_USESTYLE); if (!Ps.hdc) { RETURN( NULL); @@ -730,22 +754,20 @@ if (Window->UpdateRegion != NULL) { MsqDecPaintCountQueue(Window->MessageQueue); - IntValidateParent(Window, Window->UpdateRegion); Rgn = RGNDATA_LockRgn(Window->UpdateRegion); if (NULL != Rgn) { UnsafeIntGetRgnBox(Rgn, &Ps.rcPaint); RGNDATA_UnlockRgn(Rgn); IntGdiOffsetRect(&Ps.rcPaint, - Window->WindowRect.left - Window->ClientRect.left, - Window->WindowRect.top - Window->ClientRect.top); + -Window->ClientRect.left, + -Window->ClientRect.top); } else { IntGetClientRect(Window, &Ps.rcPaint); } GDIOBJ_SetOwnership(Window->UpdateRegion, PsGetCurrentProcess()); - NtGdiDeleteObject(Window->UpdateRegion); Window->UpdateRegion = NULL; } else @@ -755,6 +777,7 @@
IntGetClientRect(Window, &Ps.rcPaint); } + Window->Flags &= ~WINDOWOBJECT_NEED_INTERNALPAINT;
if (Window->Flags & WINDOWOBJECT_NEED_ERASEBKGND) @@ -898,10 +921,7 @@ else { RegionType = NtGdiCombineRgn(hRgn, Window->UpdateRegion, hRgn, RGN_COPY); - NtGdiOffsetRgn( - hRgn, - Window->WindowRect.left - Window->ClientRect.left, - Window->WindowRect.top - Window->ClientRect.top); + NtGdiOffsetRgn(hRgn, -Window->ClientRect.left, -Window->ClientRect.top); }
if (bErase && RegionType != NULLREGION && RegionType != ERROR) _____
Modified: trunk/reactos/subsys/win32k/ntuser/vis.c --- trunk/reactos/subsys/win32k/ntuser/vis.c 2005-09-19 10:04:07 UTC (rev 17930) +++ trunk/reactos/subsys/win32k/ntuser/vis.c 2005-09-19 10:39:26 UTC (rev 17931) @@ -38,37 +38,30 @@
BOOLEAN ClipSiblings) { HRGN VisRgn, ClipRgn; - INT LeftOffset, TopOffset; PWINDOW_OBJECT PreviousWindow, CurrentWindow, CurrentSibling;
if (!(Window->Style & WS_VISIBLE)) { - return NtGdiCreateRectRgn(0, 0, 0, 0); + return NULL; }
if (ClientArea) { - if(!(ClipRgn = VIS_ComputeVisibleRegion(Window, FALSE, ClipChildren, ClipSiblings))) + if (!(ClipRgn = VIS_ComputeVisibleRegion(Window, FALSE, ClipChildren, ClipSiblings))) { - return NtGdiCreateRectRgn(0, 0, 0, 0); + return NULL; } - if(!(VisRgn = UnsafeIntCreateRectRgnIndirect(&Window->ClientRect))) + if (!(VisRgn = UnsafeIntCreateRectRgnIndirect(&Window->ClientRect))) { NtGdiDeleteObject(VisRgn); - return NtGdiCreateRectRgn(0, 0, 0, 0); + return NULL; } - LeftOffset = Window->ClientRect.left - Window->WindowRect.left; - TopOffset = Window->ClientRect.top - Window->WindowRect.top; - NtGdiOffsetRgn(VisRgn, -Window->WindowRect.left, -Window->WindowRect.top); NtGdiCombineRgn(VisRgn, VisRgn, ClipRgn, RGN_AND); NtGdiDeleteObject(ClipRgn); - NtGdiOffsetRgn(VisRgn, -LeftOffset, -TopOffset); return VisRgn; }
VisRgn = UnsafeIntCreateRectRgnIndirect(&Window->WindowRect); - LeftOffset = Window->WindowRect.left; - TopOffset = Window->WindowRect.top;
/* * Walk through all parent windows and for each clip the visble region @@ -83,14 +76,15 @@ if (!(CurrentWindow->Style & WS_VISIBLE)) { NtGdiDeleteObject(VisRgn); - return NtGdiCreateRectRgn(0, 0, 0, 0); + return NULL; } + ClipRgn = UnsafeIntCreateRectRgnIndirect(&CurrentWindow->ClientRect); NtGdiCombineRgn(VisRgn, VisRgn, ClipRgn, RGN_AND); NtGdiDeleteObject(ClipRgn);
if ((PreviousWindow->Style & WS_CLIPSIBLINGS) || - (PreviousWindow == Window && ClipSiblings)) + (PreviousWindow == Window && ClipSiblings)) { CurrentSibling = CurrentWindow->FirstChild; while (CurrentSibling != NULL && CurrentSibling != PreviousWindow) @@ -99,7 +93,7 @@ { ClipRgn = UnsafeIntCreateRectRgnIndirect(&CurrentSibling->WindowRect); /* Combine it with the window region if available */ - if(CurrentSibling->WindowRegion && !(CurrentSibling->Style & WS_MINIMIZE)) + if (CurrentSibling->WindowRegion && !(CurrentSibling->Style & WS_MINIMIZE)) { NtGdiOffsetRgn(ClipRgn, -CurrentSibling->WindowRect.left, -CurrentSibling->WindowRect.top); NtGdiCombineRgn(ClipRgn, ClipRgn, CurrentSibling->WindowRegion, RGN_AND); @@ -125,7 +119,7 @@ { ClipRgn = UnsafeIntCreateRectRgnIndirect(&CurrentWindow->WindowRect); /* Combine it with the window region if available */ - if(CurrentWindow->WindowRegion && !(CurrentWindow->Style & WS_MINIMIZE)) + if (CurrentWindow->WindowRegion && !(CurrentWindow->Style & WS_MINIMIZE)) { NtGdiOffsetRgn(ClipRgn, -CurrentWindow->WindowRect.left, -CurrentWindow->WindowRect.top); NtGdiCombineRgn(ClipRgn, ClipRgn, CurrentWindow->WindowRegion, RGN_AND); @@ -138,15 +132,13 @@ } }
- if(Window->WindowRegion && !(Window->Style & WS_MINIMIZE)) + if (Window->WindowRegion && !(Window->Style & WS_MINIMIZE)) { - NtGdiOffsetRgn(VisRgn, -LeftOffset, -TopOffset); + NtGdiOffsetRgn(VisRgn, -Window->WindowRect.left, -Window->WindowRect.top); NtGdiCombineRgn(VisRgn, VisRgn, Window->WindowRegion, RGN_AND); - return VisRgn; + NtGdiOffsetRgn(VisRgn, Window->WindowRect.left, Window->WindowRect.top); }
- NtGdiOffsetRgn(VisRgn, -LeftOffset, -TopOffset); - return VisRgn; }
_____
Modified: trunk/reactos/subsys/win32k/ntuser/windc.c --- trunk/reactos/subsys/win32k/ntuser/windc.c 2005-09-19 10:04:07 UTC (rev 17930) +++ trunk/reactos/subsys/win32k/ntuser/windc.c 2005-09-19 10:39:26 UTC (rev 17931) @@ -34,8 +34,6 @@
#define NDEBUG #include <debug.h>
-#define DCX_USESTYLE 0x10000 - /* GLOBALS *******************************************************************/
/* NOTE - I think we should store this per window station (including gdi objects) */ @@ -187,7 +185,7 @@ STATIC VOID FASTCALL DceDeleteClipRgn(DCE* Dce) { - Dce->DCXFlags &= ~(DCX_EXCLUDERGN | DCX_INTERSECTRGN | DCX_WINDOWPAINT); + Dce->DCXFlags &= ~(DCX_EXCLUDERGN | DCX_INTERSECTRGN);
if (Dce->DCXFlags & DCX_KEEPCLIPRGN ) { @@ -216,7 +214,7 @@ /* restore previous visible region */
if ((dce->DCXFlags & (DCX_INTERSECTRGN | DCX_EXCLUDERGN)) && - (dce->DCXFlags & (DCX_CACHE | DCX_WINDOWPAINT)) ) + (dce->DCXFlags & DCX_CACHE) ) { DceDeleteClipRgn(dce); } @@ -273,23 +271,6 @@ { hRgnVisible = NtGdiCreateRectRgn(0, 0, 0, 0); } - else - { - if (0 == (Flags & DCX_WINDOW)) - { - NtGdiOffsetRgn( - hRgnVisible, - Parent->ClientRect.left - Window->ClientRect.left, - Parent->ClientRect.top - Window->ClientRect.top); - } - else - { - NtGdiOffsetRgn( - hRgnVisible, - Parent->WindowRect.left - Window->WindowRect.left, - Parent->WindowRect.top - Window->WindowRect.top); - } - } } else if (Window == NULL) { @@ -482,7 +463,7 @@ }
Dce->hwndCurrent = (Window ? Window->hSelf : NULL); - Dce->DCXFlags = DcxFlags | (Flags & DCX_WINDOWPAINT) | DCX_DCEBUSY; + Dce->DCXFlags = DcxFlags | DCX_DCEBUSY;
if (0 == (Flags & (DCX_EXCLUDERGN | DCX_INTERSECTRGN)) && NULL != ClipRegion) { @@ -498,21 +479,8 @@
if (0 != (Flags & DCX_INTERSECTUPDATE) && NULL == ClipRegion) { - Dce->hClipRgn = NtGdiCreateRectRgn(0, 0, 0, 0); - if (Dce->hClipRgn && Window->UpdateRegion) - { - GDIOBJ_SetOwnership(Dce->hClipRgn, NULL); - NtGdiCombineRgn(Dce->hClipRgn, Window->UpdateRegion, NULL, RGN_COPY); - if(Window->WindowRegion && !(Window->Style & WS_MINIMIZE)) - NtGdiCombineRgn(Dce->hClipRgn, Dce->hClipRgn, Window->WindowRegion, RGN_AND); - if (!(Flags & DCX_WINDOW)) - { - NtGdiOffsetRgn(Dce->hClipRgn, - Window->WindowRect.left - Window->ClientRect.left, - Window->WindowRect.top - Window->ClientRect.top); - } - } - Flags |= DCX_INTERSECTRGN; + Flags |= DCX_INTERSECTRGN | DCX_KEEPCLIPRGN; + ClipRegion = Window->UpdateRegion; }
if (ClipRegion == (HRGN) 1) @@ -521,40 +489,17 @@ { Dce->hClipRgn = UnsafeIntCreateRectRgnIndirect(&Window->ClientRect); GDIOBJ_SetOwnership(Dce->hClipRgn, NULL); - if(!Window->WindowRegion || (Window->Style & WS_MINIMIZE)) - { - NtGdiOffsetRgn(Dce->hClipRgn, -Window->ClientRect.left, -Window->ClientRect.top); - } - else - { - NtGdiOffsetRgn(Dce->hClipRgn, -Window->WindowRect.left, -Window->WindowRect.top); - NtGdiCombineRgn(Dce->hClipRgn, Dce->hClipRgn, Window->WindowRegion, RGN_AND); - NtGdiOffsetRgn(Dce->hClipRgn, -(Window->ClientRect.left - Window->WindowRect.left), - -(Window->ClientRect.top - Window->WindowRect.top)); - } } else { Dce->hClipRgn = UnsafeIntCreateRectRgnIndirect(&Window->WindowRect); GDIOBJ_SetOwnership(Dce->hClipRgn, NULL); - NtGdiOffsetRgn(Dce->hClipRgn, -Window->WindowRect.left, - -Window->WindowRect.top); - if(Window->WindowRegion && !(Window->Style & WS_MINIMIZE)) - NtGdiCombineRgn(Dce->hClipRgn, Dce->hClipRgn, Window->WindowRegion, RGN_AND); } } - else if (NULL != ClipRegion) + else if (ClipRegion != NULL) { - Dce->hClipRgn = NtGdiCreateRectRgn(0, 0, 0, 0); - if (Dce->hClipRgn) - { - GDIOBJ_SetOwnership(Dce->hClipRgn, NULL); - if(!Window->WindowRegion || (Window->Style & WS_MINIMIZE)) - NtGdiCombineRgn(Dce->hClipRgn, ClipRegion, NULL, RGN_COPY); - else - NtGdiCombineRgn(Dce->hClipRgn, ClipRegion, Window->WindowRegion, RGN_AND); - } - NtGdiDeleteObject(ClipRegion); + Dce->hClipRgn = ClipRegion; + GDIOBJ_SetOwnership(Dce->hClipRgn, NULL); }
DceSetDrawable(Window, Dce->hDC, Flags, UpdateClipOrigin); @@ -705,9 +650,9 @@ }
NtGdiDeleteDC(dce->hDC); + GDIOBJ_SetOwnership(dce->hClipRgn, PsGetCurrentProcess()); if (dce->hClipRgn && ! (dce->DCXFlags & DCX_KEEPCLIPRGN)) { - GDIOBJ_SetOwnership(dce->hClipRgn, PsGetCurrentProcess()); NtGdiDeleteObject(dce->hClipRgn); [truncated at 1000 lines; 106 more skipped]