Commit 45f191dc authored by Alexandre Julliard's avatar Alexandre Julliard

gdi32: Properly manage the driver stack during DC creation and deletion.

parent 174e906a
...@@ -71,13 +71,13 @@ static inline DC *get_dc_obj( HDC hdc ) ...@@ -71,13 +71,13 @@ static inline DC *get_dc_obj( HDC hdc )
/*********************************************************************** /***********************************************************************
* alloc_dc_ptr * alloc_dc_ptr
*/ */
DC *alloc_dc_ptr( const DC_FUNCTIONS *funcs, WORD magic ) DC *alloc_dc_ptr( WORD magic )
{ {
DC *dc; DC *dc;
if (!(dc = HeapAlloc( GetProcessHeap(), 0, sizeof(*dc) ))) return NULL; if (!(dc = HeapAlloc( GetProcessHeap(), 0, sizeof(*dc) ))) return NULL;
dc->funcs = funcs; dc->funcs = &null_driver;
dc->nulldrv.funcs = &null_driver; dc->nulldrv.funcs = &null_driver;
dc->nulldrv.next = NULL; dc->nulldrv.next = NULL;
dc->physDev = &dc->nulldrv; dc->physDev = &dc->nulldrv;
...@@ -179,6 +179,8 @@ static void free_dc_state( DC *dc ) ...@@ -179,6 +179,8 @@ static void free_dc_state( DC *dc )
void free_dc_ptr( DC *dc ) void free_dc_ptr( DC *dc )
{ {
assert( dc->refcount == 1 ); assert( dc->refcount == 1 );
while (dc->physDev != &dc->nulldrv) pop_dc_driver( dc, dc->physDev );
free_gdi_handle( dc->hSelf ); free_gdi_handle( dc->hSelf );
free_dc_state( dc ); free_dc_state( dc );
} }
...@@ -244,8 +246,9 @@ void update_dc( DC *dc ) ...@@ -244,8 +246,9 @@ void update_dc( DC *dc )
* *
* Push a driver on top of the DC driver stack. * Push a driver on top of the DC driver stack.
*/ */
void push_dc_driver( DC * dc, PHYSDEV physdev ) void push_dc_driver( DC * dc, PHYSDEV physdev, const DC_FUNCTIONS *funcs )
{ {
physdev->funcs = funcs;
physdev->next = dc->physDev; physdev->next = dc->physDev;
physdev->hdc = dc->hSelf; physdev->hdc = dc->hSelf;
dc->physDev = physdev; dc->physDev = physdev;
...@@ -264,6 +267,7 @@ void pop_dc_driver( DC * dc, PHYSDEV physdev ) ...@@ -264,6 +267,7 @@ void pop_dc_driver( DC * dc, PHYSDEV physdev )
assert( physdev != &dc->nulldrv ); assert( physdev != &dc->nulldrv );
dc->physDev = physdev->next; dc->physDev = physdev->next;
dc->funcs = dc->physDev->funcs; dc->funcs = dc->physDev->funcs;
physdev->funcs->pDeleteDC( physdev );
} }
...@@ -618,7 +622,6 @@ HDC WINAPI CreateDCW( LPCWSTR driver, LPCWSTR device, LPCWSTR output, ...@@ -618,7 +622,6 @@ HDC WINAPI CreateDCW( LPCWSTR driver, LPCWSTR device, LPCWSTR output,
{ {
HDC hdc; HDC hdc;
DC * dc; DC * dc;
PHYSDEV physdev;
const DC_FUNCTIONS *funcs; const DC_FUNCTIONS *funcs;
WCHAR buf[300]; WCHAR buf[300];
...@@ -639,7 +642,7 @@ HDC WINAPI CreateDCW( LPCWSTR driver, LPCWSTR device, LPCWSTR output, ...@@ -639,7 +642,7 @@ HDC WINAPI CreateDCW( LPCWSTR driver, LPCWSTR device, LPCWSTR output,
ERR( "no driver found for %s\n", debugstr_w(buf) ); ERR( "no driver found for %s\n", debugstr_w(buf) );
return 0; return 0;
} }
if (!(dc = alloc_dc_ptr( funcs, OBJ_DC ))) goto error; if (!(dc = alloc_dc_ptr( OBJ_DC ))) goto error;
hdc = dc->hSelf; hdc = dc->hSelf;
dc->hBitmap = GDI_inc_ref_count( GetStockObject( DEFAULT_BITMAP )); dc->hBitmap = GDI_inc_ref_count( GetStockObject( DEFAULT_BITMAP ));
...@@ -648,16 +651,17 @@ HDC WINAPI CreateDCW( LPCWSTR driver, LPCWSTR device, LPCWSTR output, ...@@ -648,16 +651,17 @@ HDC WINAPI CreateDCW( LPCWSTR driver, LPCWSTR device, LPCWSTR output,
TRACE("(driver=%s, device=%s, output=%s): returning %p\n", TRACE("(driver=%s, device=%s, output=%s): returning %p\n",
debugstr_w(driver), debugstr_w(device), debugstr_w(output), dc->hSelf ); debugstr_w(driver), debugstr_w(device), debugstr_w(output), dc->hSelf );
if (dc->funcs->pCreateDC && if (funcs->pCreateDC)
!dc->funcs->pCreateDC( hdc, &physdev, buf, device, output, initData ))
{ {
WARN("creation aborted by device\n" ); PHYSDEV physdev;
goto error; if (!funcs->pCreateDC( hdc, &physdev, buf, device, output, initData ))
{
WARN("creation aborted by device\n" );
goto error;
}
push_dc_driver( dc, physdev, funcs );
} }
physdev->funcs = funcs;
push_dc_driver( dc, physdev );
dc->vis_rect.left = 0; dc->vis_rect.left = 0;
dc->vis_rect.top = 0; dc->vis_rect.top = 0;
dc->vis_rect.right = GetDeviceCaps( hdc, DESKTOPHORZRES ); dc->vis_rect.right = GetDeviceCaps( hdc, DESKTOPHORZRES );
...@@ -750,15 +754,15 @@ HDC WINAPI CreateCompatibleDC( HDC hdc ) ...@@ -750,15 +754,15 @@ HDC WINAPI CreateCompatibleDC( HDC hdc )
if (!(origDC = get_dc_ptr( hdc ))) return 0; if (!(origDC = get_dc_ptr( hdc ))) return 0;
if (GetObjectType( hdc ) == OBJ_DC) if (GetObjectType( hdc ) == OBJ_DC)
{ {
funcs = origDC->funcs;
physDev = origDC->physDev; physDev = origDC->physDev;
funcs = physDev->funcs;
} }
release_dc_ptr( origDC ); release_dc_ptr( origDC );
} }
if (!funcs && !(funcs = DRIVER_get_display_driver())) return 0; if (!funcs && !(funcs = DRIVER_get_display_driver())) return 0;
if (!(dc = alloc_dc_ptr( funcs, OBJ_MEMDC ))) goto error; if (!(dc = alloc_dc_ptr( OBJ_MEMDC ))) goto error;
TRACE("(%p): returning %p\n", hdc, dc->hSelf ); TRACE("(%p): returning %p\n", hdc, dc->hSelf );
...@@ -774,15 +778,15 @@ HDC WINAPI CreateCompatibleDC( HDC hdc ) ...@@ -774,15 +778,15 @@ HDC WINAPI CreateCompatibleDC( HDC hdc )
/* Pass the driver-specific physical device info into /* Pass the driver-specific physical device info into
* the new DC. The driver may use this read-only info * the new DC. The driver may use this read-only info
* while creating the compatible DC. */ * while creating the compatible DC. */
if (dc->funcs->pCreateDC && if (funcs->pCreateDC)
!dc->funcs->pCreateDC( dc->hSelf, &physDev, NULL, NULL, NULL, NULL ))
{ {
WARN("creation aborted by device\n"); if (!funcs->pCreateDC( dc->hSelf, &physDev, NULL, NULL, NULL, NULL ))
goto error; {
WARN("creation aborted by device\n");
goto error;
}
push_dc_driver( dc, physDev, funcs );
} }
physDev->funcs = funcs;
push_dc_driver( dc, physDev );
DC_InitDC( dc ); DC_InitDC( dc );
release_dc_ptr( dc ); release_dc_ptr( dc );
return ret; return ret;
...@@ -832,8 +836,6 @@ BOOL WINAPI DeleteDC( HDC hdc ) ...@@ -832,8 +836,6 @@ BOOL WINAPI DeleteDC( HDC hdc )
SelectObject( hdc, GetStockObject(SYSTEM_FONT) ); SelectObject( hdc, GetStockObject(SYSTEM_FONT) );
SelectObject( hdc, GetStockObject(DEFAULT_BITMAP) ); SelectObject( hdc, GetStockObject(DEFAULT_BITMAP) );
if (dc->funcs->pDeleteDC) dc->funcs->pDeleteDC(dc->physDev);
dc->physDev = NULL;
free_dc_ptr( dc ); free_dc_ptr( dc );
return TRUE; return TRUE;
} }
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include "config.h" #include "config.h"
#include "wine/port.h" #include "wine/port.h"
#include <assert.h>
#include <stdarg.h> #include <stdarg.h>
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
...@@ -339,6 +340,13 @@ static BOOL CDECL nulldrv_CreateBitmap( PHYSDEV dev, HBITMAP bitmap, LPVOID bits ...@@ -339,6 +340,13 @@ static BOOL CDECL nulldrv_CreateBitmap( PHYSDEV dev, HBITMAP bitmap, LPVOID bits
return TRUE; return TRUE;
} }
static BOOL CDECL nulldrv_CreateDC( HDC hdc, PHYSDEV *dev, LPCWSTR driver, LPCWSTR device,
LPCWSTR output, const DEVMODEW *devmode )
{
assert(0); /* should never be called */
return FALSE;
}
static HBITMAP CDECL nulldrv_CreateDIBSection( PHYSDEV dev, HBITMAP bitmap, static HBITMAP CDECL nulldrv_CreateDIBSection( PHYSDEV dev, HBITMAP bitmap,
const BITMAPINFO *info, UINT usage ) const BITMAPINFO *info, UINT usage )
{ {
...@@ -350,6 +358,12 @@ static BOOL CDECL nulldrv_DeleteBitmap( HBITMAP bitmap ) ...@@ -350,6 +358,12 @@ static BOOL CDECL nulldrv_DeleteBitmap( HBITMAP bitmap )
return TRUE; return TRUE;
} }
static BOOL CDECL nulldrv_DeleteDC( PHYSDEV dev )
{
assert(0); /* should never be called */
return TRUE;
}
static BOOL CDECL nulldrv_DeleteObject( PHYSDEV dev, HGDIOBJ obj ) static BOOL CDECL nulldrv_DeleteObject( PHYSDEV dev, HGDIOBJ obj )
{ {
return TRUE; return TRUE;
...@@ -753,10 +767,10 @@ const DC_FUNCTIONS null_driver = ...@@ -753,10 +767,10 @@ const DC_FUNCTIONS null_driver =
nulldrv_Chord, /* pChord */ nulldrv_Chord, /* pChord */
nulldrv_CloseFigure, /* pCloseFigure */ nulldrv_CloseFigure, /* pCloseFigure */
nulldrv_CreateBitmap, /* pCreateBitmap */ nulldrv_CreateBitmap, /* pCreateBitmap */
NULL, /* pCreateDC */ nulldrv_CreateDC, /* pCreateDC */
nulldrv_CreateDIBSection, /* pCreateDIBSection */ nulldrv_CreateDIBSection, /* pCreateDIBSection */
nulldrv_DeleteBitmap, /* pDeleteBitmap */ nulldrv_DeleteBitmap, /* pDeleteBitmap */
NULL, /* pDeleteDC */ nulldrv_DeleteDC, /* pDeleteDC */
nulldrv_DeleteObject, /* pDeleteObject */ nulldrv_DeleteObject, /* pDeleteObject */
nulldrv_DescribePixelFormat, /* pDescribePixelFormat */ nulldrv_DescribePixelFormat, /* pDescribePixelFormat */
nulldrv_DeviceCapabilities, /* pDeviceCapabilities */ nulldrv_DeviceCapabilities, /* pDeviceCapabilities */
......
...@@ -32,6 +32,8 @@ ...@@ -32,6 +32,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(enhmetafile); WINE_DEFAULT_DEBUG_CHANNEL(enhmetafile);
static BOOL EMFDRV_DeleteDC( PHYSDEV dev );
static const DC_FUNCTIONS EMFDRV_Funcs = static const DC_FUNCTIONS EMFDRV_Funcs =
{ {
NULL, /* pAbortDoc */ NULL, /* pAbortDoc */
...@@ -49,7 +51,7 @@ static const DC_FUNCTIONS EMFDRV_Funcs = ...@@ -49,7 +51,7 @@ static const DC_FUNCTIONS EMFDRV_Funcs =
NULL, /* pCreateDC */ NULL, /* pCreateDC */
NULL, /* pCreateDIBSection */ NULL, /* pCreateDIBSection */
NULL, /* pDeleteBitmap */ NULL, /* pDeleteBitmap */
NULL, /* pDeleteDC */ EMFDRV_DeleteDC, /* pDeleteDC */
EMFDRV_DeleteObject, /* pDeleteObject */ EMFDRV_DeleteObject, /* pDeleteObject */
NULL, /* pDescribePixelFormat */ NULL, /* pDescribePixelFormat */
NULL, /* pDeviceCapabilities */ NULL, /* pDeviceCapabilities */
...@@ -160,9 +162,9 @@ static const DC_FUNCTIONS EMFDRV_Funcs = ...@@ -160,9 +162,9 @@ static const DC_FUNCTIONS EMFDRV_Funcs =
/********************************************************************** /**********************************************************************
* EMFDRV_DeleteDC * EMFDRV_DeleteDC
*/ */
static BOOL EMFDRV_DeleteDC( DC *dc ) static BOOL EMFDRV_DeleteDC( PHYSDEV dev )
{ {
EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE *)dc->physDev; EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE *)dev;
UINT index; UINT index;
if (physDev->emh) HeapFree( GetProcessHeap(), 0, physDev->emh ); if (physDev->emh) HeapFree( GetProcessHeap(), 0, physDev->emh );
...@@ -171,8 +173,6 @@ static BOOL EMFDRV_DeleteDC( DC *dc ) ...@@ -171,8 +173,6 @@ static BOOL EMFDRV_DeleteDC( DC *dc )
GDI_hdc_not_using_object(physDev->handles[index], physDev->hdc); GDI_hdc_not_using_object(physDev->handles[index], physDev->hdc);
HeapFree( GetProcessHeap(), 0, physDev->handles ); HeapFree( GetProcessHeap(), 0, physDev->handles );
HeapFree( GetProcessHeap(), 0, physDev ); HeapFree( GetProcessHeap(), 0, physDev );
dc->physDev = NULL;
free_dc_ptr( dc );
return TRUE; return TRUE;
} }
...@@ -313,17 +313,13 @@ HDC WINAPI CreateEnhMetaFileW( ...@@ -313,17 +313,13 @@ HDC WINAPI CreateEnhMetaFileW(
TRACE("%s\n", debugstr_w(filename) ); TRACE("%s\n", debugstr_w(filename) );
if (!(dc = alloc_dc_ptr( &EMFDRV_Funcs, OBJ_ENHMETADC ))) return 0; if (!(dc = alloc_dc_ptr( OBJ_ENHMETADC ))) return 0;
physDev = HeapAlloc(GetProcessHeap(),0,sizeof(*physDev)); physDev = HeapAlloc(GetProcessHeap(),0,sizeof(*physDev));
if (!physDev) { if (!physDev) {
free_dc_ptr( dc ); free_dc_ptr( dc );
return 0; return 0;
} }
physDev->dev.funcs = &EMFDRV_Funcs;
push_dc_driver( dc, &physDev->dev );
physDev->hdc = dc->hSelf;
if(description) { /* App name\0Title\0\0 */ if(description) { /* App name\0Title\0\0 */
length = lstrlenW(description); length = lstrlenW(description);
length += lstrlenW(description + length + 1); length += lstrlenW(description + length + 1);
...@@ -338,6 +334,9 @@ HDC WINAPI CreateEnhMetaFileW( ...@@ -338,6 +334,9 @@ HDC WINAPI CreateEnhMetaFileW(
return 0; return 0;
} }
push_dc_driver( dc, &physDev->dev, &EMFDRV_Funcs );
physDev->hdc = dc->hSelf;
physDev->handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, HANDLE_LIST_INC * sizeof(physDev->handles[0])); physDev->handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, HANDLE_LIST_INC * sizeof(physDev->handles[0]));
physDev->handles_size = HANDLE_LIST_INC; physDev->handles_size = HANDLE_LIST_INC;
physDev->cur_handles = 1; physDev->cur_handles = 1;
...@@ -407,11 +406,11 @@ HDC WINAPI CreateEnhMetaFileW( ...@@ -407,11 +406,11 @@ HDC WINAPI CreateEnhMetaFileW(
{ {
if ((hFile = CreateFileW(filename, GENERIC_WRITE | GENERIC_READ, 0, if ((hFile = CreateFileW(filename, GENERIC_WRITE | GENERIC_READ, 0,
NULL, CREATE_ALWAYS, 0, 0)) == INVALID_HANDLE_VALUE) { NULL, CREATE_ALWAYS, 0, 0)) == INVALID_HANDLE_VALUE) {
EMFDRV_DeleteDC( dc ); free_dc_ptr( dc );
return 0; return 0;
} }
if (!WriteFile( hFile, physDev->emh, size, NULL, NULL )) { if (!WriteFile( hFile, physDev->emh, size, NULL, NULL )) {
EMFDRV_DeleteDC( dc ); free_dc_ptr( dc );
return 0; return 0;
} }
physDev->hFile = hFile; physDev->hFile = hFile;
...@@ -484,7 +483,7 @@ HENHMETAFILE WINAPI CloseEnhMetaFile(HDC hdc) /* [in] metafile DC */ ...@@ -484,7 +483,7 @@ HENHMETAFILE WINAPI CloseEnhMetaFile(HDC hdc) /* [in] metafile DC */
if (SetFilePointer(physDev->hFile, 0, NULL, FILE_BEGIN) != 0) if (SetFilePointer(physDev->hFile, 0, NULL, FILE_BEGIN) != 0)
{ {
CloseHandle( physDev->hFile ); CloseHandle( physDev->hFile );
EMFDRV_DeleteDC( dc ); free_dc_ptr( dc );
return 0; return 0;
} }
...@@ -492,7 +491,7 @@ HENHMETAFILE WINAPI CloseEnhMetaFile(HDC hdc) /* [in] metafile DC */ ...@@ -492,7 +491,7 @@ HENHMETAFILE WINAPI CloseEnhMetaFile(HDC hdc) /* [in] metafile DC */
NULL, NULL)) NULL, NULL))
{ {
CloseHandle( physDev->hFile ); CloseHandle( physDev->hFile );
EMFDRV_DeleteDC( dc ); free_dc_ptr( dc );
return 0; return 0;
} }
HeapFree( GetProcessHeap(), 0, physDev->emh ); HeapFree( GetProcessHeap(), 0, physDev->emh );
...@@ -507,6 +506,6 @@ HENHMETAFILE WINAPI CloseEnhMetaFile(HDC hdc) /* [in] metafile DC */ ...@@ -507,6 +506,6 @@ HENHMETAFILE WINAPI CloseEnhMetaFile(HDC hdc) /* [in] metafile DC */
hmf = EMF_Create_HENHMETAFILE( physDev->emh, (physDev->hFile != 0) ); hmf = EMF_Create_HENHMETAFILE( physDev->emh, (physDev->hFile != 0) );
physDev->emh = NULL; /* So it won't be deleted */ physDev->emh = NULL; /* So it won't be deleted */
EMFDRV_DeleteDC( dc ); free_dc_ptr( dc );
return hmf; return hmf;
} }
...@@ -374,12 +374,12 @@ extern INT BITMAP_GetWidthBytes( INT bmWidth, INT bpp ) DECLSPEC_HIDDEN; ...@@ -374,12 +374,12 @@ extern INT BITMAP_GetWidthBytes( INT bmWidth, INT bpp ) DECLSPEC_HIDDEN;
extern void CLIPPING_UpdateGCRegion( DC * dc ) DECLSPEC_HIDDEN; extern void CLIPPING_UpdateGCRegion( DC * dc ) DECLSPEC_HIDDEN;
/* dc.c */ /* dc.c */
extern DC *alloc_dc_ptr( const DC_FUNCTIONS *funcs, WORD magic ) DECLSPEC_HIDDEN; extern DC *alloc_dc_ptr( WORD 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 void update_dc( DC *dc ) DECLSPEC_HIDDEN; extern void update_dc( DC *dc ) DECLSPEC_HIDDEN;
extern void push_dc_driver( DC * dc, PHYSDEV physdev ) DECLSPEC_HIDDEN; extern void push_dc_driver( DC * dc, PHYSDEV physdev, const DC_FUNCTIONS *funcs ) DECLSPEC_HIDDEN;
extern void pop_dc_driver( DC * dc, PHYSDEV physdev ) DECLSPEC_HIDDEN; extern void pop_dc_driver( DC * dc, PHYSDEV physdev ) 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;
......
...@@ -30,6 +30,8 @@ ...@@ -30,6 +30,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(metafile); WINE_DEFAULT_DEBUG_CHANNEL(metafile);
static BOOL MFDRV_DeleteDC( PHYSDEV dev );
static const DC_FUNCTIONS MFDRV_Funcs = static const DC_FUNCTIONS MFDRV_Funcs =
{ {
NULL, /* pAbortDoc */ NULL, /* pAbortDoc */
...@@ -47,7 +49,7 @@ static const DC_FUNCTIONS MFDRV_Funcs = ...@@ -47,7 +49,7 @@ static const DC_FUNCTIONS MFDRV_Funcs =
NULL, /* pCreateDC */ NULL, /* pCreateDC */
NULL, /* pCreateDIBSection */ NULL, /* pCreateDIBSection */
NULL, /* pDeleteBitmap */ NULL, /* pDeleteBitmap */
NULL, /* pDeleteDC */ MFDRV_DeleteDC, /* pDeleteDC */
MFDRV_DeleteObject, /* pDeleteObject */ MFDRV_DeleteObject, /* pDeleteObject */
NULL, /* pDescribePixelFormat */ NULL, /* pDescribePixelFormat */
NULL, /* pDeviceCapabilities */ NULL, /* pDeviceCapabilities */
...@@ -164,7 +166,7 @@ static DC *MFDRV_AllocMetaFile(void) ...@@ -164,7 +166,7 @@ static DC *MFDRV_AllocMetaFile(void)
DC *dc; DC *dc;
METAFILEDRV_PDEVICE *physDev; METAFILEDRV_PDEVICE *physDev;
if (!(dc = alloc_dc_ptr( &MFDRV_Funcs, OBJ_METADC ))) return NULL; if (!(dc = alloc_dc_ptr( OBJ_METADC ))) return NULL;
physDev = HeapAlloc(GetProcessHeap(),0,sizeof(*physDev)); physDev = HeapAlloc(GetProcessHeap(),0,sizeof(*physDev));
if (!physDev) if (!physDev)
...@@ -172,10 +174,6 @@ static DC *MFDRV_AllocMetaFile(void) ...@@ -172,10 +174,6 @@ static DC *MFDRV_AllocMetaFile(void)
free_dc_ptr( dc ); free_dc_ptr( dc );
return NULL; return NULL;
} }
physDev->dev.funcs = &MFDRV_Funcs;
push_dc_driver( dc, &physDev->dev );
physDev->hdc = dc->hSelf;
if (!(physDev->mh = HeapAlloc( GetProcessHeap(), 0, sizeof(*physDev->mh) ))) if (!(physDev->mh = HeapAlloc( GetProcessHeap(), 0, sizeof(*physDev->mh) )))
{ {
HeapFree( GetProcessHeap(), 0, physDev ); HeapFree( GetProcessHeap(), 0, physDev );
...@@ -183,6 +181,9 @@ static DC *MFDRV_AllocMetaFile(void) ...@@ -183,6 +181,9 @@ static DC *MFDRV_AllocMetaFile(void)
return NULL; return NULL;
} }
push_dc_driver( dc, &physDev->dev, &MFDRV_Funcs );
physDev->hdc = dc->hSelf;
physDev->handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, HANDLE_LIST_INC * sizeof(physDev->handles[0])); physDev->handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, HANDLE_LIST_INC * sizeof(physDev->handles[0]));
physDev->handles_size = HANDLE_LIST_INC; physDev->handles_size = HANDLE_LIST_INC;
physDev->cur_handles = 0; physDev->cur_handles = 0;
...@@ -205,9 +206,9 @@ static DC *MFDRV_AllocMetaFile(void) ...@@ -205,9 +206,9 @@ static DC *MFDRV_AllocMetaFile(void)
/********************************************************************** /**********************************************************************
* MFDRV_DeleteDC * MFDRV_DeleteDC
*/ */
static BOOL MFDRV_DeleteDC( DC *dc ) static BOOL MFDRV_DeleteDC( PHYSDEV dev )
{ {
METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dc->physDev; METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev;
DWORD index; DWORD index;
HeapFree( GetProcessHeap(), 0, physDev->mh ); HeapFree( GetProcessHeap(), 0, physDev->mh );
...@@ -216,8 +217,6 @@ static BOOL MFDRV_DeleteDC( DC *dc ) ...@@ -216,8 +217,6 @@ static BOOL MFDRV_DeleteDC( DC *dc )
GDI_hdc_not_using_object(physDev->handles[index], physDev->hdc); GDI_hdc_not_using_object(physDev->handles[index], physDev->hdc);
HeapFree( GetProcessHeap(), 0, physDev->handles ); HeapFree( GetProcessHeap(), 0, physDev->handles );
HeapFree( GetProcessHeap(), 0, physDev ); HeapFree( GetProcessHeap(), 0, physDev );
dc->physDev = NULL;
free_dc_ptr( dc );
return TRUE; return TRUE;
} }
...@@ -251,12 +250,12 @@ HDC WINAPI CreateMetaFileW( LPCWSTR filename ) ...@@ -251,12 +250,12 @@ HDC WINAPI CreateMetaFileW( LPCWSTR filename )
physDev->mh->mtType = METAFILE_DISK; physDev->mh->mtType = METAFILE_DISK;
if ((hFile = CreateFileW(filename, GENERIC_WRITE, 0, NULL, if ((hFile = CreateFileW(filename, GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, 0, 0)) == INVALID_HANDLE_VALUE) { CREATE_ALWAYS, 0, 0)) == INVALID_HANDLE_VALUE) {
MFDRV_DeleteDC( dc ); free_dc_ptr( dc );
return 0; return 0;
} }
if (!WriteFile( hFile, physDev->mh, sizeof(*physDev->mh), NULL, if (!WriteFile( hFile, physDev->mh, sizeof(*physDev->mh), NULL,
NULL )) { NULL )) {
MFDRV_DeleteDC( dc ); free_dc_ptr( dc );
return 0; return 0;
} }
physDev->hFile = hFile; physDev->hFile = hFile;
...@@ -328,21 +327,21 @@ static DC *MFDRV_CloseMetaFile( HDC hdc ) ...@@ -328,21 +327,21 @@ static DC *MFDRV_CloseMetaFile( HDC hdc )
if (!MFDRV_MetaParam0(dc->physDev, META_EOF)) if (!MFDRV_MetaParam0(dc->physDev, META_EOF))
{ {
MFDRV_DeleteDC( dc ); free_dc_ptr( dc );
return 0; return 0;
} }
if (physDev->mh->mtType == METAFILE_DISK) /* disk based metafile */ if (physDev->mh->mtType == METAFILE_DISK) /* disk based metafile */
{ {
if (SetFilePointer(physDev->hFile, 0, NULL, FILE_BEGIN) != 0) { if (SetFilePointer(physDev->hFile, 0, NULL, FILE_BEGIN) != 0) {
MFDRV_DeleteDC( dc ); free_dc_ptr( dc );
return 0; return 0;
} }
physDev->mh->mtType = METAFILE_MEMORY; /* This is what windows does */ physDev->mh->mtType = METAFILE_MEMORY; /* This is what windows does */
if (!WriteFile(physDev->hFile, physDev->mh, sizeof(*physDev->mh), if (!WriteFile(physDev->hFile, physDev->mh, sizeof(*physDev->mh),
NULL, NULL)) { NULL, NULL)) {
MFDRV_DeleteDC( dc ); free_dc_ptr( dc );
return 0; return 0;
} }
CloseHandle(physDev->hFile); CloseHandle(physDev->hFile);
...@@ -377,7 +376,7 @@ HMETAFILE WINAPI CloseMetaFile(HDC hdc) ...@@ -377,7 +376,7 @@ HMETAFILE WINAPI CloseMetaFile(HDC hdc)
hmf = MF_Create_HMETAFILE( physDev->mh ); hmf = MF_Create_HMETAFILE( physDev->mh );
physDev->mh = NULL; /* So it won't be deleted */ physDev->mh = NULL; /* So it won't be deleted */
MFDRV_DeleteDC( dc ); free_dc_ptr( dc );
return hmf; return hmf;
} }
......
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