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/winen…
==============================================================================
--- 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/win3…
==============================================================================
--- 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/win3…
==============================================================================
--- 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();