From: Piotr Caban piotr@codeweavers.com
--- dlls/wineps.drv/Makefile.in | 2 + dlls/wineps.drv/init.c | 98 +++------------------- dlls/wineps.drv/psdrv.h | 2 + dlls/wineps.drv/unixlib.c | 157 ++++++++++++++++++++++++++++++++++++ dlls/wineps.drv/unixlib.h | 31 +++++++ 5 files changed, 205 insertions(+), 85 deletions(-) create mode 100644 dlls/wineps.drv/unixlib.c create mode 100644 dlls/wineps.drv/unixlib.h
diff --git a/dlls/wineps.drv/Makefile.in b/dlls/wineps.drv/Makefile.in index 9fe0497c2b2..4dd315757da 100644 --- a/dlls/wineps.drv/Makefile.in +++ b/dlls/wineps.drv/Makefile.in @@ -1,4 +1,5 @@ MODULE = wineps.drv +UNIXLIB = wineps.so IMPORTS = user32 gdi32 winspool advapi32 win32u
C_SRCS = \ @@ -62,6 +63,7 @@ C_SRCS = \ type1.c \ type1afm.c \ type42.c \ + unixlib.c \ vertical.c
RC_SRCS = wineps.rc diff --git a/dlls/wineps.drv/init.c b/dlls/wineps.drv/init.c index afcf4321b11..a1cd09b5ba2 100644 --- a/dlls/wineps.drv/init.c +++ b/dlls/wineps.drv/init.c @@ -28,6 +28,7 @@ #include "winreg.h" #include "winnls.h" #include "winuser.h" +#include "unixlib.h" #include "psdrv.h" #include "winspool.h" #include "wine/debug.h" @@ -98,7 +99,7 @@ static const LOGFONTA DefaultLogFont = { DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" };
-static const struct gdi_dc_funcs psdrv_funcs; +static struct gdi_dc_funcs psdrv_funcs;
/********************************************************************* * DllMain @@ -113,9 +114,18 @@ BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved ) switch(reason) {
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) return FALSE; @@ -131,6 +141,7 @@ BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved ) return FALSE; } break; + }
case DLL_PROCESS_DETACH: if (reserved) break; @@ -448,88 +459,6 @@ BOOL CDECL PSDRV_ResetDC( PHYSDEV dev, const DEVMODEW *lpInitData ) return TRUE; }
-/*********************************************************************** - * GetDeviceCaps (WINEPS.@) - */ -static INT CDECL PSDRV_GetDeviceCaps( PHYSDEV dev, INT cap ) -{ - PSDRV_PDEVICE *physDev = get_psdrv_dev( dev ); - - TRACE("%p,%d\n", dev->hdc, cap); - - switch(cap) - { - case DRIVERVERSION: - return 0; - case TECHNOLOGY: - return DT_RASPRINTER; - case HORZSIZE: - return MulDiv(physDev->horzSize, 100, physDev->Devmode->dmPublic.dmScale); - case VERTSIZE: - return MulDiv(physDev->vertSize, 100, physDev->Devmode->dmPublic.dmScale); - case HORZRES: - return physDev->horzRes; - case VERTRES: - return physDev->vertRes; - case BITSPIXEL: - /* Although Windows returns 1 for monochrome printers, we want - CreateCompatibleBitmap to provide something other than 1 bpp */ - return 32; - case NUMPENS: - return 10; - case NUMFONTS: - return 39; - case NUMCOLORS: - return -1; - case PDEVICESIZE: - return sizeof(PSDRV_PDEVICE); - case TEXTCAPS: - return TC_CR_ANY | TC_VA_ABLE; /* psdrv 0x59f7 */ - case RASTERCAPS: - return (RC_BITBLT | RC_BITMAP64 | RC_GDI20_OUTPUT | RC_DIBTODEV | - RC_STRETCHBLT | RC_STRETCHDIB); /* psdrv 0x6e99 */ - case ASPECTX: - return physDev->logPixelsX; - case ASPECTY: - return physDev->logPixelsY; - case LOGPIXELSX: - return MulDiv(physDev->logPixelsX, physDev->Devmode->dmPublic.dmScale, 100); - case LOGPIXELSY: - return MulDiv(physDev->logPixelsY, physDev->Devmode->dmPublic.dmScale, 100); - case NUMRESERVED: - return 0; - case COLORRES: - return 0; - case PHYSICALWIDTH: - return (physDev->Devmode->dmPublic.dmOrientation == DMORIENT_LANDSCAPE) ? - physDev->PageSize.cy : physDev->PageSize.cx; - case PHYSICALHEIGHT: - return (physDev->Devmode->dmPublic.dmOrientation == DMORIENT_LANDSCAPE) ? - physDev->PageSize.cx : physDev->PageSize.cy; - case PHYSICALOFFSETX: - if(physDev->Devmode->dmPublic.dmOrientation == DMORIENT_LANDSCAPE) { - if(physDev->pi->ppd->LandscapeOrientation == -90) - return physDev->PageSize.cy - physDev->ImageableArea.top; - else - return physDev->ImageableArea.bottom; - } - return physDev->ImageableArea.left; - - case PHYSICALOFFSETY: - if(physDev->Devmode->dmPublic.dmOrientation == DMORIENT_LANDSCAPE) { - if(physDev->pi->ppd->LandscapeOrientation == -90) - return physDev->PageSize.cx - physDev->ImageableArea.right; - else - return physDev->ImageableArea.left; - } - return physDev->PageSize.cy - physDev->ImageableArea.top; - - default: - dev = GET_NEXT_PHYSDEV( dev, pGetDeviceCaps ); - return dev->funcs->pGetDeviceCaps( dev, cap ); - } -} - static PRINTER_ENUM_VALUESA *load_font_sub_table( HANDLE printer, DWORD *num_entries ) { DWORD res, needed, num; @@ -759,7 +688,7 @@ fail: }
-static const struct gdi_dc_funcs psdrv_funcs = +static struct gdi_dc_funcs psdrv_funcs = { .pCreateCompatibleDC = PSDRV_CreateCompatibleDC, .pCreateDC = PSDRV_CreateDC, @@ -767,7 +696,6 @@ static const struct gdi_dc_funcs psdrv_funcs = .pEnumFonts = PSDRV_EnumFonts, .pExtEscape = PSDRV_ExtEscape, .pGetCharWidth = PSDRV_GetCharWidth, - .pGetDeviceCaps = PSDRV_GetDeviceCaps, .pGetTextExtentExPoint = PSDRV_GetTextExtentExPoint, .pGetTextMetrics = PSDRV_GetTextMetrics, .pResetDC = PSDRV_ResetDC, diff --git a/dlls/wineps.drv/psdrv.h b/dlls/wineps.drv/psdrv.h index 9a82576ba0e..63bd04d8cf1 100644 --- a/dlls/wineps.drv/psdrv.h +++ b/dlls/wineps.drv/psdrv.h @@ -585,6 +585,7 @@ extern void passthrough_leave(PHYSDEV dev) DECLSPEC_HIDDEN; setlocale(LC_NUMERIC,tmplocale); \ } while (0)
+#ifndef WINE_UNIX_LIB static inline WCHAR *strdupW( const WCHAR *str ) { int size; @@ -596,5 +597,6 @@ static inline WCHAR *strdupW( const WCHAR *str ) if (ret) memcpy( ret, str, size ); return ret; } +#endif
#endif diff --git a/dlls/wineps.drv/unixlib.c b/dlls/wineps.drv/unixlib.c new file mode 100644 index 00000000000..2b85ec5d558 --- /dev/null +++ b/dlls/wineps.drv/unixlib.c @@ -0,0 +1,157 @@ +/* + * Unix interface for wineps.drv + * + * Copyright 1998 Huw D M Davies + * Copyright 2001 Marcus Meissner + * Copyright 2023 Piotr Caban for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#if 0 +#pragma makedep unix +#endif + +#include <stdarg.h> + +#include "windef.h" +#include "winbase.h" + +#include "psdrv.h" +#include "unixlib.h" +#include "wine/gdi_driver.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(psdrv); + +/* copied from kernelbase */ +static int muldiv(int a, int b, int c) +{ + LONGLONG ret; + + if (!c) return -1; + + /* We want to deal with a positive divisor to simplify the logic. */ + if (c < 0) + { + a = -a; + c = -c; + } + + /* If the result is positive, we "add" to round. else, we subtract to round. */ + if ((a < 0 && b < 0) || (a >= 0 && b >= 0)) + ret = (((LONGLONG)a * b) + (c / 2)) / c; + else + ret = (((LONGLONG)a * b) - (c / 2)) / c; + + if (ret > 2147483647 || ret < -2147483647) return -1; + return ret; +} + +static INT CDECL get_device_caps(PHYSDEV dev, INT cap) +{ + PSDRV_PDEVICE *pdev = get_psdrv_dev(dev); + + TRACE("%p,%d\n", dev->hdc, cap); + + switch(cap) + { + case DRIVERVERSION: + return 0; + case TECHNOLOGY: + return DT_RASPRINTER; + case HORZSIZE: + return muldiv(pdev->horzSize, 100, pdev->Devmode->dmPublic.dmScale); + case VERTSIZE: + return muldiv(pdev->vertSize, 100, pdev->Devmode->dmPublic.dmScale); + case HORZRES: + return pdev->horzRes; + case VERTRES: + return pdev->vertRes; + case BITSPIXEL: + /* Although Windows returns 1 for monochrome printers, we want + CreateCompatibleBitmap to provide something other than 1 bpp */ + return 32; + case NUMPENS: + return 10; + case NUMFONTS: + return 39; + case NUMCOLORS: + return -1; + case PDEVICESIZE: + return sizeof(PSDRV_PDEVICE); + case TEXTCAPS: + return TC_CR_ANY | TC_VA_ABLE; /* psdrv 0x59f7 */ + case RASTERCAPS: + return (RC_BITBLT | RC_BITMAP64 | RC_GDI20_OUTPUT | RC_DIBTODEV | + RC_STRETCHBLT | RC_STRETCHDIB); /* psdrv 0x6e99 */ + case ASPECTX: + return pdev->logPixelsX; + case ASPECTY: + return pdev->logPixelsY; + case LOGPIXELSX: + return muldiv(pdev->logPixelsX, pdev->Devmode->dmPublic.dmScale, 100); + case LOGPIXELSY: + return muldiv(pdev->logPixelsY, pdev->Devmode->dmPublic.dmScale, 100); + case NUMRESERVED: + return 0; + case COLORRES: + return 0; + case PHYSICALWIDTH: + return (pdev->Devmode->dmPublic.dmOrientation == DMORIENT_LANDSCAPE) ? + pdev->PageSize.cy : pdev->PageSize.cx; + case PHYSICALHEIGHT: + return (pdev->Devmode->dmPublic.dmOrientation == DMORIENT_LANDSCAPE) ? + pdev->PageSize.cx : pdev->PageSize.cy; + case PHYSICALOFFSETX: + if (pdev->Devmode->dmPublic.dmOrientation == DMORIENT_LANDSCAPE) + { + if (pdev->pi->ppd->LandscapeOrientation == -90) + return pdev->PageSize.cy - pdev->ImageableArea.top; + else + return pdev->ImageableArea.bottom; + } + return pdev->ImageableArea.left; + + case PHYSICALOFFSETY: + if (pdev->Devmode->dmPublic.dmOrientation == DMORIENT_LANDSCAPE) + { + if (pdev->pi->ppd->LandscapeOrientation == -90) + return pdev->PageSize.cx - pdev->ImageableArea.right; + else + return pdev->ImageableArea.left; + } + return pdev->PageSize.cy - pdev->ImageableArea.top; + + default: + dev = GET_NEXT_PHYSDEV(dev, pGetDeviceCaps); + return dev->funcs->pGetDeviceCaps(dev, cap); + } +} + +static NTSTATUS init_dc(void *arg) +{ + struct init_dc_params *params = arg; + + params->funcs->pGetDeviceCaps = get_device_caps; + return TRUE; +} + +const unixlib_entry_t __wine_unix_call_funcs[] = +{ + init_dc, +}; + +C_ASSERT(ARRAYSIZE(__wine_unix_call_funcs) == unix_funcs_count); diff --git a/dlls/wineps.drv/unixlib.h b/dlls/wineps.drv/unixlib.h new file mode 100644 index 00000000000..95efdd4c310 --- /dev/null +++ b/dlls/wineps.drv/unixlib.h @@ -0,0 +1,31 @@ +/* + * Copyright 2022 Piotr Caban for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "ntuser.h" +#include "wine/unixlib.h" + +enum wineps_funcs +{ + unix_init_dc, + unix_funcs_count, +}; + +struct init_dc_params +{ + struct gdi_dc_funcs *funcs; +};