📄 graphicsdriverentrypoints.cpp
字号:
/* * * graphicsDriverEntryPoints.c Copyright (C) 2006 Michael H. Overlin This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Contact at poster_printer@yahoo.com * */#include "graphicsDllCommon.h"#include "..\lib\debug.h"#include "..\lib\extDevMode.h"#include "..\lib\fallback.h"#include "..\lib\gdiutils.h"#include "..\lib\mathutils.h"#include "..\lib\printResizerCommon.h"#include "..\lib\spoolutils.h"#include "..\lib\utils.h"#include <windows.h>#include <winspool.h>#include <winddi.h>#include <malloc.h>// PRIVATE TYPDEFStypedef struct _PDEV { HPALETTE hpalDefault; HDEV hdev; HSURF hsurf; ULONG ulDitherFormat; GDIINFO gdiinfo; } PDEV;typedef PDEV *PPDEV;// PRIVATE PROTOTYPESvoid SetDEVINFO(PDEVINFO pDevInfo, DWORD dwcBuff) ;BOOL GetGDIINFOFromTarget(PGDIINFO pGDIInfo, PCDEVMODE pdmTargetPrinter) ;// GLOBALSHANDLE ghModule;ULONG giEngineVersion;static DRVFN RasterFuncs[] = { {INDEX_DrvEnablePDEV , (PFN)DrvEnablePDEV }, {INDEX_DrvCompletePDEV , (PFN)DrvCompletePDEV }, {INDEX_DrvDisablePDEV , (PFN)DrvDisablePDEV }, {INDEX_DrvEnableSurface , (PFN)DrvEnableSurface }, {INDEX_DrvDisableSurface , (PFN)DrvDisableSurface }, {INDEX_DrvResetPDEV , (PFN)DrvResetPDEV }, {INDEX_DrvDisableDriver , (PFN)DrvDisableDriver }, // MINIMUM REQUIRED FOR AN "OPAQUE" DEVICE MANAGED SURFACE {INDEX_DrvStrokePath , (PFN)DrvStrokePath }, {INDEX_DrvCopyBits , (PFN)DrvCopyBits }, {INDEX_DrvTextOut , (PFN)DrvTextOut }, // SOME STUFF FOR PRINTER DRIVERS, ONLY DrvEndDoc, DrvSendPage, DrvStartDoc, DrvStartPage // ARE ACTUALLY REQUIRED {INDEX_DrvStartBanding , (PFN)DrvStartBanding }, {INDEX_DrvNextBand , (PFN)DrvNextBand }, {INDEX_DrvStartDoc , (PFN)DrvStartDoc }, {INDEX_DrvEndDoc , (PFN)DrvEndDoc }, {INDEX_DrvStartPage , (PFN)DrvStartPage }, {INDEX_DrvSendPage , (PFN)DrvSendPage }, // ADD SOME MORE, DON'T KNOW WHICH I NEED { INDEX_DrvRealizeBrush , (PFN) DrvRealizeBrush }, { INDEX_DrvFillPath , (PFN) DrvFillPath }, { INDEX_DrvStrokeAndFillPath, (PFN) DrvStrokeAndFillPath }, { INDEX_DrvPaint , (PFN) DrvPaint }, { INDEX_DrvLineTo , (PFN) DrvLineTo }, { INDEX_DrvCreateDeviceBitmap, (PFN) DrvCreateDeviceBitmap }, { INDEX_DrvDeleteDeviceBitmap, (PFN) DrvDeleteDeviceBitmap }, { INDEX_DrvBitBlt , (PFN) DrvBitBlt }, { INDEX_DrvStretchBlt , (PFN) DrvStretchBlt }, { INDEX_DrvStretchBltROP , (PFN) DrvStretchBltROP }, { INDEX_DrvEscape , (PFN) DrvEscape }, { INDEX_DrvDrawEscape , (PFN) DrvDrawEscape } // MAY WANT TO ADD ANY THAT CAN MINIMIZE INTERNAL GDI RENDERING WORK // IF IT TURNS OUT ANY RENDERING FNS ARE ACTUALLY CALLED AT ALL};// PUBLIC ROUTINESBOOL CALLBACK DllMain( HANDLE hModule, ULONG ulReason, PCONTEXT pContext ) { switch (ulReason) { case DLL_PROCESS_ATTACH: { //WCHAR wName[MAX_PATH]; ghModule = hModule; /* keep the dll loaded */ /* if (GetModuleFileName((HINSTANCE)hModule, wName, MAX_PATH)) LoadLibrary(wName); */ break; } case DLL_PROCESS_DETACH: break; } return TRUE;}BOOL CALLBACK DrvEnableDriver( ULONG iEngineVersion, ULONG cj, PDRVENABLEDATA pded ) { if (iEngineVersion < DDI_DRIVER_VERSION) { return(FALSE); } if (cj < sizeof(DRVENABLEDATA)) { return(FALSE); } giEngineVersion = iEngineVersion; pded->iDriverVersion = DDI_DRIVER_VERSION_NT5; pded->c = ARRCOUNT(RasterFuncs); pded->pdrvfn = RasterFuncs; return TRUE;}BOOL CALLBACK DrvQueryDriverInfo( DWORD dwMode, PVOID pBuffer, DWORD cbBuf, PDWORD pcbNeeded ) { switch (dwMode) { case DRVQUERY_USERMODE: *pcbNeeded = sizeof(DWORD); if (pBuffer == NULL || cbBuf < sizeof(DWORD)) { SetLastError(ERROR_INSUFFICIENT_BUFFER); return FALSE; } *((PDWORD) pBuffer) = TRUE; return TRUE; default: SetLastError(ERROR_INVALID_PARAMETER); break; } return FALSE;}BOOL CALLBACK DrvStartBanding( SURFOBJ *pso, POINTL *pptl ){ DUMPMSG("DrvStartBanding"); return TRUE;}BOOL CALLBACK DrvNextBand( SURFOBJ *pso, POINTL *pptl ){ DUMPMSG("DrvNextBand"); return TRUE;}ULONG palette[256];DHPDEV CALLBACKDrvEnablePDEV( IN DEVMODEW *pdm, // Pointer to DEVMODE IN LPWSTR pwszLogAddress, // Logical address IN ULONG cPat /*NU*/, // number of patterns OUT HSURF* phsurfPatterns /*NU*/, // Return standard patterns IN ULONG cjCaps, // Length of memory pointed to by pGdiInfo OUT ULONG *pdevcaps, // Pointer to GdiInfo structure IN ULONG cjDevInfo, // Length of following PDEVINFO structure OUT DEVINFO *pdi, // physical device information structure IN HDEV hdev /*NU*/, // HDEV, used for callbacks IN LPWSTR pwszDeviceName /*NU*/, // DeviceName - not used IN HANDLE hDriver // Handle to base driver) { BOOL bSuccess = FALSE; HANDLE hPrinter = hDriver; PDEVINFO pDevInfo = (PDEVINFO) pdi; PGDIINFO pGdiInfo = (PGDIINFO) pdevcaps; static BOOL bBreak = STATICBOOLBREAK; ASSERT(!bBreak); PPDEV ppdev = (PPDEV) malloc(sizeof(*ppdev)); if (ppdev != NULL) { ZeroMemory(ppdev, sizeof(*ppdev)); PEXTDEVMODE pextdm = EXTDM_New(); if (pextdm != NULL) { LPTSTR lptstrPrinterName = GetPrinterName(hPrinter); if (lptstrPrinterName != NULL) { EXTDM_SetAppDevMode(pextdm, pdm, lptstrPrinterName); LPCTSTR lptstrTargetPrinterName = EXTDM_GetTargetPrinterName(pextdm); PCDEVMODE pdmTemp = ::EXTDM_GetTargetPrinterDevMode(pextdm); if (pdmTemp != NULL) { BOOL bFallBack = FALSE; BOOL bProceed = TRUE; if ( ::EXTDM_IsAnExtDevMode(pdmTemp) ) { PCEXTDEVMODE pextdmTemp = (PCEXTDEVMODE) pdmTemp; BOOL bCircular; if ( ::EXTDM_IsCircular(bCircular, pextdmTemp) ) { bFallBack = bCircular; } else { bProceed = FALSE; } } if (bProceed) { if ( ! bFallBack ) { if (::GetGDIINFOFromTarget(& ppdev->gdiinfo, pdmTemp)) { bSuccess = TRUE; } } else { if ( ::Fallback_GetGDIINFO(& ppdev->gdiinfo, pdmTemp )) { bSuccess = TRUE; } } } ::CopyMemory(pGdiInfo, & ppdev->gdiinfo, min(cjCaps, sizeof(ppdev->gdiinfo))); ::EXTDM_ReleaseTargetPrinterDevMode(pextdm, pdmTemp); } EXTDM_Delete(pextdm); free(lptstrPrinterName); } } } if (bSuccess) { SetDEVINFO(pDevInfo, cjDevInfo); ppdev->ulDitherFormat = pDevInfo->iDitherFormat; ppdev->hpalDefault = pDevInfo->hpalDefault; } if (!bSuccess) { DrvDisablePDEV( (DHPDEV) ppdev); ppdev = NULL; } return (DHPDEV) ppdev;}VOID CALLBACK DrvCompletePDEV(DHPDEV dhpdev,HDEV hdev) { PPDEV ppdev = (PPDEV) dhpdev; ppdev->hdev = hdev;}// THIS ROUTINE IS ALSO CALLED INTERNALLY FROM DrvEnablePDEV IN CASE OF FAILURE// TO FREE ALLOCATED RESOURCES BEFORE TURNING NULLVOID CALLBACK DrvDisablePDEV(DHPDEV dhpdev) { PPDEV ppdev = (PPDEV) dhpdev; if (ppdev != NULL) { if (ppdev->hpalDefault != NULL) { EngDeletePalette(ppdev->hpalDefault); ppdev->hpalDefault = NULL; } free(ppdev); }}HSURF CALLBACK DrvEnableSurface(DHPDEV dhpdev) { PPDEV ppdev = (PPDEV) dhpdev; BOOL b; SIZEL sizeSurface; sizeSurface.cx = ppdev->gdiinfo.ulHorzRes; sizeSurface.cy = ppdev->gdiinfo.ulVertRes; ppdev->hsurf = EngCreateDeviceSurface( (DHSURF) ppdev, sizeSurface, ppdev->ulDitherFormat); if (ppdev->hsurf != NULL) { FLONG flHooks = HOOK_BITBLT | HOOK_STRETCHBLT | HOOK_COPYBITS | HOOK_STROKEPATH | HOOK_FILLPATH | HOOK_STROKEANDFILLPATH | //HOOK_PAINT | OBSOLETE HOOK_TEXTOUT | //HOOK_STRETCHBLTROP | ASSOCIATE SURF IS FAILING 0; // MSPLOT HAS ALL BUT HOOK_STRETCHBLTROP // AND PRINT MIRROR HAS EXACTLY THESE b = EngAssociateSurface( ppdev->hsurf, ppdev->hdev, flHooks ); if (!b) { EngDeleteSurface(ppdev->hsurf); ppdev->hsurf = NULL; } } return ppdev->hsurf;}VOID CALLBACK DrvDisableSurface(DHPDEV dhpdev) { PPDEV ppdev = (PPDEV) dhpdev; EngDeleteSurface( ppdev->hsurf ); ppdev->hsurf = NULL;}/* * No real resource swapping here. * DrvRestPdev is visited in the following order * oldpdev = DrvEnablePdev(...) * DrvCompletepdev(oldpdev,...) * newpdev = DrvEnablepdev(...) * DrvResetpdev(old,new) * DrvDisablepdev(oldpdev) * we return TRUE as we don't have much to do here * Plan to keep the devmode here or we could take from EMF *//* -- from documentation: (quote) If ResetDC is called during the rendering of a print document, the printer graphics DLL receives the following sequence of calls: dhpdevNew = DrvEnablePDEV(); DrvResetPDEV(dhpdevOld, dhpdevNew); DrvDisableSurface(dhpdevOld); DrvDisablePDEV(dhpdevOld); DrvEnableSurface(dhpdevNew); DrvStartDoc(dhpdevNew);If ResetDC is called between documents there is no surface associated with the PDEV, so only the following sequence of calls is made: dhpdevNew = DrvEnablePDEV(); DrvResetPDEV(dhpdevOld,dhpdevNew); DrvDisablePDEV(dhpdevOld);also from the "ResetDC" docs (quote)ResetDC can also be used to change the paper orientation or paper bins while printing a document. -- so i would think these kinds of itmes ought to be copied over as well (?)*/BOOL CALLBACK DrvResetPDEV(DHPDEV dhpdevOld, DHPDEV dhpdevNew) { int k = 0; // dumb, diff from DrvEndDoc ! ++k;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -