From d99df2b7578144daf3893fe1b2ecffb1b55316fc Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Wed, 30 Mar 2005 10:28:58 +0000 Subject: [PATCH] Only reset the clip region in GetDC() if a new region is specified. Don't release the clip region for window DCs in ReleaseDC(), except when called from EndPaint(). Added a bunch of tests. --- dlls/user/painting.c | 7 +- dlls/user/tests/dce.c | 211 +++++++++++++++++++++++++++++++++++++++ dlls/user/user_private.h | 2 +- dlls/x11drv/dce.c | 71 +++++++------ dlls/x11drv/x11drv.spec | 2 +- include/win.h | 3 - 6 files changed, 250 insertions(+), 46 deletions(-) diff --git a/dlls/user/painting.c b/dlls/user/painting.c index d0f568db0b4..3aef4c0b14b 100644 --- a/dlls/user/painting.c +++ b/dlls/user/painting.c @@ -250,7 +250,7 @@ static BOOL send_erase( HWND hwnd, UINT flags, HRGN client_rgn, if (hdc_ret || (flags & UPDATE_ERASE)) { - UINT dcx_flags = DCX_INTERSECTRGN | DCX_WINDOWPAINT | DCX_USESTYLE; + UINT dcx_flags = DCX_INTERSECTRGN | DCX_USESTYLE; if (IsIconic(hwnd)) dcx_flags |= DCX_WINDOW; if ((hdc = GetDCEx( hwnd, client_rgn, dcx_flags ))) @@ -409,8 +409,7 @@ HDC WINAPI BeginPaint( HWND hwnd, PAINTSTRUCT *lps ) BOOL WINAPI EndPaint( HWND hwnd, const PAINTSTRUCT *lps ) { if (!lps) return FALSE; - - ReleaseDC( hwnd, lps->hdc ); + if (USER_Driver.pReleaseDC) USER_Driver.pReleaseDC( hwnd, lps->hdc, TRUE ); ShowCaret( hwnd ); return TRUE; } @@ -465,7 +464,7 @@ HDC WINAPI GetWindowDC( HWND hwnd ) */ INT WINAPI ReleaseDC( HWND hwnd, HDC hdc ) { - if (USER_Driver.pReleaseDC) return USER_Driver.pReleaseDC( hwnd, hdc ); + if (USER_Driver.pReleaseDC) return USER_Driver.pReleaseDC( hwnd, hdc, FALSE ); return 0; } diff --git a/dlls/user/tests/dce.c b/dlls/user/tests/dce.c index 74e2ca1263d..5c42e3f1e11 100644 --- a/dlls/user/tests/dce.c +++ b/dlls/user/tests/dce.c @@ -153,6 +153,215 @@ static void test_parameters(void) } +static void test_dc_visrgn(void) +{ + HDC old_hdc, hdc; + HRGN hrgn, hrgn2; + RECT rect; + + /* cache DC */ + + SetRect( &rect, 10, 10, 20, 20 ); + MapWindowPoints( hwnd_cache, 0, (POINT *)&rect, 2 ); + hrgn = CreateRectRgnIndirect( &rect ); + hdc = GetDCEx( hwnd_cache, hrgn, DCX_INTERSECTRGN | DCX_USESTYLE ); + SetRectEmpty( &rect ); + GetClipBox( hdc, &rect ); + todo_wine ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20, + "invalid clip box %ld,%ld-%ld,%ld\n", rect.left, rect.top, rect.right, rect.bottom ); + ok( GetRgnBox( hrgn, &rect ) != ERROR, "region must still be valid\n" ); + ReleaseDC( hwnd_cache, hdc ); + ok( GetRgnBox( hrgn, &rect ) == ERROR, "region must no longer be valid\n" ); + + /* cache DC with NORESETATTRS */ + + SetRect( &rect, 10, 10, 20, 20 ); + MapWindowPoints( hwnd_cache, 0, (POINT *)&rect, 2 ); + hrgn = CreateRectRgnIndirect( &rect ); + hdc = GetDCEx( hwnd_cache, hrgn, DCX_INTERSECTRGN | DCX_USESTYLE | DCX_NORESETATTRS ); + SetRectEmpty( &rect ); + GetClipBox( hdc, &rect ); + todo_wine ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20, + "invalid clip box %ld,%ld-%ld,%ld\n", rect.left, rect.top, rect.right, rect.bottom ); + ok( GetRgnBox( hrgn, &rect ) != ERROR, "region must still be valid\n" ); + ReleaseDC( hwnd_cache, hdc ); + ok( GetRgnBox( hrgn, &rect ) == ERROR, "region must no longer be valid\n" ); + hdc = GetDCEx( hwnd_cache, 0, DCX_USESTYLE | DCX_NORESETATTRS ); + SetRectEmpty( &rect ); + GetClipBox( hdc, &rect ); + ok( !(rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20), + "clip box sould have been reset %ld,%ld-%ld,%ld\n", rect.left, rect.top, rect.right, rect.bottom ); + ReleaseDC( hwnd_cache, hdc ); + + /* window DC */ + + SetRect( &rect, 10, 10, 20, 20 ); + MapWindowPoints( hwnd_owndc, 0, (POINT *)&rect, 2 ); + hrgn = CreateRectRgnIndirect( &rect ); + hdc = GetDCEx( hwnd_owndc, hrgn, DCX_INTERSECTRGN | DCX_USESTYLE ); + SetRectEmpty( &rect ); + GetClipBox( hdc, &rect ); + todo_wine ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20, + "invalid clip box %ld,%ld-%ld,%ld\n", rect.left, rect.top, rect.right, rect.bottom ); + ok( GetRgnBox( hrgn, &rect ) != ERROR, "region must still be valid\n" ); + ReleaseDC( hwnd_owndc, hdc ); + ok( GetRgnBox( hrgn, &rect ) != ERROR, "region must still be valid\n" ); + SetRectEmpty( &rect ); + GetClipBox( hdc, &rect ); + todo_wine ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20, + "invalid clip box %ld,%ld-%ld,%ld\n", rect.left, rect.top, rect.right, rect.bottom ); + hdc = GetDCEx( hwnd_owndc, 0, DCX_USESTYLE ); + SetRectEmpty( &rect ); + GetClipBox( hdc, &rect ); + todo_wine ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20, + "invalid clip box %ld,%ld-%ld,%ld\n", rect.left, rect.top, rect.right, rect.bottom ); + ok( GetRgnBox( hrgn, &rect ) != ERROR, "region must still be valid\n" ); + ReleaseDC( hwnd_owndc, hdc ); + ok( GetRgnBox( hrgn, &rect ) != ERROR, "region must still be valid\n" ); + + SetRect( &rect, 20, 20, 30, 30 ); + MapWindowPoints( hwnd_owndc, 0, (POINT *)&rect, 2 ); + hrgn2 = CreateRectRgnIndirect( &rect ); + hdc = GetDCEx( hwnd_owndc, hrgn2, DCX_INTERSECTRGN | DCX_USESTYLE ); + ok( GetRgnBox( hrgn, &rect ) == ERROR, "region must no longer be valid\n" ); + SetRectEmpty( &rect ); + GetClipBox( hdc, &rect ); + todo_wine ok( rect.left >= 20 && rect.top >= 20 && rect.right <= 30 && rect.bottom <= 30, + "invalid clip box %ld,%ld-%ld,%ld\n", rect.left, rect.top, rect.right, rect.bottom ); + ok( GetRgnBox( hrgn2, &rect ) != ERROR, "region2 must still be valid\n" ); + ReleaseDC( hwnd_owndc, hdc ); + ok( GetRgnBox( hrgn2, &rect ) != ERROR, "region2 must still be valid\n" ); + hdc = GetDCEx( hwnd_owndc, 0, DCX_EXCLUDERGN | DCX_USESTYLE ); + ok( GetRgnBox( hrgn2, &rect ) == ERROR, "region must no longer be valid\n" ); + SetRectEmpty( &rect ); + GetClipBox( hdc, &rect ); + ok( !(rect.left >= 20 && rect.top >= 20 && rect.right <= 30 && rect.bottom <= 30), + "clip box should have been reset %ld,%ld-%ld,%ld\n", rect.left, rect.top, rect.right, rect.bottom ); + ReleaseDC( hwnd_owndc, hdc ); + + /* class DC */ + + SetRect( &rect, 10, 10, 20, 20 ); + MapWindowPoints( hwnd_classdc, 0, (POINT *)&rect, 2 ); + hrgn = CreateRectRgnIndirect( &rect ); + hdc = GetDCEx( hwnd_classdc, hrgn, DCX_INTERSECTRGN | DCX_USESTYLE ); + SetRectEmpty( &rect ); + GetClipBox( hdc, &rect ); + todo_wine ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20, + "invalid clip box %ld,%ld-%ld,%ld\n", rect.left, rect.top, rect.right, rect.bottom ); + ok( GetRgnBox( hrgn, &rect ) != ERROR, "region must still be valid\n" ); + ReleaseDC( hwnd_classdc, hdc ); + ok( GetRgnBox( hrgn, &rect ) != ERROR, "region must still be valid\n" ); + SetRectEmpty( &rect ); + GetClipBox( hdc, &rect ); + todo_wine ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20, + "invalid clip box %ld,%ld-%ld,%ld\n", rect.left, rect.top, rect.right, rect.bottom ); + + hdc = GetDCEx( hwnd_classdc, 0, DCX_USESTYLE ); + SetRectEmpty( &rect ); + GetClipBox( hdc, &rect ); + todo_wine ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20, + "invalid clip box %ld,%ld-%ld,%ld\n", rect.left, rect.top, rect.right, rect.bottom ); + ok( GetRgnBox( hrgn, &rect ) != ERROR, "region must still be valid\n" ); + ReleaseDC( hwnd_classdc, hdc ); + ok( GetRgnBox( hrgn, &rect ) != ERROR, "region must still be valid\n" ); + + SetRect( &rect, 20, 20, 30, 30 ); + MapWindowPoints( hwnd_classdc, 0, (POINT *)&rect, 2 ); + hrgn2 = CreateRectRgnIndirect( &rect ); + hdc = GetDCEx( hwnd_classdc, hrgn2, DCX_INTERSECTRGN | DCX_USESTYLE ); + ok( GetRgnBox( hrgn, &rect ) == ERROR, "region must no longer be valid\n" ); + SetRectEmpty( &rect ); + GetClipBox( hdc, &rect ); + todo_wine ok( rect.left >= 20 && rect.top >= 20 && rect.right <= 30 && rect.bottom <= 30, + "invalid clip box %ld,%ld-%ld,%ld\n", rect.left, rect.top, rect.right, rect.bottom ); + ok( GetRgnBox( hrgn2, &rect ) != ERROR, "region2 must still be valid\n" ); + + old_hdc = hdc; + hdc = GetDCEx( hwnd_classdc2, 0, DCX_USESTYLE ); + ok( old_hdc == hdc, "did not get the same hdc %p/%p\n", old_hdc, hdc ); + ok( GetRgnBox( hrgn2, &rect ) != ERROR, "region2 must still be valid\n" ); + SetRectEmpty( &rect ); + GetClipBox( hdc, &rect ); + ok( !(rect.left >= 20 && rect.top >= 20 && rect.right <= 30 && rect.bottom <= 30), + "clip box should have been reset %ld,%ld-%ld,%ld\n", rect.left, rect.top, rect.right, rect.bottom ); + ReleaseDC( hwnd_classdc2, hdc ); + ok( GetRgnBox( hrgn2, &rect ) != ERROR, "region2 must still be valid\n" ); + hdc = GetDCEx( hwnd_classdc2, 0, DCX_EXCLUDERGN | DCX_USESTYLE ); + ok( GetRgnBox( hrgn2, &rect ) != ERROR, "region2 must still be valid\n" ); + ok( !(rect.left >= 20 && rect.top >= 20 && rect.right <= 30 && rect.bottom <= 30), + "clip box must have been reset %ld,%ld-%ld,%ld\n", rect.left, rect.top, rect.right, rect.bottom ); + ReleaseDC( hwnd_classdc2, hdc ); +} + + +/* test various BeginPaint/EndPaint behaviors */ +static void test_begin_paint(void) +{ + HDC old_hdc, hdc; + RECT rect; + PAINTSTRUCT ps; + + /* cache DC */ + + /* clear update region */ + RedrawWindow( hwnd_cache, NULL, 0, RDW_VALIDATE|RDW_NOFRAME|RDW_NOERASE ); + SetRect( &rect, 10, 10, 20, 20 ); + RedrawWindow( hwnd_cache, &rect, 0, RDW_INVALIDATE ); + hdc = BeginPaint( hwnd_cache, &ps ); + SetRectEmpty( &rect ); + GetClipBox( hdc, &rect ); + ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20, + "invalid clip box %ld,%ld-%ld,%ld\n", rect.left, rect.top, rect.right, rect.bottom ); + EndPaint( hwnd_cache, &ps ); + + /* window DC */ + + RedrawWindow( hwnd_owndc, NULL, 0, RDW_VALIDATE|RDW_NOFRAME|RDW_NOERASE ); + SetRect( &rect, 10, 10, 20, 20 ); + RedrawWindow( hwnd_owndc, &rect, 0, RDW_INVALIDATE ); + hdc = BeginPaint( hwnd_owndc, &ps ); + SetRectEmpty( &rect ); + GetClipBox( hdc, &rect ); + ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20, + "invalid clip box %ld,%ld-%ld,%ld\n", rect.left, rect.top, rect.right, rect.bottom ); + ReleaseDC( hwnd_owndc, hdc ); + SetRectEmpty( &rect ); + GetClipBox( hdc, &rect ); + ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20, + "invalid clip box %ld,%ld-%ld,%ld\n", rect.left, rect.top, rect.right, rect.bottom ); + ok( GetDC( hwnd_owndc ) == hdc, "got different hdc\n" ); + SetRectEmpty( &rect ); + GetClipBox( hdc, &rect ); + ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20, + "invalid clip box %ld,%ld-%ld,%ld\n", rect.left, rect.top, rect.right, rect.bottom ); + EndPaint( hwnd_owndc, &ps ); + SetRectEmpty( &rect ); + GetClipBox( hdc, &rect ); + ok( !(rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20), + "clip box should have been reset %ld,%ld-%ld,%ld\n", rect.left, rect.top, rect.right, rect.bottom ); + + /* class DC */ + + RedrawWindow( hwnd_classdc, NULL, 0, RDW_VALIDATE|RDW_NOFRAME|RDW_NOERASE ); + SetRect( &rect, 10, 10, 20, 20 ); + RedrawWindow( hwnd_classdc, &rect, 0, RDW_INVALIDATE ); + hdc = BeginPaint( hwnd_classdc, &ps ); + SetRectEmpty( &rect ); + GetClipBox( hdc, &rect ); + ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20, + "invalid clip box %ld,%ld-%ld,%ld\n", rect.left, rect.top, rect.right, rect.bottom ); + + old_hdc = hdc; + hdc = GetDC( hwnd_classdc2 ); + ok( old_hdc == hdc, "did not get the same hdc %p/%p\n", old_hdc, hdc ); + SetRectEmpty( &rect ); + GetClipBox( hdc, &rect ); + ok( !(rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20), + "clip box should have been reset %ld,%ld-%ld,%ld\n", rect.left, rect.top, rect.right, rect.bottom ); +} + + START_TEST(dce) { WNDCLASSA cls; @@ -189,4 +398,6 @@ START_TEST(dce) 0, 0, GetModuleHandleA(0), NULL ); test_dc_attributes(); test_parameters(); + test_dc_visrgn(); + test_begin_paint(); } diff --git a/dlls/user/user_private.h b/dlls/user/user_private.h index bda67c016be..be562a9904e 100644 --- a/dlls/user/user_private.h +++ b/dlls/user/user_private.h @@ -102,7 +102,7 @@ typedef struct tagUSER_DRIVER { BOOL (*pDestroyWindow)(HWND); HDC (*pGetDCEx)(HWND,HRGN,DWORD); DWORD (*pMsgWaitForMultipleObjectsEx)(DWORD,const HANDLE*,DWORD,DWORD,DWORD); - BOOL (*pReleaseDC)(HWND,HDC); + BOOL (*pReleaseDC)(HWND,HDC,BOOL); BOOL (*pScrollDC)(HDC, INT, INT, const RECT *, const RECT *, HRGN, LPRECT); void (*pSetFocus)(HWND); HWND (*pSetParent)(HWND,HWND); diff --git a/dlls/x11drv/dce.c b/dlls/x11drv/dce.c index 1b37d1d6626..600b11d9a8f 100644 --- a/dlls/x11drv/dce.c +++ b/dlls/x11drv/dce.c @@ -17,14 +17,6 @@ * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * - * Note: Visible regions of CS_OWNDC/CS_CLASSDC window DCs - * have to be updated dynamically. - * - * Internal DCX flags: - * - * DCX_WINDOWPAINT - BeginPaint() is in effect */ #include "config.h" @@ -151,11 +143,12 @@ static HWND get_top_clipping_window( HWND hwnd ) * Set the drawable, origin and dimensions for the DC associated to * a given window. */ -static void set_drawable( struct dce *dce, DWORD flags, BOOL update_visrgn ) +static void set_drawable( struct dce *dce, BOOL update_visrgn ) { HWND top = get_top_clipping_window( dce->hwnd ); struct x11drv_escape_set_drawable escape; struct x11drv_win_data *data; + DWORD flags = dce->flags; escape.mode = IncludeInferiors; /* don't clip siblings if using parent clip region */ @@ -222,13 +215,14 @@ static void set_drawable( struct dce *dce, DWORD flags, BOOL update_visrgn ) escape.code = X11DRV_SET_DRAWABLE; ExtEscape( dce->hdc, X11DRV_ESCAPE, sizeof(escape), (LPSTR)&escape, 0, NULL ); - if (flags & (DCX_EXCLUDERGN | DCX_INTERSECTRGN) || update_visrgn) + if (update_visrgn) { /* need to recompute the visible region */ HRGN visRgn = get_server_visible_region( dce->hwnd, flags ); - if (flags & (DCX_EXCLUDERGN | DCX_INTERSECTRGN)) - CombineRgn( visRgn, visRgn, dce->clip_rgn, (flags & DCX_INTERSECTRGN) ? RGN_AND : RGN_DIFF ); + if (dce->clip_rgn) + CombineRgn( visRgn, visRgn, dce->clip_rgn, + (flags & DCX_INTERSECTRGN) ? RGN_AND : RGN_DIFF ); SelectVisRgn16( HDC_16(dce->hdc), HRGN_16(visRgn) ); DeleteObject( visRgn ); @@ -266,7 +260,7 @@ static void delete_clip_rgn( struct dce *dce ) { if (!dce->clip_rgn) return; /* nothing to do */ - dce->flags &= ~(DCX_EXCLUDERGN | DCX_INTERSECTRGN | DCX_WINDOWPAINT); + dce->flags &= ~(DCX_EXCLUDERGN | DCX_INTERSECTRGN); DeleteObject( dce->clip_rgn ); dce->clip_rgn = 0; @@ -499,9 +493,10 @@ void invalidate_dce( HWND hwnd, const RECT *rect ) */ HDC X11DRV_GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags ) { + static const DWORD clip_flags = DCX_PARENTCLIP | DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN | DCX_WINDOW; + struct x11drv_win_data *data = X11DRV_get_win_data( hwnd ); struct dce *dce; - HDC hdc = 0; BOOL bUpdateVisRgn = TRUE; HWND parent; LONG window_style = GetWindowLongW( hwnd, GWL_STYLE ); @@ -565,9 +560,7 @@ HDC X11DRV_GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags ) dceUnused = dce; if (!dce->hwnd) dceEmpty = dce; - else if ((dce->hwnd == hwnd) && - (!((dce->flags ^ flags) & (DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN | - DCX_WINDOW | DCX_PARENTCLIP)))) + else if ((dce->hwnd == hwnd) && !((dce->flags ^ flags) & clip_flags)) { TRACE("\tfound valid %p dce [%p], flags %08lx\n", dce, hwnd, dce->flags ); @@ -597,44 +590,48 @@ HDC X11DRV_GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags ) TRACE("\tskipping hVisRgn update\n"); bUpdateVisRgn = FALSE; /* updated automatically, via DCHook() */ } + else + { + /* we should free dce->clip_rgn here, but Windows apparently doesn't */ + dce->flags &= ~(DCX_EXCLUDERGN | DCX_INTERSECTRGN); + dce->clip_rgn = 0; + } } - if (!(flags & (DCX_INTERSECTRGN | DCX_EXCLUDERGN))) hrgnClip = 0; - else if (!hrgnClip) hrgnClip = CreateRectRgn( 0, 0, 0, 0 ); - - if (((flags ^ dce->flags) & (DCX_INTERSECTRGN | DCX_EXCLUDERGN)) && - (dce->clip_rgn != hrgnClip)) + if (flags & (DCX_INTERSECTRGN | DCX_EXCLUDERGN)) { /* if the extra clip region has changed, get rid of the old one */ - delete_clip_rgn( dce ); + if (dce->clip_rgn != hrgnClip || ((flags ^ dce->flags) & (DCX_INTERSECTRGN | DCX_EXCLUDERGN))) + delete_clip_rgn( dce ); + dce->clip_rgn = hrgnClip; + if (!dce->clip_rgn) dce->clip_rgn = CreateRectRgn( 0, 0, 0, 0 ); + dce->flags |= flags & (DCX_INTERSECTRGN | DCX_EXCLUDERGN); + bUpdateVisRgn = TRUE; } dce->hwnd = hwnd; - dce->clip_rgn = hrgnClip; - dce->flags = flags & (DCX_PARENTCLIP | DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN | - DCX_CACHE | DCX_WINDOW | DCX_WINDOWPAINT | - DCX_INTERSECTRGN | DCX_EXCLUDERGN); - hdc = dce->hdc; + dce->flags = (dce->flags & ~clip_flags) | (flags & clip_flags); - if (SetHookFlags16( HDC_16(hdc), DCHF_VALIDATEVISRGN )) bUpdateVisRgn = TRUE; /* DC was dirty */ + if (SetHookFlags16( HDC_16(dce->hdc), DCHF_VALIDATEVISRGN )) + bUpdateVisRgn = TRUE; /* DC was dirty */ - set_drawable( dce, flags, bUpdateVisRgn ); + set_drawable( dce, bUpdateVisRgn ); if (!(flags & DCX_NORESETATTRS)) { - RestoreDC( hdc, 1 ); /* initial save level is always 1 */ - SaveDC( hdc ); /* save the state again for next time */ + RestoreDC( dce->hdc, 1 ); /* initial save level is always 1 */ + SaveDC( dce->hdc ); /* save the state again for next time */ } - TRACE("(%p,%p,0x%lx): returning %p\n", hwnd, hrgnClip, flags, hdc); - return hdc; + TRACE("(%p,%p,0x%lx): returning %p\n", hwnd, hrgnClip, flags, dce->hdc); + return dce->hdc; } /*********************************************************************** * X11DRV_ReleaseDC (X11DRV.@) */ -BOOL X11DRV_ReleaseDC( HWND hwnd, HDC hdc ) +BOOL X11DRV_ReleaseDC( HWND hwnd, HDC hdc, BOOL end_paint ) { enum x11drv_escape_codes escape = X11DRV_GET_DCE; struct dce *dce; @@ -647,7 +644,7 @@ BOOL X11DRV_ReleaseDC( HWND hwnd, HDC hdc ) sizeof(dce), (LPSTR)&dce )) dce = NULL; if (dce && dce->count) { - if ((dce->flags & (DCX_CACHE | DCX_WINDOWPAINT))) delete_clip_rgn( dce ); + if (end_paint || (dce->flags & DCX_CACHE)) delete_clip_rgn( dce ); if (dce->flags & DCX_CACHE) dce->count = 0; ret = TRUE; } @@ -677,7 +674,7 @@ static BOOL16 CALLBACK dc_hook( HDC16 hDC, WORD code, DWORD data, LPARAM lParam * DC is dirty (usually after SetHookFlags()). This * means that we have to recompute the visible region. */ - if (dce->count) set_drawable( dce, dce->flags, TRUE ); + if (dce->count) set_drawable( dce, TRUE ); else /* non-fatal but shouldn't happen */ WARN("DC is not in use!\n"); break; diff --git a/dlls/x11drv/x11drv.spec b/dlls/x11drv/x11drv.spec index 3e4a44456e9..9a705d1a948 100644 --- a/dlls/x11drv/x11drv.spec +++ b/dlls/x11drv/x11drv.spec @@ -96,7 +96,7 @@ @ cdecl IsClipboardFormatAvailable(long) X11DRV_IsClipboardFormatAvailable @ cdecl MsgWaitForMultipleObjectsEx(long ptr long long long) X11DRV_MsgWaitForMultipleObjectsEx @ cdecl RegisterClipboardFormat(str) X11DRV_RegisterClipboardFormat -@ cdecl ReleaseDC(long long) X11DRV_ReleaseDC +@ cdecl ReleaseDC(long long long) X11DRV_ReleaseDC @ cdecl ResetSelectionOwner(long long) X11DRV_ResetSelectionOwner @ cdecl ScrollDC(long long long ptr ptr long ptr) X11DRV_ScrollDC @ cdecl SetClipboardData(long long long long) X11DRV_SetClipboardData diff --git a/include/win.h b/include/win.h index 1aed8eba936..b7112457f80 100644 --- a/include/win.h +++ b/include/win.h @@ -106,7 +106,4 @@ inline static void WIN_ReleasePtr( WND *ptr ) extern LRESULT HOOK_CallHooks( INT id, INT code, WPARAM wparam, LPARAM lparam, BOOL unicode ); -/* internal GetDC flag (FIXME) */ -#define DCX_WINDOWPAINT 0x00020000 - #endif /* __WINE_WIN_H */