Author: fireball Date: Sun Apr 25 15:28:14 2010 New Revision: 47014
URL: http://svn.reactos.org/svn/reactos?rev=47014&view=rev Log: - WINENT.DRV: Remove bit copying, it's a job of SWM. - SWM: Create a screen DC, and copy window's contents when changing position (significantly faster than doing it from winent.drv, not to say that doing so without interaction with a window manager is not possible). - SWM: Invalidate areas after changing moving a window or changing its size. - GDIOBJ: Add a missing space for code beautification. See issue #5237 for more details.
Modified: branches/arwinss/reactos/dll/win32/winent.drv/userdrv.c branches/arwinss/reactos/subsystems/win32/win32k/gre/gdiobj.c branches/arwinss/reactos/subsystems/win32/win32k/swm/winman.c
Modified: branches/arwinss/reactos/dll/win32/winent.drv/userdrv.c URL: http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/dll/win32/winent... ============================================================================== --- branches/arwinss/reactos/dll/win32/winent.drv/userdrv.c [iso-8859-1] (original) +++ branches/arwinss/reactos/dll/win32/winent.drv/userdrv.c [iso-8859-1] Sun Apr 25 15:28:14 2010 @@ -83,23 +83,6 @@ else RedrawWindow( data->hwnd, NULL, rgn, RDW_INVALIDATE | RDW_ERASE | RDW_ALLCHILDREN ); DeleteObject( rgn ); } -} - -void swm_move_whole_window( struct ntdrv_win_data *data, const RECT *old_rect ) -{ - HDC hdc_src, hdc_dst; - HWND parent; - - parent = GetAncestor( data->hwnd, GA_PARENT ); - hdc_src = GetDCEx( parent, 0, DCX_CACHE ); - hdc_dst = GetDCEx( data->hwnd, 0, DCX_CACHE | DCX_WINDOW ); - - BitBlt( hdc_dst, 0, 0, - data->whole_rect.right - data->whole_rect.left, data->whole_rect.bottom - data->whole_rect.top, - hdc_src, old_rect->left, old_rect->top, SRCCOPY ); - - ReleaseDC( data->hwnd, hdc_dst ); - ReleaseDC( parent, hdc_src ); }
HKL CDECL RosDrv_ActivateKeyboardLayout( HKL layout, UINT flags ) @@ -954,10 +937,8 @@ /* Sync position change */ if (!(swp_flags & SWP_NOREDRAW)) // HACK: When removing this, explorer's start menu starts to appear partially. Investigate! { + /* SWM: Change windows position */ SwmPosChanged(hwnd, &data->whole_rect, &old_whole_rect, insert_after, swp_flags); - - /* SWM: Move whole window bits */ - swm_move_whole_window( data, &old_whole_rect ); }
/* Pass show/hide information to the window manager */
Modified: branches/arwinss/reactos/subsystems/win32/win32k/gre/gdiobj.c URL: http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/subsystems/win32... ============================================================================== --- branches/arwinss/reactos/subsystems/win32/win32k/gre/gdiobj.c [iso-8859-1] (original) +++ branches/arwinss/reactos/subsystems/win32/win32k/gre/gdiobj.c [iso-8859-1] Sun Apr 25 15:28:14 2010 @@ -51,7 +51,7 @@ {0, 0, 0, NULL}, /* 02 reserved entry */ {0, 0, 0, NULL}, /* 03 reserved entry */ {0, 0, 0, NULL}, /* 04 reserved entry */ - {0, sizeof(SURFACE), TAG_SURFOBJ, SURFACE_Cleanup}, /* 05 SURFACE */ + {0, sizeof(SURFACE), TAG_SURFOBJ, SURFACE_Cleanup}, /* 05 SURFACE */ {0, 0, 0, NULL}, /* 06 reserved entry */ {0, 0, 0, NULL}, /* 07 reserved entry */ {0, sizeof(PALETTE), TAG_PALETTE, GDI_CleanupDummy}, /* 08 PAL */
Modified: branches/arwinss/reactos/subsystems/win32/win32k/swm/winman.c URL: http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/subsystems/win32... ============================================================================== --- branches/arwinss/reactos/subsystems/win32/win32k/swm/winman.c [iso-8859-1] (original) +++ branches/arwinss/reactos/subsystems/win32/win32k/swm/winman.c [iso-8859-1] Sun Apr 25 15:28:14 2010 @@ -34,6 +34,7 @@
LIST_ENTRY SwmWindows; ERESOURCE SwmLock; +HDC SwmDc; /* Screen DC for copying operations */
/* FUNCTIONS *****************************************************************/
@@ -53,6 +54,23 @@ /* Release user resource */ ExReleaseResourceLite(&SwmLock); KeLeaveCriticalRegion(); +} + +VOID +NTAPI +SwmCreateScreenDc() +{ + ROS_DCINFO RosDc; + + /* Create the display DC */ + RtlZeroMemory(&RosDc, sizeof(ROS_DCINFO)); + RosDc.dwType = OBJ_DC; + SwmDc = (HDC)0; + RosGdiCreateDC(&RosDc, &SwmDc, NULL, NULL, NULL, NULL); + RosGdiSetDeviceClipping(SwmDc, 0, NULL, NULL); + + /* Make it global */ + GDIOBJ_SetOwnership(SwmDc, NULL); }
VOID @@ -533,6 +551,18 @@
VOID NTAPI +SwmCopyBits(const RECT *WindowRect, const RECT *OldRect) +{ + /* Lazily create a global screen DC */ + if (!SwmDc) SwmCreateScreenDc(); + + /* Copy bits */ + RosGdiBitBlt(SwmDc, WindowRect->left, WindowRect->top, WindowRect->right - WindowRect->left, + WindowRect->bottom - WindowRect->top, SwmDc, OldRect->left, OldRect->top, SRCCOPY); +} + +VOID +NTAPI SwmPosChanging(HWND hWnd, const RECT *WindowRect) { } @@ -542,6 +572,10 @@ SwmPosChanged(HWND hWnd, const RECT *WindowRect, const RECT *OldRect, HWND hWndAfter, UINT SwpFlags) { PSWM_WINDOW SwmWin, SwmPrev; + LONG Width, Height, OldWidth, OldHeight; + BOOLEAN IsMove = FALSE; + struct region *OldRegion, *DiffRegion; + rectangle_t OldRectSafe;
/* Acquire the lock */ SwmAcquire(); @@ -553,6 +587,25 @@ /* Release the lock */ SwmRelease(); return; + } + + /* Save parameters */ + OldRectSafe.left = OldRect->left; OldRectSafe.top = OldRect->top; + OldRectSafe.right = OldRect->right; OldRectSafe.bottom = OldRect->bottom; + + Width = WindowRect->right - WindowRect->left; + Height = WindowRect->bottom - WindowRect->top; + + OldWidth = OldRect->right - OldRect->left; + OldHeight = OldRect->bottom - OldRect->top; + + /* Detect if it's a move without resizing */ + if ((WindowRect->top != OldRect->top || + WindowRect->left != OldRect->left) && + Width == OldWidth && + Height == OldHeight) + { + IsMove = TRUE; }
/* Check if window really moved anywhere (origin, size or z order) */ @@ -590,6 +643,36 @@
/* Recalculate all clipping */ SwmClipAllWindows(); + + /* Copy bitmap bits if it's a move */ + if (IsMove) + { + /* FIXME: The window MUST be foreground, otherwise bits will be + copied incorrectly */ + SwmCopyBits(WindowRect, OldRect); + } + + /* Paint area changed after moving or resizing */ + if (Width < OldWidth || + Height < OldHeight || + IsMove) + { + /* Subtract new visible rect from the old one, + and invalidate the result */ + OldRegion = create_empty_region(); + set_region_rect(OldRegion, &OldRectSafe); + + /* Compute the difference into the temp region */ + DiffRegion = create_empty_region(); + subtract_region(DiffRegion, OldRegion, SwmWin->Visible); + + /* Paint it */ + SwmPaintRegion(DiffRegion); + + /* Free temporary regions */ + free_region(OldRegion); + free_region(DiffRegion); + }
/* Release the lock */ SwmRelease();