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