From 98006d367a7b51a4b6e4db11606ef0f23cf52389 Mon Sep 17 00:00:00 2001 From: James Tabor Date: Sat, 23 Jan 2010 23:55:32 +0000 Subject: [PATCH] [Win32k] - Fixed DCE masks, clipping and added support for mirror and process owned dce. - Reference: http://www.reactos.org/archives/public/ros-dev/2008-July/010498.html http://www.reactos.org/archives/public/ros-dev/2008-July/010499.html svn path=/trunk/; revision=45221 --- reactos/include/reactos/win32k/ntuser.h | 2 + .../subsystems/win32/win32k/ntuser/windc.c | 118 +++++++++--------- 2 files changed, 64 insertions(+), 56 deletions(-) diff --git a/reactos/include/reactos/win32k/ntuser.h b/reactos/include/reactos/win32k/ntuser.h index 21616a3fc6a..e281e90a472 100644 --- a/reactos/include/reactos/win32k/ntuser.h +++ b/reactos/include/reactos/win32k/ntuser.h @@ -775,6 +775,8 @@ typedef struct _USERCONNECT // #define DCX_USESTYLE 0x00010000 #define DCX_KEEPCLIPRGN 0x00040000 +#define DCX_KEEPLAYOUT 0x40000000 +#define DCX_PROCESSOWNED 0x80000000 // // Non SDK Queue message types. diff --git a/reactos/subsystems/win32/win32k/ntuser/windc.c b/reactos/subsystems/win32/win32k/ntuser/windc.c index 2b8e198be5a..8be75da50c0 100644 --- a/reactos/subsystems/win32/win32k/ntuser/windc.c +++ b/reactos/subsystems/win32/win32k/ntuser/windc.c @@ -14,6 +14,8 @@ #define NDEBUG #include +int FASTCALL CLIPPING_UpdateGCRegion(DC* Dc); + /* GLOBALS *******************************************************************/ /* NOTE - I think we should store this per window station (including gdi objects) */ @@ -22,7 +24,9 @@ static PDCE FirstDce = NULL; //static INT DCECount = 0; // Count of DCE in system. #define DCX_CACHECOMPAREMASK (DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN | \ - DCX_CACHE | DCX_WINDOW | DCX_PARENTCLIP) + DCX_NORESETATTRS | DCX_LOCKWINDOWUPDATE | \ + DCX_LAYEREDWIN | DCX_CACHE | DCX_WINDOW | \ + DCX_PARENTCLIP) /* FUNCTIONS *****************************************************************/ @@ -58,9 +62,9 @@ DceGetVisRgn(PWINDOW_OBJECT Window, ULONG Flags, HWND hWndChild, ULONG CFlags) HRGN VisRgn; VisRgn = VIS_ComputeVisibleRegion( Window, - 0 == (Flags & DCX_WINDOW), - 0 != (Flags & DCX_CLIPCHILDREN), - 0 != (Flags & DCX_CLIPSIBLINGS)); + 0 == (Flags & DCX_WINDOW), + 0 != (Flags & DCX_CLIPCHILDREN), + 0 != (Flags & DCX_CLIPSIBLINGS)); if (VisRgn == NULL) VisRgn = IntSysCreateRectRgn(0, 0, 0, 0); @@ -68,7 +72,6 @@ DceGetVisRgn(PWINDOW_OBJECT Window, ULONG Flags, HWND hWndChild, ULONG CFlags) return VisRgn; } - PDCE FASTCALL DceAllocDCE(PWINDOW_OBJECT Window OPTIONAL, DCE_TYPE Type) { @@ -94,7 +97,6 @@ DceAllocDCE(PWINDOW_OBJECT Window OPTIONAL, DCE_TYPE Type) pDce->hrgnClip = NULL; pDce->hrgnClipPublic = NULL; pDce->hrgnSavedVis = NULL; - pDce->ptiOwner = NULL; pDce->ppiOwner = NULL; KeEnterCriticalRegion(); @@ -111,13 +113,13 @@ DceAllocDCE(PWINDOW_OBJECT Window OPTIONAL, DCE_TYPE Type) if (Type == DCE_WINDOW_DC || Type == DCE_CLASS_DC) //Window DCE have ownership. { - pDce->ptiOwner = GetW32ThreadInfo(); - pDce->ppiOwner = pDce->ptiOwner->ppi; + pDce->ptiOwner = GetW32ThreadInfo(); } else { DPRINT("FREE DCATTR!!!! NOT DCE_WINDOW_DC!!!!! hDC-> %x\n", pDce->hDC); IntGdiSetDCOwnerEx( pDce->hDC, GDI_OBJ_HMGR_NONE, FALSE); + pDce->ptiOwner = NULL; } if (Type == DCE_CACHE_DC) @@ -140,8 +142,10 @@ DceAllocDCE(PWINDOW_OBJECT Window OPTIONAL, DCE_TYPE Type) } static VOID APIENTRY -DceSetDrawable(PWINDOW_OBJECT Window OPTIONAL, HDC hDC, ULONG Flags, - BOOL SetClipOrigin) +DceSetDrawable( PWINDOW_OBJECT Window OPTIONAL, + HDC hDC, + ULONG Flags, + BOOL SetClipOrigin) { PWND Wnd; DC *dc = DC_LockDc(hDC); @@ -302,8 +306,7 @@ noparent: hRgnVisible = IntSysCreateRectRgn(0, 0, 0, 0); } } - - if (Flags & DCX_EXCLUDERGN && Dce->hrgnClip != NULL) + else if (Flags & DCX_EXCLUDERGN && Dce->hrgnClip != NULL) { NtGdiCombineRgn(hRgnVisible, hRgnVisible, Dce->hrgnClip, RGN_DIFF); } @@ -328,10 +331,10 @@ UserGetDCEx(PWINDOW_OBJECT Window OPTIONAL, HANDLE ClipRegion, ULONG Flags) PWINDOW_OBJECT Parent; ULONG DcxFlags; DCE* Dce = NULL; - BOOL UpdateVisRgn = TRUE; BOOL UpdateClipOrigin = FALSE; PWND Wnd = NULL; - HDC hDC = NULL; + HDC hDC = NULL; + PPROCESSINFO ppi; if (NULL == Window) { @@ -382,6 +385,12 @@ UserGetDCEx(PWINDOW_OBJECT Window OPTIONAL, HANDLE ClipRegion, ULONG Flags) { Flags |= DCX_CLIPCHILDREN; } + /* If minized with icon in the set, we are forced to be cheap! */ + if (Wnd->style & WS_MINIMIZE && + Wnd->pcls->hIcon) + { + Flags |= DCX_CACHE; + } } else { @@ -458,9 +467,6 @@ UserGetDCEx(PWINDOW_OBJECT Window OPTIONAL, HANDLE ClipRegion, ULONG Flags) else if (Dce->hwndCurrent == (Window ? Window->hSelf : NULL) && ((Dce->DCXFlags & DCX_CACHECOMPAREMASK) == DcxFlags)) { -#if 0 /* FIXME */ - UpdateVisRgn = FALSE; -#endif UpdateClipOrigin = TRUE; break; } @@ -485,31 +491,19 @@ UserGetDCEx(PWINDOW_OBJECT Window OPTIONAL, HANDLE ClipRegion, ULONG Flags) Dce = FirstDce; do { // Check for Window handle than HDC match for CLASS. - if ((Dce->hwndCurrent == Window->hSelf) || (Dce->hDC == hDC)) break; + if ((Dce->hwndCurrent == Window->hSelf) || + (Dce->hDC == hDC)) + break; Dce = (PDCE)Dce->List.Flink; } while (Dce != FirstDce); KeLeaveCriticalRegion(); - DPRINT("DCX:Flags -> %x:%x\n",Dce->DCXFlags & DCX_CACHE, Flags & DCX_CACHE); - - if (Dce->hwndCurrent == Window->hSelf) + if ( (Flags & (DCX_INTERSECTRGN|DCX_EXCLUDERGN)) && + (Dce->DCXFlags & (DCX_INTERSECTRGN|DCX_EXCLUDERGN)) ) { - DPRINT("Owned DCE!\n"); - UpdateVisRgn = FALSE; /* updated automatically, via DCHook() */ + DceDeleteClipRgn(Dce); } - else - { - DPRINT("Owned/Class DCE\n"); - /* we should free dce->clip_rgn here, but Windows apparently doesn't */ - Dce->DCXFlags &= ~(DCX_EXCLUDERGN | DCX_INTERSECTRGN); - Dce->hrgnClip = NULL; - } - -#if 1 /* FIXME */ - UpdateVisRgn = TRUE; -#endif } - // First time use hax, need to use DceAllocDCE during window display init. if (NULL == Dce) { @@ -523,23 +517,24 @@ UserGetDCEx(PWINDOW_OBJECT Window OPTIONAL, HANDLE ClipRegion, ULONG Flags) /* FIXME: Handle error */ } - if (!(Flags & (DCX_EXCLUDERGN | DCX_INTERSECTRGN)) && ClipRegion) - { - if (!(Flags & DCX_KEEPCLIPRGN)) - REGION_FreeRgnByHandle(ClipRegion); - ClipRegion = NULL; - } - -#if 0 - if (NULL != Dce->hrgnClip) - { - DceDeleteClipRgn(Dce); - } -#endif - Dce->DCXFlags = Flags | DCX_DCEBUSY; - if (0 != (Flags & DCX_INTERSECTUPDATE) && NULL == ClipRegion) + /* + Bump it up! This prevents the random errors in wine dce tests and with + proper bits set in DCX_CACHECOMPAREMASK. + Reference: + http://www.reactos.org/archives/public/ros-dev/2008-July/010498.html + http://www.reactos.org/archives/public/ros-dev/2008-July/010499.html + */ + if ((Dce != FirstDce)) + { + RemoveEntryList(&Dce->List); + InsertHeadList(&FirstDce->List, &Dce->List); + FirstDce = Dce; + } + + /* Introduced in rev 6691 and modified later. */ + if ( (Flags & DCX_INTERSECTUPDATE) && !ClipRegion ) { Flags |= DCX_INTERSECTRGN | DCX_KEEPCLIPRGN; Dce->DCXFlags |= DCX_INTERSECTRGN | DCX_KEEPCLIPRGN; @@ -565,10 +560,7 @@ UserGetDCEx(PWINDOW_OBJECT Window OPTIONAL, HANDLE ClipRegion, ULONG Flags) DceSetDrawable(Window, Dce->hDC, Flags, UpdateClipOrigin); - // if (UpdateVisRgn) - { - DceUpdateVisRgn(Dce, Window, Flags); - } + DceUpdateVisRgn(Dce, Window, Flags); if (Dce->DCXFlags & DCX_CACHE) { @@ -576,8 +568,23 @@ UserGetDCEx(PWINDOW_OBJECT Window OPTIONAL, HANDLE ClipRegion, ULONG Flags) // Need to set ownership so Sync dcattr will work. IntGdiSetDCOwnerEx( Dce->hDC, GDI_OBJ_HMGR_POWNED, FALSE); Dce->ptiOwner = GetW32ThreadInfo(); // Set the temp owning - Dce->ppiOwner = Dce->ptiOwner->ppi; } + + if ( Wnd && + Wnd->ExStyle & WS_EX_LAYOUTRTL && + !(Flags & DCX_KEEPLAYOUT) ) + { + NtGdiSetLayout(Dce->hDC, -1, LAYOUT_RTL); + } + + if (Dce->DCXFlags & DCX_PROCESSOWNED) + { + ppi = PsGetCurrentProcessWin32Process(); + ppi->W32PF_flags |= W32PF_OWNDCCLEANUP; + Dce->ptiOwner = NULL; + Dce->ppiOwner = ppi; + } + return(Dce->hDC); } @@ -726,7 +733,6 @@ DceResetActiveDCEs(PWINDOW_OBJECT Window) } if (NULL != dc->rosdc.hClipRgn) { - int FASTCALL CLIPPING_UpdateGCRegion(DC* Dc); NtGdiOffsetRgn(dc->rosdc.hClipRgn, DeltaX, DeltaY); CLIPPING_UpdateGCRegion(dc); }