Commit 4496c64a authored by Piotr Caban's avatar Piotr Caban Committed by Alexandre Julliard

gdi32: Support creating EMRI_DEVMODE records in spool files.

parent 2b8de930
......@@ -54,7 +54,8 @@ struct graphics_driver
enum print_flags
{
CALL_START_PAGE = 0x1,
CALL_END_PAGE = 0x2
CALL_END_PAGE = 0x2,
WRITE_DEVMODE = 0x4,
};
struct print
......@@ -62,6 +63,7 @@ struct print
HANDLE printer;
WCHAR *output;
enum print_flags flags;
DEVMODEW *devmode;
};
DC_ATTR *get_dc_attr( HDC hdc )
......@@ -202,6 +204,29 @@ done:
return driver->entry_point;
}
static BOOL print_copy_devmode( struct print *print, const DEVMODEW *devmode )
{
size_t size;
if (!print) return TRUE;
if (!print->devmode && !devmode) return TRUE;
HeapFree( GetProcessHeap(), 0, print->devmode );
if (!devmode)
{
print->devmode = NULL;
print->flags |= WRITE_DEVMODE;
return TRUE;
}
size = devmode->dmSize + devmode->dmDriverExtra;
print->devmode = HeapAlloc( GetProcessHeap(), 0, size );
if (!print->devmode) return FALSE;
memcpy(print->devmode, devmode, size);
print->flags |= WRITE_DEVMODE;
return TRUE;
}
/***********************************************************************
* CreateDCW (GDI32.@)
*/
......@@ -262,10 +287,13 @@ HDC WINAPI CreateDCW( LPCWSTR driver, LPCWSTR device, LPCWSTR output,
ClosePrinter( hspool );
return 0;
}
else if (!(print = HeapAlloc( GetProcessHeap(), 0, sizeof(*print) )))
else if (!(print = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*print) )) ||
!print_copy_devmode( print, devmode ))
{
HeapFree( GetProcessHeap(), 0, print );
ClosePrinter( hspool );
HeapFree( GetProcessHeap(), 0, port );
return 0;
}
if (display)
......@@ -295,13 +323,13 @@ HDC WINAPI CreateDCW( LPCWSTR driver, LPCWSTR device, LPCWSTR output,
}
print->printer = hspool;
print->output = port;
print->flags = 0;
dc_attr->print = (UINT_PTR)print;
}
else if (hspool)
{
ClosePrinter( hspool );
HeapFree( GetProcessHeap(), 0, port );
HeapFree( GetProcessHeap(), 0, print->devmode );
HeapFree( GetProcessHeap(), 0, print );
}
......@@ -431,6 +459,7 @@ static void delete_print_dc( DC_ATTR *dc_attr )
ClosePrinter( print->printer );
HeapFree( GetProcessHeap(), 0, print->output );
HeapFree( GetProcessHeap(), 0, print->devmode );
HeapFree( GetProcessHeap(), 0, print );
dc_attr->print = 0;
}
......@@ -471,7 +500,15 @@ HDC WINAPI ResetDCA( HDC hdc, const DEVMODEA *devmode )
*/
HDC WINAPI ResetDCW( HDC hdc, const DEVMODEW *devmode )
{
return NtGdiResetDC( hdc, devmode, NULL, NULL, NULL ) ? hdc : 0;
struct print *print;
DC_ATTR *dc_attr;
if (!(dc_attr = get_dc_attr( hdc ))) return 0;
print = get_dc_print( dc_attr );
if (print && print->flags & CALL_END_PAGE) return 0;
if (!NtGdiResetDC( hdc, devmode, NULL, NULL, NULL )) return 0;
if (print && !print_copy_devmode( print, devmode )) return 0;
return hdc;
}
/***********************************************************************
......@@ -2404,9 +2441,11 @@ INT WINAPI EndPage( HDC hdc )
print = get_dc_print( dc_attr );
if (print)
{
print->flags = (print->flags & ~CALL_END_PAGE) | CALL_START_PAGE;
BOOL write = print->flags & WRITE_DEVMODE;
print->flags = (print->flags & ~(CALL_END_PAGE | WRITE_DEVMODE)) | CALL_START_PAGE;
if (dc_attr->emf)
return spool_end_page( dc_attr, print->printer );
return spool_end_page( dc_attr, print->printer, print->devmode, write );
}
return NtGdiEndPage( hdc );
}
......
......@@ -2807,7 +2807,7 @@ int spool_start_page( DC_ATTR *dc_attr, HANDLE hspool )
return StartPagePrinter( hspool );
}
int spool_end_page( DC_ATTR *dc_attr, HANDLE hspool )
int spool_end_page( DC_ATTR *dc_attr, HANDLE hspool, const DEVMODEW *devmode, BOOL write_devmode )
{
struct record_hdr
{
......@@ -2831,9 +2831,20 @@ int spool_end_page( DC_ATTR *dc_attr, HANDLE hspool )
if (!WritePrinter( hspool, &record_hdr, sizeof(record_hdr), &written )) return 0;
if (!WritePrinter( hspool, emf->emh, emf->emh->nBytes, &written )) return 0;
if (write_devmode)
{
record_hdr.ulID = EMRI_DEVMODE;
record_hdr.cjSize = devmode ? devmode->dmSize + devmode->dmDriverExtra : 0;
if (!WritePrinter( hspool, &record_hdr, sizeof(record_hdr), &written )) return 0;
if (devmode && !WritePrinter( hspool, (BYTE *)devmode,
record_hdr.cjSize, &written )) return 0;
}
metafile_ext.hdr.ulID = EMRI_METAFILE_EXT;
metafile_ext.hdr.cjSize = sizeof(metafile_ext) - sizeof(struct record_hdr);
metafile_ext.pos.QuadPart = emf->emh->nBytes + sizeof(record_hdr);
if (write_devmode)
metafile_ext.pos.QuadPart += record_hdr.cjSize + sizeof(record_hdr);
if (!WritePrinter( hspool, &metafile_ext, sizeof(metafile_ext), &written )) return 0;
emf_reset( dc_attr, NULL );
......
......@@ -283,7 +283,8 @@ extern HENHMETAFILE EMF_Create_HENHMETAFILE( ENHMETAHEADER *emh, DWORD filesize,
extern BOOL spool_start_doc( DC_ATTR *dc_attr, HANDLE hspool,
const DOCINFOW *doc_info ) DECLSPEC_HIDDEN;
extern int spool_start_page( DC_ATTR *dc_attr, HANDLE hspool ) DECLSPEC_HIDDEN;
extern int spool_end_page( DC_ATTR *dc_attr, HANDLE hspool ) DECLSPEC_HIDDEN;
extern int spool_end_page( DC_ATTR *dc_attr, HANDLE hspool, const DEVMODEW *devmode,
BOOL write_devmode ) DECLSPEC_HIDDEN;
extern int spool_end_doc( DC_ATTR *dc_attr, HANDLE hspool ) DECLSPEC_HIDDEN;
extern int spool_abort_doc( DC_ATTR *dc_attr, HANDLE hspool ) DECLSPEC_HIDDEN;
......
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