Author: fireball Date: Wed Nov 11 20:55:22 2009 New Revision: 44112
URL: http://svn.reactos.org/svn/reactos?rev=44112&view=rev Log: - Implement GetDC/ReleaseDC for window manager with clipping support. This addresses the invalid drawing order "bug", which is in fact a feature. Client window manager is responsible for compositing all windows in a given rectangle being redrawn. Arwinss implements a very simple client window manager (SWM) which just clips out all contents behind the window on top of a z order. - Notify SWM about a new (or an existing) desktop window. - Fix comment typos.
Modified: branches/arwinss/reactos/dll/win32/winent.drv/gdidrv.c branches/arwinss/reactos/dll/win32/winent.drv/userdrv.c branches/arwinss/reactos/dll/win32/winent.drv/winent.h branches/arwinss/reactos/include/psdk/ntrosgdi.h branches/arwinss/reactos/include/reactos/win32k/rosuser.h branches/arwinss/reactos/subsystems/win32/win32k/gdi/dc.c branches/arwinss/reactos/subsystems/win32/win32k/gre/surfobj.c branches/arwinss/reactos/subsystems/win32/win32k/include/dc.h branches/arwinss/reactos/subsystems/win32/win32k/w32ksvc.db
Modified: branches/arwinss/reactos/dll/win32/winent.drv/gdidrv.c URL: http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/dll/win32/winent... ============================================================================== --- branches/arwinss/reactos/dll/win32/winent.drv/gdidrv.c [iso-8859-1] (original) +++ branches/arwinss/reactos/dll/win32/winent.drv/gdidrv.c [iso-8859-1] Wed Nov 11 20:55:22 2009 @@ -228,6 +228,12 @@ { const struct ntdrv_escape_set_drawable *data = in_data; RosGdiSetDcRects(physDev->hKernelDC, (RECT*)&data->dc_rect, (RECT*)&data->drawable_rect); + + if (!data->release) + RosGdiGetDC(physDev->hKernelDC, data->hwnd, data->clip_children); + else + RosGdiReleaseDC(physDev->hKernelDC); + TRACE( "SET_DRAWABLE hdc %p dc_rect %s drawable_rect %s\n", physDev->hUserDC, wine_dbgstr_rect(&data->dc_rect), wine_dbgstr_rect(&data->drawable_rect) ); return TRUE;
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] Wed Nov 11 20:55:22 2009 @@ -458,6 +458,8 @@
TRACE("RosDrv_CreateDesktopWindow(%x), w %d h %d\n", hwnd, width, height);
+ SwmAddDesktopWindow(hwnd, width, height); + if (!width && !height) /* not initialized yet */ { SERVER_START_REQ( set_window_pos ) @@ -490,27 +492,25 @@ NTDRV_destroy_win_data( hwnd ); }
-void CDECL RosDrv_GetDC( HDC hdc, HWND hwnd, HWND top_win, const RECT *win_rect, +void CDECL RosDrv_GetDC( HDC hdc, HWND hwnd, HWND top, const RECT *win_rect, const RECT *top_rect, DWORD flags ) { struct ntdrv_escape_set_drawable escape; - //struct ntdrv_win_data *data = X11DRV_get_win_data( hwnd ); + struct ntdrv_win_data *data = NTDRV_get_win_data( hwnd );
escape.code = NTDRV_SET_DRAWABLE; - //escape.mode = IncludeInferiors; - //escape.fbconfig_id = 0; - //escape.gl_drawable = 0; - //escape.pixmap = 0; + escape.clip_children = FALSE; escape.gl_copy = FALSE; - -#if 0 - if (top == hwnd && data && IsIconic( hwnd ) && data->icon_window) + escape.hwnd = hwnd; + escape.release = FALSE; + + if (top == hwnd && data && IsIconic( hwnd ) /*&& data->icon_window*/) { //escape.drawable = data->icon_window; } else if (top == hwnd) { - escape.fbconfig_id = data ? data->fbconfig_id : (XID)GetPropA( hwnd, fbconfig_id_prop ); + //escape.fbconfig_id = data ? data->fbconfig_id : (XID)GetPropA( hwnd, fbconfig_id_prop ); /* GL draws to the client area even for window DCs */ /*escape.gl_drawable = data ? data->client_window : X11DRV_get_client_window( hwnd ); if (flags & DCX_WINDOW) @@ -525,9 +525,9 @@ //escape.gl_drawable = data ? data->gl_drawable : (Drawable)GetPropA( hwnd, gl_drawable_prop ); //escape.pixmap = data ? data->pixmap : (Pixmap)GetPropA( hwnd, pixmap_prop ); //escape.gl_copy = (escape.gl_drawable != 0); - if (flags & DCX_CLIPCHILDREN) escape.mode = ClipByChildren; - } -#endif + + if (flags & DCX_CLIPCHILDREN) escape.clip_children = TRUE; + }
escape.dc_rect.left = win_rect->left - top_rect->left; escape.dc_rect.top = win_rect->top - top_rect->top; @@ -544,7 +544,7 @@ DWORD CDECL RosDrv_MsgWaitForMultipleObjectsEx( DWORD count, const HANDLE *handles, DWORD timeout, DWORD mask, DWORD flags ) { - TRACE("WaitForMultipleObjectsEx(%d %p %d %x %x %x\n", count, handles, timeout, mask, flags); + //TRACE("WaitForMultipleObjectsEx(%d %p %d %x %x %x\n", count, handles, timeout, mask, flags);
if (!count && !timeout) return WAIT_TIMEOUT; return WaitForMultipleObjectsEx( count, handles, flags & MWMO_WAITALL, @@ -557,6 +557,8 @@
escape.code = NTDRV_SET_DRAWABLE; escape.gl_copy = FALSE; + escape.hwnd = hwnd; + escape.release = TRUE;
escape.dc_rect.left = 0; escape.dc_rect.top = 0; @@ -840,8 +842,8 @@
if (!data) return;
- TRACE( "win %x pos changed. new vis rect %s, old whole rect %s\n", - hwnd, wine_dbgstr_rect(visible_rect), wine_dbgstr_rect(&data->whole_rect) ); + TRACE( "win %x pos changed. new vis rect %s, old whole rect %s, swp_flags %x\n", + hwnd, wine_dbgstr_rect(visible_rect), wine_dbgstr_rect(&data->whole_rect), swp_flags );
old_whole_rect = data->whole_rect; old_client_rect = data->client_rect; @@ -864,15 +866,17 @@ old_client_rect.bottom - data->client_rect.bottom == y_offset && !memcmp( &valid_rects[0], &data->client_rect, sizeof(RECT) )) { - //move_window_bits( data, &old_whole_rect, &data->whole_rect, &old_client_rect ); + //move_window_bits( data, &old_whole_rect, &data->whole_rect, &old_client_rect ); SwmPosChanged(hwnd, &data->whole_rect, &old_whole_rect); + FIXME("change1\n"); } else { - //move_window_bits( data, &valid_rects[1], &valid_rects[0], &old_client_rect ); + move_window_bits( data, &valid_rects[1], &valid_rects[0], &old_client_rect ); + FIXME("change2\n"); } } - +// visible: 0x1843, hide: 0x1883. 1843 = 1 + 2 + 64 + 2048 + 4096 //RosDrv_UpdateZOrder(hwnd, (RECT*)visible_rect); }
Modified: branches/arwinss/reactos/dll/win32/winent.drv/winent.h URL: http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/dll/win32/winent... ============================================================================== --- branches/arwinss/reactos/dll/win32/winent.drv/winent.h [iso-8859-1] (original) +++ branches/arwinss/reactos/dll/win32/winent.drv/winent.h [iso-8859-1] Wed Nov 11 20:55:22 2009 @@ -19,14 +19,12 @@ struct ntdrv_escape_set_drawable { enum ntdrv_escape_codes code; /* escape code (X11DRV_SET_DRAWABLE) */ - //Drawable drawable; /* X drawable */ - int mode; /* ClipByChildren or IncludeInferiors */ + BOOL clip_children;/* ClipByChildren or IncludeInferiors */ RECT dc_rect; /* DC rectangle relative to drawable */ RECT drawable_rect;/* Drawable rectangle relative to screen */ - //XID fbconfig_id; /* fbconfig id used by the GL drawable */ - //Drawable gl_drawable; /* GL drawable */ - //Pixmap pixmap; /* Pixmap for a GLXPixmap gl_drawable */ + HWND hwnd; /* hwnd of which the GetDC is performed */ int gl_copy; /* whether the GL contents need explicit copying */ + BOOL release; /* whether the DC is acquired or released */ };
/* ntdrv private window data */
Modified: branches/arwinss/reactos/include/psdk/ntrosgdi.h URL: http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/include/psdk/ntr... ============================================================================== --- branches/arwinss/reactos/include/psdk/ntrosgdi.h [iso-8859-1] (original) +++ branches/arwinss/reactos/include/psdk/ntrosgdi.h [iso-8859-1] Wed Nov 11 20:55:22 2009 @@ -119,6 +119,8 @@ COLORREF APIENTRY RosGdiSetTextColor( HDC physDev, COLORREF color ); VOID APIENTRY RosGdiSetDcRects( HDC physDev, RECT *rcDcRect, RECT *rcVport ); VOID APIENTRY RosGdiGetDcRects( HDC physDev, RECT *rcDcRect, RECT *rcVport ); +VOID APIENTRY RosGdiGetDC( HDC physDev, HWND hwnd, BOOL clipChildren ); +VOID APIENTRY RosGdiReleaseDC( HDC physDev );
/* enum.c */ int APIENTRY RosGdiChoosePixelFormat(HDC physDev,
Modified: branches/arwinss/reactos/include/reactos/win32k/rosuser.h URL: http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/include/reactos/... ============================================================================== --- branches/arwinss/reactos/include/reactos/win32k/rosuser.h [iso-8859-1] (original) +++ branches/arwinss/reactos/include/reactos/win32k/rosuser.h [iso-8859-1] Wed Nov 11 20:55:22 2009 @@ -140,6 +140,9 @@ SwmAddWindow(HWND hWnd, RECT *WindowRect);
VOID NTAPI +SwmAddDesktopWindow(HWND hWnd, UINT Width, UINT Height); + +VOID NTAPI SwmRemoveWindow(HWND hWnd);
VOID NTAPI
Modified: branches/arwinss/reactos/subsystems/win32/win32k/gdi/dc.c URL: http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/subsystems/win32... ============================================================================== --- branches/arwinss/reactos/subsystems/win32/win32k/gdi/dc.c [iso-8859-1] (original) +++ branches/arwinss/reactos/subsystems/win32/win32k/gdi/dc.c [iso-8859-1] Wed Nov 11 20:55:22 2009 @@ -9,6 +9,11 @@ /* INCLUDES ******************************************************************/
#include <win32k.h> + +#include "object.h" +#include "handle.h" +#include "user.h" + #define NDEBUG #include <debug.h>
@@ -143,6 +148,7 @@
/* Create an empty combined clipping region */ pNewDC->CombinedClip = EngCreateClip(); + pNewDC->Clipping = create_empty_region();
/* Set default palette */ pNewDC->hPalette = hSystemPal; @@ -447,6 +453,36 @@ return 0; }
+VOID APIENTRY RosGdiUpdateClipping(PDC pDC) +{ + struct region *inter; + if (!pDC->pWindow) + { + /* Easy case, just copy the existing clipping region */ + if (pDC->CombinedClip) EngDeleteClip(pDC->CombinedClip); + pDC->CombinedClip = IntEngCreateClipRegionFromRegion(pDC->Clipping); + } + else + { + /* Intersect with window's visibility */ + inter = create_empty_region(); + copy_region(inter, pDC->Clipping); + + /* Acquire SWM lock */ + SwmAcquire(); + + /* Intersect current clipping region and window's visible region */ + intersect_region(inter, inter, pDC->pWindow->Visible); + + /* Release SWM lock */ + SwmRelease(); + + if (pDC->CombinedClip) EngDeleteClip(pDC->CombinedClip); + pDC->CombinedClip = IntEngCreateClipRegionFromRegion(inter); + free_region(inter); + } +} + void APIENTRY RosGdiSetDeviceClipping( HDC physDev, UINT count, PRECTL pRects, PRECTL rcBounds ) { PDC pDC; @@ -510,8 +546,8 @@ pDC->rcDcRect.top + pDC->rcVport.top);
/* Delete old clipping region */ - if (pDC->CombinedClip) - IntEngDeleteClipRegion(pDC->CombinedClip); + if (pDC->Clipping) + free_region(pDC->Clipping);
if (count == 0) { @@ -534,12 +570,12 @@ RECTL_bIntersectRect(&rcSafeBounds, &rcSafeBounds, &rcSurface);
/* Set the clipping object */ - pDC->CombinedClip = IntEngCreateClipRegion(1, &rcSafeBounds, &rcSafeBounds); + pDC->Clipping = create_region_from_rects(&rcSafeBounds, 1); } else { /* Set the clipping object */ - pDC->CombinedClip = IntEngCreateClipRegion(count, pSafeRects, &rcSafeBounds); + pDC->Clipping = create_region_from_rects(pSafeRects, count); }
DPRINT("RosGdiSetDeviceClipping() for DC %x, bounding rect (%d,%d)-(%d, %d)\n", @@ -550,6 +586,9 @@ { DPRINT("%d: (%d,%d)-(%d, %d)\n", i, pSafeRects[i].left, pSafeRects[i].top, pSafeRects[i].right, pSafeRects[i].bottom); } + + /* Update the combined clipping */ + RosGdiUpdateClipping(pDC);
/* Release the object */ DC_Unlock(pDC); @@ -641,4 +680,38 @@ DC_Unlock(pDC); }
+VOID APIENTRY RosGdiGetDC(HDC physDev, HWND hwnd, BOOL clipChildren) +{ + PDC pDC; + + /* Acquire SWM lock before locking the DC */ + SwmAcquire(); + + /* Get a pointer to the DC */ + pDC = DC_Lock(physDev); + + /* Get a pointer to this window */ + pDC->pWindow = SwmFindByHwnd(hwnd); + + /* Release the object */ + DC_Unlock(pDC); + + /* Release SWM lock */ + SwmRelease(); +} + +VOID APIENTRY RosGdiReleaseDC(HDC physDev) +{ + PDC pDC; + + /* Get a pointer to the DC */ + pDC = DC_Lock(physDev); + + /* No window clipping is to be performed */ + pDC->pWindow = NULL; + + /* Release the object */ + DC_Unlock(pDC); +} + /* EOF */
Modified: branches/arwinss/reactos/subsystems/win32/win32k/gre/surfobj.c URL: http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/subsystems/win32... ============================================================================== --- branches/arwinss/reactos/subsystems/win32/win32k/gre/surfobj.c [iso-8859-1] (original) +++ branches/arwinss/reactos/subsystems/win32/win32k/gre/surfobj.c [iso-8859-1] Wed Nov 11 20:55:22 2009 @@ -298,7 +298,7 @@ x += pDC->rcVport.left + pDC->rcDcRect.left; y += pDC->rcVport.top + pDC->rcDcRect.top;
- /* If points is outside combined clipping region - return error */ + /* If point is outside the combined clipping region - return error */ if (!RECTL_bPointInRect(&pDC->CombinedClip->rclBounds, x, y)) return CLR_INVALID;
Modified: branches/arwinss/reactos/subsystems/win32/win32k/include/dc.h URL: http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/subsystems/win32... ============================================================================== --- branches/arwinss/reactos/subsystems/win32/win32k/include/dc.h [iso-8859-1] (original) +++ branches/arwinss/reactos/subsystems/win32/win32k/include/dc.h [iso-8859-1] Wed Nov 11 20:55:22 2009 @@ -20,7 +20,9 @@ POINT ptBrushOrg;
/* Combined clipping region */ - CLIPOBJ *CombinedClip; + struct region *Clipping; + CLIPOBJ *CombinedClip; + PSWM_WINDOW pWindow;
/* Transformations */ MATRIX mxWorldToDevice;
Modified: branches/arwinss/reactos/subsystems/win32/win32k/w32ksvc.db URL: http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/subsystems/win32... ============================================================================== --- branches/arwinss/reactos/subsystems/win32/win32k/w32ksvc.db [iso-8859-1] (original) +++ branches/arwinss/reactos/subsystems/win32/win32k/w32ksvc.db [iso-8859-1] Wed Nov 11 20:55:22 2009 @@ -39,6 +39,7 @@ RosGdiGetCharWidth 4 RosGdiGetDeviceCaps 2 RosGdiGetDeviceGammaRamp 2 +RosGdiGetDC 3 RosGdiGetICMProfile 3 RosGdiGetNearestColor 2 RosGdiGetPixelFormat 1 @@ -60,6 +61,7 @@ RosGdiRealizeDefaultPalette 1 RosGdiRealizePalette 3 RosGdiRectangle 2 +RosGdiReleaseDC 1 RosGdiRoundRect 7 RosGdiSwapBuffers 1 RosGdiUnrealizePalette 1 @@ -83,6 +85,7 @@ RosUserMapVirtualKeyEx 4 RosUserGetAsyncKeyState 1 SwmAddWindow 2 +SwmAddDesktopWindow 3 SwmRemoveWindow 1 SwmSetForeground 1 SwmPosChanging 2