Commit ffb152df authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

win32u: Make interface between DC and dce private.

parent e17ec9e8
...@@ -326,20 +326,6 @@ void release_dc_ptr( DC *dc ) ...@@ -326,20 +326,6 @@ void release_dc_ptr( DC *dc )
} }
/***********************************************************************
* update_dc
*
* Make sure the DC vis region is up to date.
* This function may call up to USER so the GDI lock should _not_
* be held when calling it.
*/
void update_dc( DC *dc )
{
if (InterlockedExchange( &dc->dirty, 0 ) && dc->hookProc)
dc->hookProc( dc->hSelf, DCHC_INVALIDVISRGN, dc->dwHookData, 0 );
}
static void set_bk_color( DC *dc, COLORREF color ) static void set_bk_color( DC *dc, COLORREF color )
{ {
PHYSDEV physdev = GET_DC_PHYSDEV( dc, pSetBkColor ); PHYSDEV physdev = GET_DC_PHYSDEV( dc, pSetBkColor );
...@@ -524,7 +510,7 @@ static BOOL DC_DeleteObject( HGDIOBJ handle ) ...@@ -524,7 +510,7 @@ static BOOL DC_DeleteObject( HGDIOBJ handle )
/* Call hook procedure to check whether is it OK to delete this DC, /* Call hook procedure to check whether is it OK to delete this DC,
* gdi_lock should not be locked */ * gdi_lock should not be locked */
if (dc->hookProc && !dc->hookProc( dc->hSelf, DCHC_DELETEDC, dc->dwHookData, 0 )) if (dc->dce && !delete_dce( dc->dce ))
{ {
release_dc_ptr( dc ); release_dc_ptr( dc );
return TRUE; return TRUE;
...@@ -1035,57 +1021,43 @@ BOOL WINAPI NtGdiGetTransform( HDC hdc, DWORD which, XFORM *xform ) ...@@ -1035,57 +1021,43 @@ BOOL WINAPI NtGdiGetTransform( HDC hdc, DWORD which, XFORM *xform )
/*********************************************************************** /***********************************************************************
* SetDCHook (win32u.@) * set_dc_dce
*
* Note: this doesn't exist in Win32, we add it here because user32 needs it.
*/ */
BOOL WINAPI SetDCHook( HDC hdc, DCHOOKPROC hookProc, DWORD_PTR dwHookData ) void set_dc_dce( HDC hdc, struct dce *dce )
{ {
DC *dc = get_dc_obj( hdc ); DC *dc;
if (!dc) return FALSE; if (!(dc = get_dc_obj( hdc ))) return;
if (dc->attr->disabled) if (dc->attr->disabled)
{ {
GDI_ReleaseObj( hdc ); GDI_ReleaseObj( hdc );
return 0; return;
} }
dc->dce = dce;
dc->dwHookData = dwHookData; if (dce) dc->dirty = 1;
dc->hookProc = hookProc;
GDI_ReleaseObj( hdc ); GDI_ReleaseObj( hdc );
return TRUE;
} }
/*********************************************************************** /***********************************************************************
* GetDCHook (win32u.@) * get_dc_dce
*
* Note: this doesn't exist in Win32, we add it here because user32 needs it.
*/ */
DWORD_PTR WINAPI GetDCHook( HDC hdc, DCHOOKPROC *proc ) struct dce *get_dc_dce( HDC hdc )
{ {
DC *dc = get_dc_obj( hdc ); DC *dc = get_dc_obj( hdc );
DWORD_PTR ret; struct dce *ret = NULL;
if (!dc) return 0; if (!dc) return 0;
if (dc->attr->disabled) if (!dc->attr->disabled) ret = dc->dce;
{
GDI_ReleaseObj( hdc );
return 0;
}
if (proc) *proc = dc->hookProc;
ret = dc->dwHookData;
GDI_ReleaseObj( hdc ); GDI_ReleaseObj( hdc );
return ret; return ret;
} }
/*********************************************************************** /***********************************************************************
* SetHookFlags (win32u.@) * set_dce_flags
*
* Note: this doesn't exist in Win32, we add it here because user32 needs it.
*/ */
WORD WINAPI SetHookFlags( HDC hdc, WORD flags ) WORD set_dce_flags( HDC hdc, WORD flags )
{ {
DC *dc = get_dc_obj( hdc ); /* not get_dc_ptr, this needs to work from any thread */ DC *dc = get_dc_obj( hdc ); /* not get_dc_ptr, this needs to work from any thread */
LONG ret = 0; LONG ret = 0;
......
...@@ -294,52 +294,51 @@ static void delete_clip_rgn( struct dce *dce ) ...@@ -294,52 +294,51 @@ static void delete_clip_rgn( struct dce *dce )
dce->clip_rgn = 0; dce->clip_rgn = 0;
/* make it dirty so that the vis rgn gets recomputed next time */ /* make it dirty so that the vis rgn gets recomputed next time */
SetHookFlags( dce->hdc, DCHF_INVALIDATEVISRGN ); set_dce_flags( dce->hdc, DCHF_INVALIDATEVISRGN );
} }
/*********************************************************************** /***********************************************************************
* dc_hook * delete_dce
*
* See "Undoc. Windows" for hints (DC, SetDCHook, SetHookFlags)..
*/ */
static BOOL CALLBACK dc_hook( HDC hDC, WORD code, DWORD_PTR data, LPARAM lParam ) BOOL delete_dce( struct dce *dce )
{ {
BOOL retv = TRUE; BOOL ret = TRUE;
struct dce *dce = (struct dce *)data;
TRACE("hDC = %p, %u\n", hDC, code); TRACE( "hdc = %p\n", dce->hdc );
if (!dce) return FALSE; user_lock();
assert( dce->hdc == hDC ); if (!(dce->flags & DCX_CACHE))
{
WARN("Application trying to delete an owned DC %p\n", dce->hdc);
ret = FALSE;
}
else
{
list_remove( &dce->entry );
if (dce->clip_rgn) NtGdiDeleteObjectApp( dce->clip_rgn );
free( dce );
}
user_unlock();
return ret;
}
switch( code ) /***********************************************************************
* update_dc
*
* Make sure the DC vis region is up to date.
* This function may need user lock so the GDI lock should _not_
* be held when calling it.
*/
void update_dc( DC *dc )
{
if (!dc->dirty) return;
dc->dirty = 0;
if (dc->dce)
{ {
case DCHC_INVALIDVISRGN: if (dc->dce->count) update_visible_region( dc->dce );
/* GDI code calls this when it detects that the
* DC is dirty (usually after SetHookFlags()). This
* means that we have to recompute the visible region.
*/
if (dce->count) update_visible_region( dce );
else /* non-fatal but shouldn't happen */ else /* non-fatal but shouldn't happen */
WARN("DC is not in use!\n"); WARN("DC is not in use!\n");
break;
case DCHC_DELETEDC:
user_lock();
if (!(dce->flags & DCX_CACHE))
{
WARN("Application trying to delete an owned DC %p\n", dce->hdc);
retv = FALSE;
}
else
{
list_remove( &dce->entry );
if (dce->clip_rgn) NtGdiDeleteObjectApp( dce->clip_rgn );
free( dce );
}
user_unlock();
break;
} }
return retv;
} }
/*********************************************************************** /***********************************************************************
...@@ -362,9 +361,7 @@ static struct dce *alloc_dce(void) ...@@ -362,9 +361,7 @@ static struct dce *alloc_dce(void)
dce->flags = 0; dce->flags = 0;
dce->count = 1; dce->count = 1;
/* store DCE handle in DC hook data field */ set_dc_dce( dce->hdc, dce );
SetDCHook( dce->hdc, dc_hook, (DWORD_PTR)dce );
SetHookFlags( dce->hdc, DCHF_INVALIDATEVISRGN );
return dce; return dce;
} }
...@@ -445,7 +442,7 @@ static struct dce *get_window_dce( HWND hwnd ) ...@@ -445,7 +442,7 @@ static struct dce *get_window_dce( HWND hwnd )
if (dce_to_free) if (dce_to_free)
{ {
SetDCHook( dce_to_free->hdc, NULL, 0 ); set_dc_dce( dce_to_free->hdc, NULL );
NtGdiDeleteObjectApp( dce_to_free->hdc ); NtGdiDeleteObjectApp( dce_to_free->hdc );
free( dce_to_free ); free( dce_to_free );
if (dce_to_free == dce) if (dce_to_free == dce)
...@@ -494,7 +491,7 @@ void free_dce( struct dce *dce, HWND hwnd ) ...@@ -494,7 +491,7 @@ void free_dce( struct dce *dce, HWND hwnd )
{ {
WARN( "GetDC() without ReleaseDC() for window %p\n", hwnd ); WARN( "GetDC() without ReleaseDC() for window %p\n", hwnd );
dce->count = 0; dce->count = 0;
SetHookFlags( dce->hdc, DCHF_DISABLEDC ); set_dce_flags( dce->hdc, DCHF_DISABLEDC );
} }
} }
} }
...@@ -503,7 +500,7 @@ void free_dce( struct dce *dce, HWND hwnd ) ...@@ -503,7 +500,7 @@ void free_dce( struct dce *dce, HWND hwnd )
if (dce_to_free) if (dce_to_free)
{ {
SetDCHook( dce_to_free->hdc, NULL, 0 ); set_dc_dce( dce_to_free->hdc, NULL );
NtGdiDeleteObjectApp( dce_to_free->hdc ); NtGdiDeleteObjectApp( dce_to_free->hdc );
free( dce_to_free ); free( dce_to_free );
} }
...@@ -526,7 +523,7 @@ static void make_dc_dirty( struct dce *dce ) ...@@ -526,7 +523,7 @@ static void make_dc_dirty( struct dce *dce )
{ {
/* Set dirty bits in the hDC and DCE structs */ /* Set dirty bits in the hDC and DCE structs */
TRACE("fixed up %p hwnd %p\n", dce->hdc, dce->hwnd); TRACE("fixed up %p hwnd %p\n", dce->hdc, dce->hwnd);
SetHookFlags( dce->hdc, DCHF_INVALIDATEVISRGN ); set_dce_flags( dce->hdc, DCHF_INVALIDATEVISRGN );
} }
} }
...@@ -596,15 +593,15 @@ static INT release_dc( HWND hwnd, HDC hdc, BOOL end_paint ) ...@@ -596,15 +593,15 @@ static INT release_dc( HWND hwnd, HDC hdc, BOOL end_paint )
TRACE( "%p %p\n", hwnd, hdc ); TRACE( "%p %p\n", hwnd, hdc );
user_lock(); user_lock();
dce = (struct dce *)GetDCHook( hdc, NULL ); dce = get_dc_dce( hdc );
if (dce && dce->count && dce->hwnd) if (dce && dce->count && dce->hwnd)
{ {
if (!(dce->flags & DCX_NORESETATTRS)) SetHookFlags( dce->hdc, DCHF_RESETDC ); if (!(dce->flags & DCX_NORESETATTRS)) set_dce_flags( dce->hdc, DCHF_RESETDC );
if (end_paint || (dce->flags & DCX_CACHE)) delete_clip_rgn( dce ); if (end_paint || (dce->flags & DCX_CACHE)) delete_clip_rgn( dce );
if (dce->flags & DCX_CACHE) if (dce->flags & DCX_CACHE)
{ {
dce->count = 0; dce->count = 0;
SetHookFlags( dce->hdc, DCHF_DISABLEDC ); set_dce_flags( dce->hdc, DCHF_DISABLEDC );
} }
ret = TRUE; ret = TRUE;
} }
...@@ -703,7 +700,7 @@ HDC WINAPI NtUserGetDCEx( HWND hwnd, HRGN clip_rgn, DWORD flags ) ...@@ -703,7 +700,7 @@ HDC WINAPI NtUserGetDCEx( HWND hwnd, HRGN clip_rgn, DWORD flags )
if (dce) if (dce)
{ {
dce->count = 1; dce->count = 1;
SetHookFlags( dce->hdc, DCHF_ENABLEDC ); set_dce_flags( dce->hdc, DCHF_ENABLEDC );
} }
user_unlock(); user_unlock();
...@@ -749,7 +746,7 @@ HDC WINAPI NtUserGetDCEx( HWND hwnd, HRGN clip_rgn, DWORD flags ) ...@@ -749,7 +746,7 @@ HDC WINAPI NtUserGetDCEx( HWND hwnd, HRGN clip_rgn, DWORD flags )
/* cross-process invalidation is not supported yet, so always update the vis rgn */ /* cross-process invalidation is not supported yet, so always update the vis rgn */
if (!is_current_process_window( hwnd )) update_vis_rgn = TRUE; if (!is_current_process_window( hwnd )) update_vis_rgn = TRUE;
if (SetHookFlags( dce->hdc, DCHF_VALIDATEVISRGN )) update_vis_rgn = TRUE; /* DC was dirty */ if (set_dce_flags( dce->hdc, DCHF_VALIDATEVISRGN )) update_vis_rgn = TRUE; /* DC was dirty */
if (update_vis_rgn) update_visible_region( dce ); if (update_vis_rgn) update_visible_region( dce );
...@@ -775,7 +772,7 @@ HWND WINAPI NtUserWindowFromDC( HDC hdc ) ...@@ -775,7 +772,7 @@ HWND WINAPI NtUserWindowFromDC( HDC hdc )
HWND hwnd = 0; HWND hwnd = 0;
user_lock(); user_lock();
dce = (struct dce *)GetDCHook( hdc, NULL ); dce = get_dc_dce( hdc );
if (dce) hwnd = dce->hwnd; if (dce) hwnd = dce->hwnd;
user_unlock(); user_unlock();
return hwnd; return hwnd;
......
...@@ -54,8 +54,7 @@ typedef struct tagDC ...@@ -54,8 +54,7 @@ typedef struct tagDC
LONG dirty; /* dirty flag */ LONG dirty; /* dirty flag */
DC_ATTR *attr; /* DC attributes accessible by client */ DC_ATTR *attr; /* DC attributes accessible by client */
struct tagDC *saved_dc; struct tagDC *saved_dc;
DWORD_PTR dwHookData; struct dce *dce; /* associated dce, if any */
DCHOOKPROC hookProc; /* DC hook */
BOOL bounds_enabled:1; /* bounds tracking is enabled */ BOOL bounds_enabled:1; /* bounds tracking is enabled */
BOOL path_open:1; /* path is currently open (only for saved DCs) */ BOOL path_open:1; /* path is currently open (only for saved DCs) */
BOOL is_display:1; /* DC is for display device */ BOOL is_display:1; /* DC is for display device */
...@@ -89,6 +88,15 @@ typedef struct tagDC ...@@ -89,6 +88,15 @@ typedef struct tagDC
RECT bounds; /* Current bounding rect */ RECT bounds; /* Current bounding rect */
} DC; } DC;
/* dce flags */
#define DCHC_INVALIDVISRGN 0x0001
#define DCHC_DELETEDC 0x0002
#define DCHF_INVALIDATEVISRGN 0x0001
#define DCHF_VALIDATEVISRGN 0x0002
#define DCHF_RESETDC 0x0004
#define DCHF_DISABLEDC 0x0008
#define DCHF_ENABLEDC 0x0010
/* Rounds a floating point number to integer. The world-to-viewport /* Rounds a floating point number to integer. The world-to-viewport
* transformation process is done in floating point internally. This function * transformation process is done in floating point internally. This function
* is then used to round these coordinates to integer values. * is then used to round these coordinates to integer values.
...@@ -167,8 +175,10 @@ extern DC *alloc_dc_ptr( DWORD magic ) DECLSPEC_HIDDEN; ...@@ -167,8 +175,10 @@ extern DC *alloc_dc_ptr( DWORD magic ) DECLSPEC_HIDDEN;
extern void free_dc_ptr( DC *dc ) DECLSPEC_HIDDEN; extern void free_dc_ptr( DC *dc ) DECLSPEC_HIDDEN;
extern DC *get_dc_ptr( HDC hdc ) DECLSPEC_HIDDEN; extern DC *get_dc_ptr( HDC hdc ) DECLSPEC_HIDDEN;
extern void release_dc_ptr( DC *dc ) DECLSPEC_HIDDEN; extern void release_dc_ptr( DC *dc ) DECLSPEC_HIDDEN;
extern struct dce *get_dc_dce( HDC hdc ) DECLSPEC_HIDDEN;
extern void set_dc_dce( HDC hdc, struct dce *dce ) DECLSPEC_HIDDEN;
extern WORD set_dce_flags( HDC hdc, WORD flags ) DECLSPEC_HIDDEN;
extern DWORD set_stretch_blt_mode( HDC hdc, DWORD mode ) DECLSPEC_HIDDEN; extern DWORD set_stretch_blt_mode( HDC hdc, DWORD mode ) DECLSPEC_HIDDEN;
extern void update_dc( DC *dc ) DECLSPEC_HIDDEN;
extern void DC_InitDC( DC * dc ) DECLSPEC_HIDDEN; extern void DC_InitDC( DC * dc ) DECLSPEC_HIDDEN;
extern void DC_UpdateXforms( DC * dc ) DECLSPEC_HIDDEN; extern void DC_UpdateXforms( DC * dc ) DECLSPEC_HIDDEN;
...@@ -413,6 +423,10 @@ extern BOOL REGION_FrameRgn( HRGN dest, HRGN src, INT x, INT y ) DECLSPEC_HIDDEN ...@@ -413,6 +423,10 @@ extern BOOL REGION_FrameRgn( HRGN dest, HRGN src, INT x, INT y ) DECLSPEC_HIDDEN
extern HRGN create_polypolygon_region( const POINT *pts, const INT *count, INT nbpolygons, extern HRGN create_polypolygon_region( const POINT *pts, const INT *count, INT nbpolygons,
INT mode, const RECT *clip_rect ) DECLSPEC_HIDDEN; INT mode, const RECT *clip_rect ) DECLSPEC_HIDDEN;
/* dce.c */
extern BOOL delete_dce( struct dce *dce ) DECLSPEC_HIDDEN;
extern void update_dc( DC *dc ) DECLSPEC_HIDDEN;
#define RGN_DEFAULT_RECTS 4 #define RGN_DEFAULT_RECTS 4
typedef struct typedef struct
{ {
......
...@@ -4636,7 +4636,7 @@ ULONG_PTR WINAPI NtUserCallOneParam( ULONG_PTR arg, ULONG code ) ...@@ -4636,7 +4636,7 @@ ULONG_PTR WINAPI NtUserCallOneParam( ULONG_PTR arg, ULONG code )
case NtUserCreateCursorIcon: case NtUserCreateCursorIcon:
return HandleToUlong( alloc_cursoricon_handle( arg )); return HandleToUlong( alloc_cursoricon_handle( arg ));
case NtUserEnableDC: case NtUserEnableDC:
return SetHookFlags( UlongToHandle(arg), DCHF_ENABLEDC ); return set_dce_flags( UlongToHandle(arg), DCHF_ENABLEDC );
case NtUserGetClipCursor: case NtUserGetClipCursor:
return get_clip_cursor( (RECT *)arg ); return get_clip_cursor( (RECT *)arg );
case NtUserGetCursorPos: case NtUserGetCursorPos:
......
...@@ -327,23 +327,6 @@ struct user_driver_funcs ...@@ -327,23 +327,6 @@ struct user_driver_funcs
}; };
extern void CDECL __wine_set_user_driver( const struct user_driver_funcs *funcs, UINT version ); extern void CDECL __wine_set_user_driver( const struct user_driver_funcs *funcs, UINT version );
/* the DC hook support is only exported on Win16, the 32-bit version is a Wine extension */
#define DCHC_INVALIDVISRGN 0x0001
#define DCHC_DELETEDC 0x0002
#define DCHF_INVALIDATEVISRGN 0x0001
#define DCHF_VALIDATEVISRGN 0x0002
#define DCHF_RESETDC 0x0004 /* Wine extension */
#define DCHF_DISABLEDC 0x0008 /* Wine extension */
#define DCHF_ENABLEDC 0x0010 /* Wine extension */
typedef BOOL (CALLBACK *DCHOOKPROC)(HDC,WORD,DWORD_PTR,LPARAM);
WINGDIAPI DWORD_PTR WINAPI GetDCHook(HDC,DCHOOKPROC*);
WINGDIAPI BOOL WINAPI SetDCHook(HDC,DCHOOKPROC,DWORD_PTR);
WINGDIAPI WORD WINAPI SetHookFlags(HDC,WORD);
extern void CDECL __wine_set_visible_region( HDC hdc, HRGN hrgn, const RECT *vis_rect, extern void CDECL __wine_set_visible_region( HDC hdc, HRGN hrgn, const RECT *vis_rect,
const RECT *device_rect, struct window_surface *surface ); const RECT *device_rect, struct window_surface *surface );
extern void CDECL __wine_set_display_driver( struct user_driver_funcs *funcs, UINT version ); extern void CDECL __wine_set_display_driver( struct user_driver_funcs *funcs, UINT version );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment