From 7b7b6088220ae2e842997062dba389ca0372ea34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9=20van=20Geldorp?= Date: Mon, 2 Feb 2004 22:09:05 +0000 Subject: [PATCH] Update DC when moving a window. Fixes bug #5. Based on a patch by Filip Navara. svn path=/trunk/; revision=8003 --- reactos/subsys/win32k/include/dce.h | 1 + reactos/subsys/win32k/ntuser/windc.c | 153 +++++++++++++++++--------- reactos/subsys/win32k/ntuser/winpos.c | 4 +- 3 files changed, 107 insertions(+), 51 deletions(-) diff --git a/reactos/subsys/win32k/include/dce.h b/reactos/subsys/win32k/include/dce.h index c3e423ea910..a13a0a9b6fc 100644 --- a/reactos/subsys/win32k/include/dce.h +++ b/reactos/subsys/win32k/include/dce.h @@ -54,5 +54,6 @@ HWND FASTCALL IntWindowFromDC(HDC hDc); PDCE FASTCALL DceFreeDCE(PDCE dce); void FASTCALL DceFreeWindowDCE(PWINDOW_OBJECT Window); void FASTCALL DceEmptyCache(void); +VOID FASTCALL DceMoveDCE(HWND hwnd, int X, int Y); #endif /* _WIN32K_DCE_H */ diff --git a/reactos/subsys/win32k/ntuser/windc.c b/reactos/subsys/win32k/ntuser/windc.c index 0cb063cdc13..3e4ac4357ba 100644 --- a/reactos/subsys/win32k/ntuser/windc.c +++ b/reactos/subsys/win32k/ntuser/windc.c @@ -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.51 2004/01/17 15:18:25 navaraf Exp $ +/* $Id: windc.c,v 1.52 2004/02/02 22:09:05 gvg Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -227,6 +227,63 @@ DceReleaseDC(DCE* dce) return 1; } +STATIC VOID FASTCALL +DceUpdateVisRgn(DCE *Dce, PWINDOW_OBJECT Window, ULONG Flags) +{ + HANDLE hRgnVisible = NULL; + ULONG DcxFlags; + + if (Flags & DCX_PARENTCLIP) + { + PWINDOW_OBJECT Parent; + + Parent = Window->Parent; + + if (Window->Style & WS_VISIBLE /*&& + !(Parent->Style & WS_MINIMIZE)*/) + { + if (Parent->Style & WS_CLIPSIBLINGS) + { + DcxFlags = DCX_CLIPSIBLINGS | + (Flags & ~(DCX_CLIPCHILDREN | DCX_WINDOW)); + } + else + { + DcxFlags = Flags & + ~(DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN | DCX_WINDOW); + } + hRgnVisible = DceGetVisRgn(Parent->Self, DcxFlags, + Window->Self, Flags); + } + else + { + hRgnVisible = NtGdiCreateRectRgn(0, 0, 0, 0); + } + } + else + { + hRgnVisible = DceGetVisRgn(NULL != Window ? Window->Self : NULL, Flags, 0, 0); + } + + if (0 != (Flags & DCX_INTERSECTRGN)) + { + NtGdiCombineRgn(hRgnVisible, hRgnVisible, Dce->hClipRgn, RGN_AND); + } + + if (0 != (Flags & DCX_EXCLUDERGN)) + { + NtGdiCombineRgn(hRgnVisible, hRgnVisible, Dce->hClipRgn, RGN_DIFF); + } + + Dce->DCXFlags &= ~DCX_DCEDIRTY; + NtGdiSelectVisRgn(Dce->hDC, hRgnVisible); + + if (hRgnVisible != NULL) + { + NtGdiDeleteObject(hRgnVisible); + } +} + HDC STDCALL NtUserGetDCEx(HWND hWnd, HANDLE ClipRegion, ULONG Flags) { @@ -235,7 +292,6 @@ NtUserGetDCEx(HWND hWnd, HANDLE ClipRegion, ULONG Flags) DCE* Dce; BOOL UpdateVisRgn = TRUE; BOOL UpdateClipOrigin = FALSE; - HANDLE hRgnVisible = NULL; if (NULL == hWnd) { @@ -435,56 +491,9 @@ NtUserGetDCEx(HWND hWnd, HANDLE ClipRegion, ULONG Flags) if (UpdateVisRgn) { - if (Flags & DCX_PARENTCLIP) - { - PWINDOW_OBJECT Parent; - - Parent = Window->Parent; - - if (Window->Style & WS_VISIBLE /*&& - !(Parent->Style & WS_MINIMIZE)*/) - { - if (Parent->Style & WS_CLIPSIBLINGS) - { - DcxFlags = DCX_CLIPSIBLINGS | - (Flags & ~(DCX_CLIPCHILDREN | DCX_WINDOW)); - } - else - { - DcxFlags = Flags & - ~(DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN | DCX_WINDOW); - } - hRgnVisible = DceGetVisRgn(Parent->Self, DcxFlags, - Window->Self, Flags); - } - else - { - hRgnVisible = NtGdiCreateRectRgn(0, 0, 0, 0); - } - } - else - { - hRgnVisible = DceGetVisRgn(hWnd, Flags, 0, 0); - } - - if (0 != (Flags & DCX_INTERSECTRGN)) - { - NtGdiCombineRgn(hRgnVisible, hRgnVisible, Dce->hClipRgn, RGN_AND); - } - - if (0 != (Flags & DCX_EXCLUDERGN)) - { - NtGdiCombineRgn(hRgnVisible, hRgnVisible, Dce->hClipRgn, RGN_DIFF); - } - - Dce->DCXFlags &= ~DCX_DCEDIRTY; - NtGdiSelectVisRgn(Dce->hDC, hRgnVisible); + DceUpdateVisRgn(Dce, Window, Flags); } - if (hRgnVisible != NULL) - { - NtGdiDeleteObject(hRgnVisible); - } if (NULL != Window) { IntReleaseWindowObject(Window); @@ -662,4 +671,48 @@ DceEmptyCache() } } +VOID FASTCALL DceMoveDCE(HWND hwnd, int X, int Y) +{ + DCE *pDCE; + PWINDOW_OBJECT Window = IntGetWindowObject(hwnd); + PDC dc; + + if (NULL == Window) + { + return; + } + + pDCE = FirstDce; + while (pDCE) + { + if (pDCE->DCXFlags & DCX_DCEEMPTY) + { + pDCE = pDCE->next; + continue; + } + if (pDCE->hwndCurrent == hwnd) + { + dc = DC_LockDc(pDCE->hDC); + if (dc == NULL) + { + pDCE = pDCE->next; + continue; + } + dc->w.DCOrgX += X; + dc->w.DCOrgY += Y; + NtGdiOffsetRgn(dc->w.hClipRgn, X, Y); + DC_UnlockDc(pDCE->hDC); + NtGdiOffsetRgn(pDCE->hClipRgn, X, Y); + + DceUpdateVisRgn(pDCE, Window, pDCE->DCXFlags); + IntReleaseWindowObject(Window); + + pDCE->DCXFlags |= DCX_DCEDIRTY; + } + pDCE = pDCE->next; + } + + IntReleaseWindowObject(Window); +} + /* EOF */ diff --git a/reactos/subsys/win32k/ntuser/winpos.c b/reactos/subsys/win32k/ntuser/winpos.c index fc093f85d32..2aa13143e53 100644 --- a/reactos/subsys/win32k/ntuser/winpos.c +++ b/reactos/subsys/win32k/ntuser/winpos.c @@ -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.84 2004/01/31 19:56:14 weiden Exp $ +/* $Id: winpos.c,v 1.85 2004/02/02 22:09:05 gvg Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -599,6 +599,8 @@ WinPosInternalMoveWindow(PWINDOW_OBJECT Window, INT MoveX, INT MoveY) Window->ClientRect.top += MoveY; Window->ClientRect.bottom += MoveY; + DceMoveDCE(Window->Self, MoveX, MoveY); + ExAcquireFastMutexUnsafe(&Window->ChildrenListLock); Child = Window->FirstChild; while (Child)