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 )
}
/***********************************************************************
* 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 )
{
PHYSDEV physdev = GET_DC_PHYSDEV( dc, pSetBkColor );
......@@ -524,7 +510,7 @@ static BOOL DC_DeleteObject( HGDIOBJ handle )
/* Call hook procedure to check whether is it OK to delete this DC,
* 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 );
return TRUE;
......@@ -1035,57 +1021,43 @@ BOOL WINAPI NtGdiGetTransform( HDC hdc, DWORD which, XFORM *xform )
/***********************************************************************
* SetDCHook (win32u.@)
*
* Note: this doesn't exist in Win32, we add it here because user32 needs it.
* set_dc_dce
*/
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)
{
GDI_ReleaseObj( hdc );
return 0;
return;
}
dc->dwHookData = dwHookData;
dc->hookProc = hookProc;
dc->dce = dce;
if (dce) dc->dirty = 1;
GDI_ReleaseObj( hdc );
return TRUE;
}
/***********************************************************************
* GetDCHook (win32u.@)
*
* Note: this doesn't exist in Win32, we add it here because user32 needs it.
* get_dc_dce
*/
DWORD_PTR WINAPI GetDCHook( HDC hdc, DCHOOKPROC *proc )
struct dce *get_dc_dce( HDC hdc )
{
DC *dc = get_dc_obj( hdc );
DWORD_PTR ret;
struct dce *ret = NULL;
if (!dc) return 0;
if (dc->attr->disabled)
{
GDI_ReleaseObj( hdc );
return 0;
}
if (proc) *proc = dc->hookProc;
ret = dc->dwHookData;
if (!dc->attr->disabled) ret = dc->dce;
GDI_ReleaseObj( hdc );
return ret;
}
/***********************************************************************
* SetHookFlags (win32u.@)
*
* Note: this doesn't exist in Win32, we add it here because user32 needs it.
* set_dce_flags
*/
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 */
LONG ret = 0;
......
......@@ -294,52 +294,51 @@ static void delete_clip_rgn( struct dce *dce )
dce->clip_rgn = 0;
/* 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
*
* See "Undoc. Windows" for hints (DC, SetDCHook, SetHookFlags)..
* delete_dce
*/
static BOOL CALLBACK dc_hook( HDC hDC, WORD code, DWORD_PTR data, LPARAM lParam )
BOOL delete_dce( struct dce *dce )
{
BOOL retv = TRUE;
struct dce *dce = (struct dce *)data;
BOOL ret = TRUE;
TRACE("hDC = %p, %u\n", hDC, code);
TRACE( "hdc = %p\n", dce->hdc );
if (!dce) return FALSE;
assert( dce->hdc == hDC );
user_lock();
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:
/* 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 );
if (dc->dce->count) update_visible_region( dc->dce );
else /* non-fatal but shouldn't happen */
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)
dce->flags = 0;
dce->count = 1;
/* store DCE handle in DC hook data field */
SetDCHook( dce->hdc, dc_hook, (DWORD_PTR)dce );
SetHookFlags( dce->hdc, DCHF_INVALIDATEVISRGN );
set_dc_dce( dce->hdc, dce );
return dce;
}
......@@ -445,7 +442,7 @@ static struct dce *get_window_dce( HWND hwnd )
if (dce_to_free)
{
SetDCHook( dce_to_free->hdc, NULL, 0 );
set_dc_dce( dce_to_free->hdc, NULL );
NtGdiDeleteObjectApp( dce_to_free->hdc );
free( dce_to_free );
if (dce_to_free == dce)
......@@ -494,7 +491,7 @@ void free_dce( struct dce *dce, HWND hwnd )
{
WARN( "GetDC() without ReleaseDC() for window %p\n", hwnd );
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 )
if (dce_to_free)
{
SetDCHook( dce_to_free->hdc, NULL, 0 );
set_dc_dce( dce_to_free->hdc, NULL );
NtGdiDeleteObjectApp( dce_to_free->hdc );
free( dce_to_free );
}
......@@ -526,7 +523,7 @@ static void make_dc_dirty( struct dce *dce )
{
/* Set dirty bits in the hDC and DCE structs */
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 )
TRACE( "%p %p\n", hwnd, hdc );
user_lock();
dce = (struct dce *)GetDCHook( hdc, NULL );
dce = get_dc_dce( hdc );
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 (dce->flags & DCX_CACHE)
{
dce->count = 0;
SetHookFlags( dce->hdc, DCHF_DISABLEDC );
set_dce_flags( dce->hdc, DCHF_DISABLEDC );
}
ret = TRUE;
}
......@@ -703,7 +700,7 @@ HDC WINAPI NtUserGetDCEx( HWND hwnd, HRGN clip_rgn, DWORD flags )
if (dce)
{
dce->count = 1;
SetHookFlags( dce->hdc, DCHF_ENABLEDC );
set_dce_flags( dce->hdc, DCHF_ENABLEDC );
}
user_unlock();
......@@ -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 */
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 );
......@@ -775,7 +772,7 @@ HWND WINAPI NtUserWindowFromDC( HDC hdc )
HWND hwnd = 0;
user_lock();
dce = (struct dce *)GetDCHook( hdc, NULL );
dce = get_dc_dce( hdc );
if (dce) hwnd = dce->hwnd;
user_unlock();
return hwnd;
......
......@@ -54,8 +54,7 @@ typedef struct tagDC
LONG dirty; /* dirty flag */
DC_ATTR *attr; /* DC attributes accessible by client */
struct tagDC *saved_dc;
DWORD_PTR dwHookData;
DCHOOKPROC hookProc; /* DC hook */
struct dce *dce; /* associated dce, if any */
BOOL bounds_enabled:1; /* bounds tracking is enabled */
BOOL path_open:1; /* path is currently open (only for saved DCs) */
BOOL is_display:1; /* DC is for display device */
......@@ -89,6 +88,15 @@ typedef struct tagDC
RECT bounds; /* Current bounding rect */
} 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
* transformation process is done in floating point internally. This function
* is then used to round these coordinates to integer values.
......@@ -167,8 +175,10 @@ extern DC *alloc_dc_ptr( DWORD magic ) DECLSPEC_HIDDEN;
extern void free_dc_ptr( DC *dc ) DECLSPEC_HIDDEN;
extern DC *get_dc_ptr( HDC hdc ) 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 void update_dc( DC *dc ) DECLSPEC_HIDDEN;
extern void DC_InitDC( 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
extern HRGN create_polypolygon_region( const POINT *pts, const INT *count, INT nbpolygons,
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
typedef struct
{
......
......@@ -4636,7 +4636,7 @@ ULONG_PTR WINAPI NtUserCallOneParam( ULONG_PTR arg, ULONG code )
case NtUserCreateCursorIcon:
return HandleToUlong( alloc_cursoricon_handle( arg ));
case NtUserEnableDC:
return SetHookFlags( UlongToHandle(arg), DCHF_ENABLEDC );
return set_dce_flags( UlongToHandle(arg), DCHF_ENABLEDC );
case NtUserGetClipCursor:
return get_clip_cursor( (RECT *)arg );
case NtUserGetCursorPos:
......
......@@ -327,23 +327,6 @@ struct user_driver_funcs
};
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,
const RECT *device_rect, struct window_surface *surface );
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