From: Piotr Caban piotr@codeweavers.com
--- dlls/wineps.drv/init.c | 78 +++---------------- dlls/wineps.drv/unixlib.c | 152 ++++++++++++++++++++++++++++++++++++-- dlls/wineps.drv/unixlib.h | 6 +- 3 files changed, 159 insertions(+), 77 deletions(-)
diff --git a/dlls/wineps.drv/init.c b/dlls/wineps.drv/init.c index c5bb855ea93..cc06c7017c9 100644 --- a/dlls/wineps.drv/init.c +++ b/dlls/wineps.drv/init.c @@ -28,8 +28,8 @@ #include "winreg.h" #include "winnls.h" #include "winuser.h" -#include "unixlib.h" #include "psdrv.h" +#include "unixlib.h" #include "winspool.h" #include "wine/debug.h"
@@ -93,8 +93,6 @@ static const PSDRV_DEVMODE DefaultDevmode = HINSTANCE PSDRV_hInstance = 0; HANDLE PSDRV_Heap = 0;
-static struct gdi_dc_funcs psdrv_funcs; - /********************************************************************* * DllMain * @@ -109,16 +107,11 @@ BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
case DLL_PROCESS_ATTACH: { - struct init_dc_params params = { &psdrv_funcs }; - PSDRV_hInstance = hinst; DisableThreadLibraryCalls(hinst);
if (__wine_init_unix_call()) return FALSE; - if (!WINE_UNIX_CALL( unix_init_dc, ¶ms )) - return FALSE; -
PSDRV_Heap = HeapCreate(0, 0x10000, 0); if (PSDRV_Heap == NULL) @@ -133,6 +126,7 @@ BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
case DLL_PROCESS_DETACH: if (reserved) break; + WINE_UNIX_CALL(unix_free_printer_info, NULL); HeapDestroy( PSDRV_Heap ); break; } @@ -382,55 +376,6 @@ PSDRV_PDEVICE *create_psdrv_physdev( HDC hdc, const WCHAR *device, return pdev; }
-/********************************************************************** - * PSDRV_CreateDC - */ -static BOOL CDECL PSDRV_CreateDC( PHYSDEV *pdev, LPCWSTR device, LPCWSTR output, - const DEVMODEW *initData ) -{ - PSDRV_PDEVICE *physDev; - - TRACE("(%s %s %p)\n", debugstr_w(device), debugstr_w(output), initData); - - if (!device) return FALSE; - if (!(physDev = create_psdrv_physdev( (*pdev)->hdc, device, - (const PSDRV_DEVMODE *)initData ))) return FALSE; - push_dc_driver( pdev, &physDev->dev, &psdrv_funcs ); - return TRUE; -} - - -/********************************************************************** - * PSDRV_CreateCompatibleDC - */ -static BOOL CDECL PSDRV_CreateCompatibleDC( PHYSDEV orig, PHYSDEV *pdev ) -{ - PSDRV_PDEVICE *physDev, *orig_dev = get_psdrv_dev( orig ); - - if (!(physDev = create_psdrv_physdev( (*pdev)->hdc, orig_dev->pi->friendly_name, - orig_dev->Devmode ))) return FALSE; - push_dc_driver( pdev, &physDev->dev, &psdrv_funcs ); - return TRUE; -} - - - -/********************************************************************** - * PSDRV_DeleteDC - */ -static BOOL CDECL PSDRV_DeleteDC( PHYSDEV dev ) -{ - PSDRV_PDEVICE *physDev = get_psdrv_dev( dev ); - - TRACE("\n"); - - HeapFree( GetProcessHeap(), 0, physDev->Devmode ); - HeapFree( GetProcessHeap(), 0, physDev ); - - return TRUE; -} - - /********************************************************************** * ResetDC (WINEPS.@) */ @@ -674,25 +619,22 @@ fail: return NULL; }
- -static struct gdi_dc_funcs psdrv_funcs = -{ - .pCreateCompatibleDC = PSDRV_CreateCompatibleDC, - .pCreateDC = PSDRV_CreateDC, - .pDeleteDC = PSDRV_DeleteDC, - .priority = GDI_PRIORITY_GRAPHICS_DRV -}; - - /****************************************************************************** * PSDRV_get_gdi_driver */ const struct gdi_dc_funcs * CDECL PSDRV_get_gdi_driver( unsigned int version, const WCHAR *name ) { + PRINTERINFO *pi = PSDRV_FindPrinterInfo( name ); + struct init_dc_params params = { NULL, pi, pi->friendly_name }; + + if (!pi) + return NULL; if (version != WINE_GDI_DRIVER_VERSION) { ERR( "version mismatch, gdi32 wants %u but wineps has %u\n", version, WINE_GDI_DRIVER_VERSION ); return NULL; } - return &psdrv_funcs; + if (!WINE_UNIX_CALL( unix_init_dc, ¶ms )) + return FALSE; + return params.funcs; } diff --git a/dlls/wineps.drv/unixlib.c b/dlls/wineps.drv/unixlib.c index 88e53024738..bb04610396c 100644 --- a/dlls/wineps.drv/unixlib.c +++ b/dlls/wineps.drv/unixlib.c @@ -49,6 +49,16 @@ static const WCHAR systemW[] = {'S','y','s','t','e','m',0}; static const WCHAR times_new_romanW[] = {'T','i','m','e','s',' ','N','e','w',' ','R','o','m','a','n',0}; static const WCHAR courier_newW[] = {'C','o','u','r','i','e','r',' ','N','e','w',0};
+static const struct gdi_dc_funcs psdrv_funcs; + +struct printer_info +{ + struct list entry; + const WCHAR *name; + PRINTERINFO *pi; +}; + +static struct list printer_info_list = LIST_INIT( printer_info_list );
/* copied from kernelbase */ static int muldiv(int a, int b, int c) @@ -1249,24 +1259,150 @@ static BOOL CDECL get_text_extent_ex_point(PHYSDEV dev, const WCHAR *str, int co return TRUE; }
+static struct printer_info *find_printer_info(const WCHAR *name) +{ + struct printer_info *pi; + + LIST_FOR_EACH_ENTRY(pi, &printer_info_list, struct printer_info, entry) + { + if (!wcscmp(pi->name, name)) + return pi; + } + return NULL; +} + +static PSDRV_PDEVICE *create_physdev(HDC hdc, const WCHAR *device, + const PSDRV_DEVMODE *devmode) +{ + struct printer_info *pi = find_printer_info(device); + PSDRV_PDEVICE *pdev; + + if (!pi) return NULL; + if (!pi->pi->Fonts) + { + RASTERIZER_STATUS status; + if (!NtGdiGetRasterizerCaps(&status, sizeof(status)) || + !(status.wFlags & TT_AVAILABLE) || + !(status.wFlags & TT_ENABLED)) + { + MESSAGE("Disabling printer %s since it has no builtin fonts and " + "there are no TrueType fonts available.\n", debugstr_w(device)); + return FALSE; + } + } + + pdev = malloc(sizeof(*pdev)); + if (!pdev) return NULL; + + pdev->Devmode = malloc(sizeof(PSDRV_DEVMODE)); + if (!pdev->Devmode) + { + free(pdev); + return NULL; + } + + *pdev->Devmode = *pi->pi->Devmode; + pdev->pi = pi->pi; + pdev->logPixelsX = pi->pi->ppd->DefaultResolution; + pdev->logPixelsY = pi->pi->ppd->DefaultResolution; + + if (devmode) + { + dump_devmode(&devmode->dmPublic); + merge_devmodes(pdev->Devmode, devmode, pi->pi); + } + + update_dev_caps(pdev); + NtGdiSelectFont(hdc, GetStockObject(DEVICE_DEFAULT_FONT)); + return pdev; +} + +static BOOL CDECL create_dc(PHYSDEV *dev, const WCHAR *device, + const WCHAR *output, const DEVMODEW *devmode) +{ + PSDRV_PDEVICE *pdev; + + TRACE("(%s %s %p)\n", debugstr_w(device), debugstr_w(output), devmode); + + if (!device) return FALSE; + if (!(pdev = create_physdev((*dev)->hdc, device, + (const PSDRV_DEVMODE *)devmode))) return FALSE; + push_dc_driver(dev, &pdev->dev, &psdrv_funcs); + return TRUE; +} + +static BOOL CDECL create_compatible_dc(PHYSDEV orig, PHYSDEV *dev) +{ + PSDRV_PDEVICE *pdev, *orig_dev = get_psdrv_dev(orig); + + if (!(pdev = create_physdev((*dev)->hdc, orig_dev->pi->friendly_name, + orig_dev->Devmode))) return FALSE; + push_dc_driver(dev, &pdev->dev, &psdrv_funcs); + return TRUE; +} + +static BOOL CDECL delete_dc(PHYSDEV dev) +{ + PSDRV_PDEVICE *pdev = get_psdrv_dev(dev); + + TRACE("\n"); + + free(pdev->Devmode); + free(pdev); + return TRUE; +} + +static const struct gdi_dc_funcs psdrv_funcs = +{ + .pCreateCompatibleDC = create_compatible_dc, + .pCreateDC = create_dc, + .pDeleteDC = delete_dc, + .pEnumFonts = enum_fonts, + .pExtEscape = ext_escape, + .pGetCharWidth = get_char_width, + .pGetDeviceCaps = get_device_caps, + .pGetTextExtentExPoint = get_text_extent_ex_point, + .pGetTextMetrics = get_text_metrics, + .pResetDC = reset_dc, + .pSelectFont = select_font, + .priority = GDI_PRIORITY_GRAPHICS_DRV +}; + static NTSTATUS init_dc(void *arg) { struct init_dc_params *params = arg; + struct printer_info *pi; + + pi = find_printer_info(params->name); + if (!pi) + { + pi = malloc(sizeof(*pi)); + if (!pi) return FALSE;
- params->funcs->pGetDeviceCaps = get_device_caps; - params->funcs->pResetDC = reset_dc; - params->funcs->pExtEscape = ext_escape; - params->funcs->pSelectFont = select_font; - params->funcs->pEnumFonts = enum_fonts; - params->funcs->pGetCharWidth = get_char_width; - params->funcs->pGetTextMetrics = get_text_metrics; - params->funcs->pGetTextExtentExPoint = get_text_extent_ex_point; + pi->name = params->name; + pi->pi = params->pi; + list_add_head(&printer_info_list, &pi->entry); + } + + params->funcs = &psdrv_funcs; return TRUE; }
+static NTSTATUS free_printer_info(void *arg) +{ + struct printer_info *pi, *next; + + LIST_FOR_EACH_ENTRY_SAFE(pi, next, &printer_info_list, struct printer_info, entry) + { + free(pi); + } + return 0; +} + const unixlib_entry_t __wine_unix_call_funcs[] = { init_dc, + free_printer_info, };
C_ASSERT(ARRAYSIZE(__wine_unix_call_funcs) == unix_funcs_count); diff --git a/dlls/wineps.drv/unixlib.h b/dlls/wineps.drv/unixlib.h index 9e6c0298086..09ba9d3c662 100644 --- a/dlls/wineps.drv/unixlib.h +++ b/dlls/wineps.drv/unixlib.h @@ -32,10 +32,14 @@ struct font_info enum wineps_funcs { unix_init_dc, + unix_free_printer_info, unix_funcs_count, };
struct init_dc_params { - struct gdi_dc_funcs *funcs; + const struct gdi_dc_funcs *funcs; + PRINTERINFO *pi; + + const WCHAR *name; };