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/winen…
==============================================================================
--- 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/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] 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/winen…
==============================================================================
--- 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/nt…
==============================================================================
--- 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/win3…
==============================================================================
--- 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/win3…
==============================================================================
--- 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/win3…
==============================================================================
--- 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/win3…
==============================================================================
--- 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