gdi32: Use NtGdiCreateClientObj for CreateMetaFile.
Instead of alloc_dc_ptr. Metafile DCs are not real DCs. Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Huw Davies <huw@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
728f96bf8a
commit
6167fd3290
|
@ -55,7 +55,6 @@ static inline DC *get_dc_obj( HDC hdc )
|
|||
{
|
||||
case NTGDI_OBJ_DC:
|
||||
case NTGDI_OBJ_MEMDC:
|
||||
case NTGDI_OBJ_METADC:
|
||||
case NTGDI_OBJ_ENHMETADC:
|
||||
return dc;
|
||||
default:
|
||||
|
@ -755,6 +754,8 @@ BOOL WINAPI DeleteDC( HDC hdc )
|
|||
|
||||
TRACE("%p\n", hdc );
|
||||
|
||||
if (is_meta_dc( hdc )) return METADC_DeleteDC( hdc );
|
||||
|
||||
GDI_CheckNotLock();
|
||||
|
||||
if (!(dc = get_dc_ptr( hdc ))) return FALSE;
|
||||
|
|
|
@ -52,6 +52,7 @@ extern BOOL METADC_BitBlt( HDC hdc_dst, INT x_dst, INT y_dst, INT width, INT hei
|
|||
HDC hdc_src, INT x_src, INT y_src, DWORD rop );
|
||||
extern BOOL METADC_Chord( HDC hdc, INT left, INT top, INT right, INT bottom, INT xstart,
|
||||
INT ystart, INT xend, INT yend ) DECLSPEC_HIDDEN;
|
||||
extern BOOL METADC_DeleteDC( HDC hdc );
|
||||
extern BOOL METADC_Ellipse( HDC hdc, INT left, INT top, INT right, INT bottom ) DECLSPEC_HIDDEN;
|
||||
extern BOOL METADC_ExcludeClipRect( HDC hdc, INT left, INT top, INT right,
|
||||
INT bottom ) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -149,63 +149,3 @@ BOOL METADC_SetMapperFlags( HDC hdc, DWORD flags )
|
|||
{
|
||||
return metadc_param2( hdc, META_SETMAPPERFLAGS, HIWORD(flags), LOWORD(flags) );
|
||||
}
|
||||
|
||||
BOOL CDECL MFDRV_AbortPath( PHYSDEV dev )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL CDECL MFDRV_BeginPath( PHYSDEV dev )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL CDECL MFDRV_CloseFigure( PHYSDEV dev )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL CDECL MFDRV_EndPath( PHYSDEV dev )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL CDECL MFDRV_FillPath( PHYSDEV dev )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL CDECL MFDRV_FlattenPath( PHYSDEV dev )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL CDECL MFDRV_SelectClipPath( PHYSDEV dev, INT iMode )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL CDECL MFDRV_StrokeAndFillPath( PHYSDEV dev )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL CDECL MFDRV_StrokePath( PHYSDEV dev )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL CDECL MFDRV_WidenPath( PHYSDEV dev )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
COLORREF CDECL MFDRV_SetDCBrushColor( PHYSDEV dev, COLORREF color )
|
||||
{
|
||||
return CLR_INVALID;
|
||||
}
|
||||
|
||||
COLORREF CDECL MFDRV_SetDCPenColor( PHYSDEV dev, COLORREF color )
|
||||
{
|
||||
return CLR_INVALID;
|
||||
}
|
||||
|
|
|
@ -58,16 +58,6 @@ BOOL METADC_Arc( HDC hdc, INT left, INT top, INT right, INT bottom,
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* MFDRV_ArcTo
|
||||
*/
|
||||
BOOL CDECL MFDRV_ArcTo( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
|
||||
INT xstart, INT ystart, INT xend, INT yend )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* METADC_Pie
|
||||
*/
|
||||
|
@ -400,14 +390,6 @@ BOOL METADC_FillRgn( HDC hdc, HRGN hrgn, HBRUSH hbrush )
|
|||
return metadc_param2( hdc, META_FILLREGION, iRgn, iBrush );
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* MFDRV_FillRgn
|
||||
*/
|
||||
BOOL CDECL MFDRV_FillRgn( PHYSDEV dev, HRGN hrgn, HBRUSH hbrush )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* METADC_FrameRgn
|
||||
*/
|
||||
|
@ -446,24 +428,3 @@ BOOL METADC_ExtSelectClipRgn( HDC hdc, HRGN hrgn, INT mode )
|
|||
metadc_remove_handle( metadc, iRgn );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* MFDRV_PolyBezier
|
||||
* Since MetaFiles don't record Beziers and they don't even record
|
||||
* approximations to them using lines, we need this stub function.
|
||||
*/
|
||||
BOOL CDECL MFDRV_PolyBezier( PHYSDEV dev, const POINT *pts, DWORD count )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* MFDRV_PolyBezierTo
|
||||
* Since MetaFiles don't record Beziers and they don't even record
|
||||
* approximations to them using lines, we need this stub function.
|
||||
*/
|
||||
BOOL CDECL MFDRV_PolyBezierTo( PHYSDEV dev, const POINT *pts, DWORD count )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
|
|
@ -30,9 +30,6 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(metafile);
|
||||
|
||||
static BOOL CDECL MFDRV_CreateCompatibleDC( PHYSDEV orig, PHYSDEV *pdev );
|
||||
static BOOL CDECL MFDRV_DeleteDC( PHYSDEV dev );
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* METADC_ExtEscape
|
||||
|
@ -59,24 +56,6 @@ BOOL METADC_ExtEscape( HDC hdc, INT escape, INT input_size, const void *input,
|
|||
}
|
||||
|
||||
|
||||
/******************************************************************
|
||||
* MFDRV_GetBoundsRect
|
||||
*/
|
||||
static UINT CDECL MFDRV_GetBoundsRect( PHYSDEV dev, RECT *rect, UINT flags )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************
|
||||
* MFDRV_SetBoundsRect
|
||||
*/
|
||||
static UINT CDECL MFDRV_SetBoundsRect( PHYSDEV dev, RECT *rect, UINT flags )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************
|
||||
* METADC_GetDeviceCaps
|
||||
*
|
||||
|
@ -98,184 +77,29 @@ INT METADC_GetDeviceCaps( HDC hdc, INT cap )
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static const struct gdi_dc_funcs MFDRV_Funcs =
|
||||
static void metadc_free( struct metadc *metadc )
|
||||
{
|
||||
NULL, /* pAbortDoc */
|
||||
MFDRV_AbortPath, /* pAbortPath */
|
||||
NULL, /* pAlphaBlend */
|
||||
NULL, /* pAngleArc */
|
||||
NULL, /* pArc */
|
||||
MFDRV_ArcTo, /* pArcTo */
|
||||
MFDRV_BeginPath, /* pBeginPath */
|
||||
NULL, /* pBlendImage */
|
||||
NULL, /* pChord */
|
||||
MFDRV_CloseFigure, /* pCloseFigure */
|
||||
MFDRV_CreateCompatibleDC, /* pCreateCompatibleDC */
|
||||
NULL, /* pCreateDC */
|
||||
MFDRV_DeleteDC, /* pDeleteDC */
|
||||
NULL, /* pDeleteObject */
|
||||
NULL, /* pDeviceCapabilities */
|
||||
NULL, /* pEllipse */
|
||||
NULL, /* pEndDoc */
|
||||
NULL, /* pEndPage */
|
||||
MFDRV_EndPath, /* pEndPath */
|
||||
NULL, /* pEnumFonts */
|
||||
NULL, /* pEnumICMProfiles */
|
||||
NULL, /* pExtDeviceMode */
|
||||
NULL, /* pExtEscape */
|
||||
NULL, /* pExtFloodFill */
|
||||
NULL, /* pExtTextOut */
|
||||
MFDRV_FillPath, /* pFillPath */
|
||||
MFDRV_FillRgn, /* pFillRgn */
|
||||
MFDRV_FlattenPath, /* pFlattenPath */
|
||||
NULL, /* pFontIsLinked */
|
||||
NULL, /* pFrameRgn */
|
||||
NULL, /* pGdiComment */
|
||||
MFDRV_GetBoundsRect, /* pGetBoundsRect */
|
||||
NULL, /* pGetCharABCWidths */
|
||||
NULL, /* pGetCharABCWidthsI */
|
||||
NULL, /* pGetCharWidth */
|
||||
NULL, /* pGetCharWidthInfo */
|
||||
NULL, /* pGetDeviceCaps */
|
||||
NULL, /* pGetDeviceGammaRamp */
|
||||
NULL, /* pGetFontData */
|
||||
NULL, /* pGetFontRealizationInfo */
|
||||
NULL, /* pGetFontUnicodeRanges */
|
||||
NULL, /* pGetGlyphIndices */
|
||||
NULL, /* pGetGlyphOutline */
|
||||
NULL, /* pGetICMProfile */
|
||||
NULL, /* pGetImage */
|
||||
NULL, /* pGetKerningPairs */
|
||||
NULL, /* pGetNearestColor */
|
||||
NULL, /* pGetOutlineTextMetrics */
|
||||
NULL, /* pGetPixel */
|
||||
NULL, /* pGetSystemPaletteEntries */
|
||||
NULL, /* pGetTextCharsetInfo */
|
||||
NULL, /* pGetTextExtentExPoint */
|
||||
NULL, /* pGetTextExtentExPointI */
|
||||
NULL, /* pGetTextFace */
|
||||
NULL, /* pGetTextMetrics */
|
||||
NULL, /* pGradientFill */
|
||||
NULL, /* pInvertRgn */
|
||||
NULL, /* pLineTo */
|
||||
NULL, /* pMoveTo */
|
||||
NULL, /* pPaintRgn */
|
||||
NULL, /* pPatBlt */
|
||||
NULL, /* pPie */
|
||||
MFDRV_PolyBezier, /* pPolyBezier */
|
||||
MFDRV_PolyBezierTo, /* pPolyBezierTo */
|
||||
NULL, /* pPolyDraw */
|
||||
NULL, /* pPolyPolygon */
|
||||
NULL, /* pPolyPolyline */
|
||||
NULL, /* pPolylineTo */
|
||||
NULL, /* pPutImage */
|
||||
NULL, /* pRealizeDefaultPalette */
|
||||
NULL, /* pRealizePalette */
|
||||
NULL, /* pRectangle */
|
||||
NULL, /* pResetDC */
|
||||
NULL, /* pRestoreDC */
|
||||
NULL, /* pRoundRect */
|
||||
NULL, /* pSelectBitmap */
|
||||
NULL, /* pSelectBrush */
|
||||
MFDRV_SelectClipPath, /* pSelectClipPath */
|
||||
NULL, /* pSelectFont */
|
||||
NULL, /* pSelectPen */
|
||||
NULL, /* pSetBkColor */
|
||||
MFDRV_SetBoundsRect, /* pSetBoundsRect */
|
||||
MFDRV_SetDCBrushColor, /* pSetDCBrushColor*/
|
||||
MFDRV_SetDCPenColor, /* pSetDCPenColor*/
|
||||
NULL, /* pSetDIBitsToDevice */
|
||||
NULL, /* pSetDeviceClipping */
|
||||
NULL, /* pSetDeviceGammaRamp */
|
||||
NULL, /* pSetPixel */
|
||||
NULL, /* pSetTextColor */
|
||||
NULL, /* pStartDoc */
|
||||
NULL, /* pStartPage */
|
||||
NULL, /* pStretchBlt */
|
||||
NULL, /* pStretchDIBits */
|
||||
MFDRV_StrokeAndFillPath, /* pStrokeAndFillPath */
|
||||
MFDRV_StrokePath, /* pStrokePath */
|
||||
NULL, /* pUnrealizePalette */
|
||||
MFDRV_WidenPath, /* pWidenPath */
|
||||
NULL, /* pD3DKMTCheckVidPnExclusiveOwnership */
|
||||
NULL, /* pD3DKMTSetVidPnSourceOwner */
|
||||
NULL, /* wine_get_wgl_driver */
|
||||
NULL, /* wine_get_vulkan_driver */
|
||||
GDI_PRIORITY_GRAPHICS_DRV /* priority */
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* MFDRV_AllocMetaFile
|
||||
*/
|
||||
static DC *MFDRV_AllocMetaFile(void)
|
||||
{
|
||||
DC *dc;
|
||||
struct metadc *physDev;
|
||||
|
||||
if (!(dc = alloc_dc_ptr( NTGDI_OBJ_METADC ))) return NULL;
|
||||
|
||||
physDev = HeapAlloc(GetProcessHeap(),0,sizeof(*physDev));
|
||||
if (!physDev)
|
||||
{
|
||||
free_dc_ptr( dc );
|
||||
return NULL;
|
||||
}
|
||||
if (!(physDev->mh = HeapAlloc( GetProcessHeap(), 0, sizeof(*physDev->mh) )))
|
||||
{
|
||||
HeapFree( GetProcessHeap(), 0, physDev );
|
||||
free_dc_ptr( dc );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
push_dc_driver( &dc->physDev, &physDev->dev, &MFDRV_Funcs );
|
||||
set_gdi_client_ptr( dc->hSelf, physDev );
|
||||
|
||||
physDev->handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, HANDLE_LIST_INC * sizeof(physDev->handles[0]));
|
||||
physDev->handles_size = HANDLE_LIST_INC;
|
||||
physDev->cur_handles = 0;
|
||||
|
||||
physDev->hFile = 0;
|
||||
|
||||
physDev->mh->mtHeaderSize = sizeof(METAHEADER) / sizeof(WORD);
|
||||
physDev->mh->mtVersion = 0x0300;
|
||||
physDev->mh->mtSize = physDev->mh->mtHeaderSize;
|
||||
physDev->mh->mtNoObjects = 0;
|
||||
physDev->mh->mtMaxRecord = 0;
|
||||
physDev->mh->mtNoParameters = 0;
|
||||
|
||||
NtGdiSetVirtualResolution( physDev->dev.hdc, 0, 0, 0, 0);
|
||||
|
||||
return dc;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* MFDRV_CreateCompatibleDC
|
||||
*/
|
||||
static BOOL CDECL MFDRV_CreateCompatibleDC( PHYSDEV orig, PHYSDEV *pdev )
|
||||
{
|
||||
/* not supported on metafile DCs */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* MFDRV_DeleteDC
|
||||
*/
|
||||
static BOOL CDECL MFDRV_DeleteDC( PHYSDEV dev )
|
||||
{
|
||||
struct metadc *physDev = (struct metadc *)dev;
|
||||
DWORD index;
|
||||
|
||||
HeapFree( GetProcessHeap(), 0, physDev->mh );
|
||||
for(index = 0; index < physDev->handles_size; index++)
|
||||
if(physDev->handles[index])
|
||||
GDI_hdc_not_using_object(physDev->handles[index], dev->hdc);
|
||||
HeapFree( GetProcessHeap(), 0, physDev->handles );
|
||||
HeapFree( GetProcessHeap(), 0, physDev );
|
||||
CloseHandle( metadc->hFile );
|
||||
HeapFree( GetProcessHeap(), 0, metadc->mh );
|
||||
for(index = 0; index < metadc->handles_size; index++)
|
||||
if(metadc->handles[index])
|
||||
GDI_hdc_not_using_object( metadc->handles[index], metadc->hdc );
|
||||
HeapFree( GetProcessHeap(), 0, metadc->handles );
|
||||
HeapFree( GetProcessHeap(), 0, metadc );
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* METADC_DeleteObject
|
||||
*/
|
||||
BOOL METADC_DeleteDC( HDC hdc )
|
||||
{
|
||||
struct metadc *metadc;
|
||||
|
||||
if (!(metadc = get_metadc_ptr( hdc ))) return FALSE;
|
||||
if (!NtGdiDeleteClientObj( hdc )) return FALSE;
|
||||
metadc_free( metadc );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -294,34 +118,62 @@ static BOOL CDECL MFDRV_DeleteDC( PHYSDEV dev )
|
|||
*/
|
||||
HDC WINAPI CreateMetaFileW( LPCWSTR filename )
|
||||
{
|
||||
HDC ret;
|
||||
DC *dc;
|
||||
struct metadc *physDev;
|
||||
HANDLE hFile;
|
||||
struct metadc *metadc;
|
||||
HANDLE hdc;
|
||||
|
||||
TRACE("%s\n", debugstr_w(filename) );
|
||||
|
||||
if (!(dc = MFDRV_AllocMetaFile())) return 0;
|
||||
physDev = (struct metadc *)dc->physDev;
|
||||
physDev->mh->mtType = METAFILE_MEMORY;
|
||||
physDev->pen = GetStockObject( BLACK_PEN );
|
||||
physDev->brush = GetStockObject( WHITE_BRUSH );
|
||||
physDev->font = GetStockObject( DEVICE_DEFAULT_FONT );
|
||||
if (!(hdc = NtGdiCreateClientObj( NTGDI_OBJ_METADC ))) return NULL;
|
||||
|
||||
metadc = HeapAlloc( GetProcessHeap(), 0, sizeof(*metadc) );
|
||||
if (!metadc)
|
||||
{
|
||||
NtGdiDeleteClientObj( hdc );
|
||||
return NULL;
|
||||
}
|
||||
if (!(metadc->mh = HeapAlloc( GetProcessHeap(), 0, sizeof(*metadc->mh) )))
|
||||
{
|
||||
HeapFree( GetProcessHeap(), 0, metadc );
|
||||
NtGdiDeleteClientObj( hdc );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
metadc->hdc = hdc;
|
||||
set_gdi_client_ptr( hdc, metadc );
|
||||
|
||||
metadc->handles = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||
HANDLE_LIST_INC * sizeof(metadc->handles[0]) );
|
||||
metadc->handles_size = HANDLE_LIST_INC;
|
||||
metadc->cur_handles = 0;
|
||||
|
||||
metadc->hFile = 0;
|
||||
|
||||
metadc->mh->mtHeaderSize = sizeof(METAHEADER) / sizeof(WORD);
|
||||
metadc->mh->mtVersion = 0x0300;
|
||||
metadc->mh->mtSize = metadc->mh->mtHeaderSize;
|
||||
metadc->mh->mtNoObjects = 0;
|
||||
metadc->mh->mtMaxRecord = 0;
|
||||
metadc->mh->mtNoParameters = 0;
|
||||
metadc->mh->mtType = METAFILE_MEMORY;
|
||||
|
||||
metadc->pen = GetStockObject( BLACK_PEN );
|
||||
metadc->brush = GetStockObject( WHITE_BRUSH );
|
||||
metadc->font = GetStockObject( DEVICE_DEFAULT_FONT );
|
||||
|
||||
if (filename) /* disk based metafile */
|
||||
{
|
||||
if ((hFile = CreateFileW(filename, GENERIC_WRITE, 0, NULL,
|
||||
CREATE_ALWAYS, 0, 0)) == INVALID_HANDLE_VALUE) {
|
||||
free_dc_ptr( dc );
|
||||
HANDLE file = CreateFileW( filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 );
|
||||
if (file == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
HeapFree( GetProcessHeap(), 0, metadc );
|
||||
NtGdiDeleteClientObj( hdc );
|
||||
return 0;
|
||||
}
|
||||
physDev->hFile = hFile;
|
||||
metadc->hFile = file;
|
||||
}
|
||||
|
||||
TRACE("returning %p\n", physDev->dev.hdc);
|
||||
ret = physDev->dev.hdc;
|
||||
release_dc_ptr( dc );
|
||||
return ret;
|
||||
TRACE("returning %p\n", hdc);
|
||||
return hdc;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
@ -349,54 +201,6 @@ HDC WINAPI CreateMetaFileA(LPCSTR filename)
|
|||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* MFDRV_CloseMetaFile
|
||||
*/
|
||||
static DC *MFDRV_CloseMetaFile( HDC hdc )
|
||||
{
|
||||
DC *dc;
|
||||
struct metadc *physDev;
|
||||
DWORD bytes_written;
|
||||
|
||||
TRACE("(%p)\n", hdc );
|
||||
|
||||
if (!(dc = get_dc_ptr( hdc ))) return NULL;
|
||||
if (GetObjectType( hdc ) != OBJ_METADC)
|
||||
{
|
||||
release_dc_ptr( dc );
|
||||
return NULL;
|
||||
}
|
||||
if (dc->refcount != 1)
|
||||
{
|
||||
FIXME( "not deleting busy DC %p refcount %u\n", hdc, dc->refcount );
|
||||
release_dc_ptr( dc );
|
||||
return NULL;
|
||||
}
|
||||
physDev = (struct metadc *)dc->physDev;
|
||||
|
||||
/* Construct the end of metafile record - this is documented
|
||||
* in SDK Knowledgebase Q99334.
|
||||
*/
|
||||
|
||||
if (!metadc_param0( hdc, META_EOF ))
|
||||
{
|
||||
free_dc_ptr( dc );
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (physDev->hFile) /* disk based metafile */
|
||||
{
|
||||
if (!WriteFile(physDev->hFile, physDev->mh, physDev->mh->mtSize * 2,
|
||||
&bytes_written, NULL)) {
|
||||
free_dc_ptr( dc );
|
||||
return 0;
|
||||
}
|
||||
CloseHandle(physDev->hFile);
|
||||
}
|
||||
|
||||
return dc;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* CloseMetaFile (GDI32.@)
|
||||
*
|
||||
|
@ -411,18 +215,31 @@ static DC *MFDRV_CloseMetaFile( HDC hdc )
|
|||
*/
|
||||
HMETAFILE WINAPI CloseMetaFile(HDC hdc)
|
||||
{
|
||||
struct metadc *metadc;
|
||||
DWORD bytes_written;
|
||||
HMETAFILE hmf;
|
||||
struct metadc *physDev;
|
||||
DC *dc = MFDRV_CloseMetaFile(hdc);
|
||||
if (!dc) return 0;
|
||||
physDev = (struct metadc *)dc->physDev;
|
||||
|
||||
TRACE("(%p)\n", hdc );
|
||||
|
||||
if (!(metadc = get_metadc_ptr( hdc ))) return FALSE;
|
||||
|
||||
/* Construct the end of metafile record - this is documented
|
||||
* in SDK Knowledgebase Q99334.
|
||||
*/
|
||||
if (!metadc_param0( hdc, META_EOF )) return FALSE;
|
||||
if (!NtGdiDeleteClientObj( hdc )) return FALSE;
|
||||
|
||||
if (metadc->hFile && !WriteFile( metadc->hFile, metadc->mh, metadc->mh->mtSize * sizeof(WORD),
|
||||
&bytes_written, NULL ))
|
||||
{
|
||||
metadc_free( metadc );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Now allocate a global handle for the metafile */
|
||||
|
||||
hmf = MF_Create_HMETAFILE( physDev->mh );
|
||||
|
||||
physDev->mh = NULL; /* So it won't be deleted */
|
||||
free_dc_ptr( dc );
|
||||
hmf = MF_Create_HMETAFILE( metadc->mh );
|
||||
if (hmf) metadc->mh = NULL; /* So it won't be deleted */
|
||||
metadc_free( metadc );
|
||||
return hmf;
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
|
||||
struct metadc
|
||||
{
|
||||
struct gdi_physdev dev;
|
||||
HDC hdc;
|
||||
METAHEADER *mh; /* Pointer to metafile header */
|
||||
UINT handles_size, cur_handles;
|
||||
HGDIOBJ *handles;
|
||||
|
@ -66,25 +66,4 @@ extern BOOL metadc_param8( HDC hdc, short func, short param1, short param2,
|
|||
extern BOOL metadc_record( HDC hdc, METARECORD *mr, DWORD rlen ) DECLSPEC_HIDDEN;
|
||||
extern BOOL metadc_write_record( struct metadc *metadc, METARECORD *mr, DWORD rlen ) DECLSPEC_HIDDEN;
|
||||
|
||||
/* Metafile driver functions */
|
||||
|
||||
extern BOOL CDECL MFDRV_AbortPath( PHYSDEV dev ) DECLSPEC_HIDDEN;
|
||||
extern BOOL CDECL MFDRV_ArcTo( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
|
||||
INT xstart, INT ystart, INT xend, INT yend ) DECLSPEC_HIDDEN;
|
||||
extern BOOL CDECL MFDRV_BeginPath( PHYSDEV dev ) DECLSPEC_HIDDEN;
|
||||
extern BOOL CDECL MFDRV_CloseFigure( PHYSDEV dev ) DECLSPEC_HIDDEN;
|
||||
extern BOOL CDECL MFDRV_EndPath( PHYSDEV dev ) DECLSPEC_HIDDEN;
|
||||
extern BOOL CDECL MFDRV_FillPath( PHYSDEV dev ) DECLSPEC_HIDDEN;
|
||||
extern BOOL CDECL MFDRV_FillRgn( PHYSDEV dev, HRGN hrgn, HBRUSH hbrush ) DECLSPEC_HIDDEN;
|
||||
extern BOOL CDECL MFDRV_FlattenPath( PHYSDEV dev ) DECLSPEC_HIDDEN;
|
||||
extern BOOL CDECL MFDRV_PolyBezier( PHYSDEV dev, const POINT* pt, DWORD count ) DECLSPEC_HIDDEN;
|
||||
extern BOOL CDECL MFDRV_PolyBezierTo( PHYSDEV dev, const POINT* pt, DWORD count ) DECLSPEC_HIDDEN;
|
||||
extern BOOL CDECL MFDRV_ScaleWindowExtEx( PHYSDEV dev, INT xNum, INT xDenom, INT yNum, INT yDenom, SIZE *size ) DECLSPEC_HIDDEN;
|
||||
extern BOOL CDECL MFDRV_SelectClipPath( PHYSDEV dev, INT iMode ) DECLSPEC_HIDDEN;
|
||||
extern COLORREF CDECL MFDRV_SetDCBrushColor( PHYSDEV dev, COLORREF color ) DECLSPEC_HIDDEN;
|
||||
extern COLORREF CDECL MFDRV_SetDCPenColor( PHYSDEV dev, COLORREF color ) DECLSPEC_HIDDEN;
|
||||
extern BOOL CDECL MFDRV_StrokeAndFillPath( PHYSDEV dev ) DECLSPEC_HIDDEN;
|
||||
extern BOOL CDECL MFDRV_StrokePath( PHYSDEV dev ) DECLSPEC_HIDDEN;
|
||||
extern BOOL CDECL MFDRV_WidenPath( PHYSDEV dev ) DECLSPEC_HIDDEN;
|
||||
|
||||
#endif /* __WINE_METAFILEDRV_H */
|
||||
|
|
|
@ -153,6 +153,8 @@ BOOL WINAPI DeleteObject( HGDIOBJ obj )
|
|||
struct hdc_list *hdc_list = NULL;
|
||||
struct wine_rb_entry *entry;
|
||||
|
||||
if (is_meta_dc( obj )) return METADC_DeleteDC( obj );
|
||||
|
||||
EnterCriticalSection( &obj_map_cs );
|
||||
|
||||
if ((entry = wine_rb_get( &obj_map, obj )))
|
||||
|
|
|
@ -3059,7 +3059,6 @@ static void test_metafile_file(void)
|
|||
|
||||
SetLastError(0xdeadbeef);
|
||||
metafile = CloseMetaFile(dc);
|
||||
todo_wine
|
||||
ok(!metafile && GetLastError() == ERROR_INVALID_HANDLE, "CloseMetaFile returned %p (%u)\n",
|
||||
metafile, GetLastError());
|
||||
|
||||
|
@ -3714,7 +3713,6 @@ static void test_mf_select(void)
|
|||
ok(ret, "DeleteObject failed: %u\n", GetLastError());
|
||||
|
||||
obj = GetCurrentObject(hdc, OBJ_PEN);
|
||||
todo_wine
|
||||
ok(!obj, "GetCurrentObject succeeded\n");
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
|
|
Loading…
Reference in New Issue