Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1627 lines
40 KiB

/*++
Copyright (c) 1990-1993 Microsoft Corporation
Module Name:
enable.c
Abstract:
This module contains the Plotter driver's Enable and Disable functions
and related routines.
The functions dealing with driver initialization are as follows:
DrvEnableDriver()
DrvEnablePDEV()
DrvRestartPDEV()
DrvCompletePDEV()
DrvEnableSurface()
DrvDisableSurface()
DrvDisablePDEV()
DrvDisableDriver()
Author:
12-Nov-1993 Fri 10:16:36 updated -by- Daniel Chou (danielc)
Move all #define related only to this function to here
15-Nov-1993 Mon 19:31:34 updated -by- Daniel Chou (danielc)
clean up / debugging information
05-Jan-1994 Wed 22:50:28 updated -by- Daniel Chou (danielc)
Move ColorMap's RGB pen color to local so that we only need array
reference, it defined PenRGBColor as DWORD from RGB() macro
[Environment:]
GDI Device Driver - Plotter.
[Notes:]
Revision History:
--*/
#include "precomp.h"
#pragma hdrstop
#define DBG_PLOTFILENAME DbgEnable
#define DBG_ENABLEDRV 0x00000001
#define DBG_DISABLEDRV 0x00000002
#define DBG_ENABLEPDEV 0x00000004
#define DBG_COMPLETEPDEV 0x00000008
#define DBG_DISABLEPDEV 0x00000010
#define DBG_ENABLESURF 0x00000020
#define DBG_DISABLESURF 0x00000040
#define DBG_GDICAPS 0x00000080
#define DBG_DEVCAPS 0x00000100
#define DBG_PENPAL 0x00000200
#define DBG_BAND 0x00000400
#define DBG_DLLINIT 0x00000800
DEFINE_DBGVAR(0);
#if DBG
TCHAR DebugDLLName[] = TEXT("PLOTTER");
#endif
#define FIXUP_PLOTGPC_PDATA(pd,ps,v) \
if (ps->v) {pd->v=(LPVOID)((LPBYTE)pd+((LPBYTE)(ps->v)-(LPBYTE)ps));}
// local function forward prototypes
BOOL
CommonStartPDEV(
PDEV *pPDev,
DEVMODEW *pPlotDMIn,
ULONG cPatterns,
HSURF *phsurfPatterns,
ULONG cjDevCaps,
ULONG *pDevCaps,
ULONG cjDevInfo,
DEVINFO *pDevInfo
);
//
// Move hooked function to this file because only used here, and it is not a
// good idea to have variable defined in header file
//
static const DRVFN DrvFuncTable[] = {
{ INDEX_DrvEnablePDEV, (PFN)DrvEnablePDEV },
{ INDEX_DrvResetPDEV, (PFN)DrvResetPDEV },
{ INDEX_DrvCompletePDEV, (PFN)DrvCompletePDEV },
{ INDEX_DrvDisablePDEV, (PFN)DrvDisablePDEV },
{ INDEX_DrvEnableSurface, (PFN)DrvEnableSurface },
{ INDEX_DrvDisableSurface, (PFN)DrvDisableSurface },
// { INDEX_DrvQueryFont, (PFN)DrvQueryFont },
// { INDEX_DrvQueryFontTree, (PFN)DrvQueryFontTree },
// { INDEX_DrvQueryFontData, (PFN)DrvQueryFontData },
{ INDEX_DrvStrokePath, (PFN)DrvStrokePath },
{ INDEX_DrvStrokeAndFillPath, (PFN)DrvStrokeAndFillPath },
{ INDEX_DrvFillPath, (PFN)DrvFillPath },
{ INDEX_DrvRealizeBrush, (PFN)DrvRealizeBrush },
{ INDEX_DrvBitBlt, (PFN)DrvBitBlt },
{ INDEX_DrvStretchBlt, (PFN)DrvStretchBlt },
{ INDEX_DrvCopyBits, (PFN)DrvCopyBits },
{ INDEX_DrvPaint, (PFN)DrvPaint },
{ INDEX_DrvGetGlyphMode, (PFN)DrvGetGlyphMode },
{ INDEX_DrvTextOut, (PFN)DrvTextOut },
{ INDEX_DrvSendPage, (PFN)DrvSendPage },
{ INDEX_DrvStartPage, (PFN)DrvStartPage },
{ INDEX_DrvStartDoc, (PFN)DrvStartDoc },
{ INDEX_DrvEndDoc, (PFN)DrvEndDoc },
{ INDEX_DrvEscape, (PFN)DrvEscape },
};
#define TOTAL_DRVFUNC (sizeof(DrvFuncTable)/sizeof(DrvFuncTable[0]))
BOOL
DrvEnableDriver(
ULONG iEngineVersion,
ULONG cb,
DRVENABLEDATA *pded
)
/*++
Routine Description:
Requests the driver to fill in a structure containing recognized functions
and other control information. One time initialization, such as semaphore
allocation may be performed, but no device activity should happen. That
is done when dhpdevEnable is called. This function is the only way the
engine can determine what functions we supply to it.
Arguments:
iEngineVersion - The engine version which we run under
cb - total bytes in pded
pded - Pointer to the DRVENABLEDATA data structure
Return Value:
TRUE if sucssfully FALSE otherwise
Author:
01-Dec-1993 Wed 02:03:20 created -by- Daniel Chou (danielc)
03-Mar-1994 Thu 10:04:30 updated -by- Daniel Chou (danielc)
Adding EngineVersion check to make sure ourself can run correctly.
Revision History:
--*/
{
PLOTDBG(DBG_ENABLEDRV, ("DrvEnableDriver: EngineVersion=%08lx, Request=%08lx",
iEngineVersion, DDI_DRIVER_VERSION));
//
// This driver required EngineVersion to be at least 0x00010001 (Daytona)
// so if we running on lower GDI version we could GP fault so don't do it
//
if (iEngineVersion < DDI_DRIVER_VERSION) {
PLOTRIP(("DrvEnableDriver: EARLIER VERSION: EngineVersion(%08lx) < Request(%08lx)",
iEngineVersion, DDI_DRIVER_VERSION));
EngSetLastError(ERROR_BAD_DRIVER_LEVEL);
return(FALSE);
}
//
// cb is a count of the number of bytes available in pded. It is not
// clear that there is any significant use of the engine version number.
// Returns TRUE if successfully enabled, otherwise FALSE.
//
// iEngineVersion is the engine version while DDI_DRIVER_VERSION is the
// driver version. So, unless we re-compile the driver and get a new
// version of driver, we can only stick with the our version.
//
if (cb < sizeof(DRVENABLEDATA)) {
EngSetLastError(ERROR_INVALID_PARAMETER);
PLOTRIP(("DrvEnableDriver: cb=%ld, should be %ld\n",
cb, sizeof(DRVENABLEDATA)));
return(FALSE);
}
pded->iDriverVersion = DDI_DRIVER_VERSION;
//
// Fill in the driver table returned to the engine. We return the minimum
// of the number of functions supported OR the number the engine has asked
// for.
//
pded->c = TOTAL_DRVFUNC;
pded->pdrvfn = (DRVFN *)DrvFuncTable;
//
// Initialize the GPC cache
//
InitCachedData();
return(TRUE);
}
VOID
DrvDisableDriver(
VOID
)
/*++
Routine Description:
Called just before the engine unloads the driver. Main purpose is
to allow freeing any resources obtained during the DrvEnableDriver()
function call.
Arguments:
NONE
Return Value:
VOID
Author:
01-Dec-1993 Wed 02:02:18 created -by- Daniel Chou (danielc)
01-Feb-1994 Tue 22:03:03 updated -by- Daniel Chou (danielc)
Make sure we unload the cache.
Revision History:
--*/
{
DestroyCachedData();
PLOTDBG(DBG_DISABLEDRV, ("DrvDisableDriver: Done!!"));
}
VOID
FreeAllocMem(
PPDEV pPDev
)
/*++
Routine Description:
This function free all the memory allocated durning the PDEV liftime
Arguments:
pPDev - Our instance data
Return Value:
VOID
Author:
24-Oct-1995 Tue 16:28:35 created -by- Daniel Chou (danielc)
Revision History:
--*/
{
//
// Free any font memory that may have been allocated.
//
if (pPDev) {
PDRVHTINFO pDrvHTInfo;
if (pPDev->hPalDefault) {
EngDeletePalette(pPDev->hPalDefault);
pPDev->hPalDefault = NULL;
}
if (pDrvHTInfo = (PDRVHTINFO)(pPDev->pvDrvHTData)) {
if (pDrvHTInfo->pHTXB) {
LocalFree((HLOCAL)pDrvHTInfo->pHTXB);
pDrvHTInfo->pHTXB = NULL;
}
pPDev->pvDrvHTData = NULL;
}
if (pPDev->pPenCache) {
LocalFree((HLOCAL)pPDev->pPenCache);
pPDev->pPenCache = NULL;
}
if (pPDev->pTransPosTable) {
LocalFree((HLOCAL)pPDev->pTransPosTable);
pPDev->pTransPosTable = NULL;
}
FreeOutBuffer(pPDev);
LocalFree((HLOCAL)pPDev);
}
}
DHPDEV
DrvEnablePDEV(
DEVMODEW *pPlotDMIn,
PWSTR pwszLogAddr,
ULONG cPatterns,
HSURF *phsurfPatterns,
ULONG cjDevCaps,
ULONG *pDevCaps,
ULONG cjDevInfo,
DEVINFO *pDevInfo,
HDEV hdev,
PWSTR pwszDeviceName,
HANDLE hDriver
)
/*++
Routine Description:
Function called to let the driver create the data structures
needed to support the device, and also to tell the engine
about its capabilities. This is the stage where we find out
exactly which device we are dealing with, and so we need to
find out its capabilities.
Arguments:
pPlotDMIn - Pointer to the DEVMODE data structure
pwszLogAddr - pointer to the output location, (ie. LPT1
cPatterns - Count of pattern to be set in phsurfPatterns
phsurfPatterns - pointer to the standard pattern HSURF array
cjDevCaps - total size of pDevCaps pointed to.
pDevCaps - pointer to the device cap DWORDs
cjDevInfo - total size of pDevInfo pointed to
pDevInfo - pointer to the DEVINFO data structure
hdev - Handle to the logical device from the engine
pwszDeviceName - pointer to the plotter device name
hDriver - handle to this driver
Return Value:
DHPDEV if sucessful, NULL if failed
Author:
15-Dec-1993 Wed 21:04:40 updated -by- Daniel Chou (danielc)
Add cached mechanism for the PLOTGPC
14-Dec-1993 Tue 20:22:26 updated -by- Daniel Chou (danielc)
Update how the pen plotter data should work
23-Nov-1993 Tue 19:48:08 updated -by- Daniel Chou (danielc)
Clean up and using new devmode.c in ..\lib directory
17:30 on Mon 1 Apr 1991 -by- Steve Cathcart [stevecat]
Took skeletal code from RASDD printer driver
16-Jul-1996 Tue 13:59:15 updated -by- Daniel Chou (danielc)
Fix up the pData in the PLOTGPC/GPCVARSIZE structure, since the
pointer is based on the cached GPC not the clone copy of it
Revision History:
--*/
{
PPDEV pPDev = NULL;
PPLOTGPC pPlotGPC;
LPWSTR pwszDataFile;
UNREFERENCED_PARAMETER(pwszLogAddr);
if (!(pwszDataFile = EngGetPrinterDataFileName(hdev))) {
PLOTRIP(("DrvEnablePDEV: EngGetPrinteDataFileName() failed"));
} else if (!(pPlotGPC = GetCachedPlotGPC(pwszDataFile))) {
PLOTRIP(("DrvEnablePDEV: GetCachedPlotGPC(%ws) failed", pwszDataFile));
} else if (!(pPDev = (PPDEV)LocalAlloc(LPTR,
sizeof(PDEV) + sizeof(DRVHTINFO) +
pPlotGPC->cjThis +
pPlotGPC->SizeExtra))) {
//
// Free the cached pPlotGPC before we leave
//
UnGetCachedPlotGPC(pPlotGPC);
PLOTRIP(("DrvEnablePDEV: LocalAlloc(PDEV + DRVHTINFO + pPlotGPC) failed."));
} else {
PLOTDBG(DBG_ENABLEPDEV,("EnablePDEV: PlotGPC data file=%ws",
pwszDataFile));
//
// If we got the PDEV set the ID for later checking, also set the
// hPrinter so later we can use it
//
pPDev->pvDrvHTData = (LPVOID)((LPBYTE)pPDev + sizeof(PDEV));
pPDev->hPrinter = hDriver;
pPDev->SizePDEV = sizeof(PDEV);
pPDev->PDEVBegID = PDEV_BEG_ID;
pPDev->PDEVEndID = PDEV_END_ID;
//
// We will get the PLOTGPC out from the cached, the pPlotGPC is
// allocated by the ReadPlotGPCFromFile() using LocalAlloc().
//
// *** NOW we will Clone the cached pPlotGPC then un-cached it
//
pPDev->pPlotGPC = (PPLOTGPC)((LPBYTE)pPDev + sizeof (PDEV) +
sizeof(DRVHTINFO));
CopyMemory(pPDev->pPlotGPC,
pPlotGPC,
pPlotGPC->cjThis + pPlotGPC->SizeExtra);
//
// 16-Jul-1996 Tue 13:59:15 updated -by- Daniel Chou (danielc)
// Fix up the pData in the PLOTGPC/GPCVARSIZE structure, since the
// pointer is based on the cached GPC not the clone copy of it
//
FIXUP_PLOTGPC_PDATA(pPDev->pPlotGPC, pPlotGPC, InitString.pData);
FIXUP_PLOTGPC_PDATA(pPDev->pPlotGPC, pPlotGPC, Forms.pData);
FIXUP_PLOTGPC_PDATA(pPDev->pPlotGPC, pPlotGPC, Pens.pData);
UnGetCachedPlotGPC(pPlotGPC);
//
// Now, depends on the pen/raster plotter, we will update the
// pen data only if we have one and needs one
//
PLOTASSERT(1, "Raster Plotter should not have PEN data [%08lx]",
((pPDev->pPlotGPC->Flags & PLOTF_RASTER) &&
(pPDev->pPlotGPC->Pens.pData == NULL)) ||
((!(pPDev->pPlotGPC->Flags & PLOTF_RASTER)) &&
(pPDev->pPlotGPC->Pens.pData != NULL)),
pPDev->pPlotGPC->Pens.pData);
//
// Try to get from registry if user did some modification to
// the printer properties, such as DEVHTINFO or type of paper
// loaded in the plotter, if none then default paper will be
// assumed, also when we update pen data it will using current
// pen set.
//
GetDefaultPlotterForm(pPDev->pPlotGPC, &(pPDev->CurPaper));
//
// Set the default Flags in case we did not update from registry
//
pPDev->PPData.Flags = PPF_AUTO_ROTATE |
PPF_SMALLER_FORM |
PPF_MANUAL_FEED_CX;
if (IS_RASTER(pPDev)) {
//
// The raster do not need pen data
//
UpdateFromRegistry(hDriver,
&(pPDev->pPlotGPC->ci),
&(pPDev->pPlotGPC->DevicePelsDPI),
&(pPDev->pPlotGPC->HTPatternSize),
&(pPDev->CurPaper),
&(pPDev->PPData),
NULL,
0,
NULL);
} else {
//
// The Pen plotter do not need ColorInfo, DevicePelsDPI and
// HTPatternSize
//
UpdateFromRegistry(hDriver,
NULL,
NULL,
NULL,
&(pPDev->CurPaper),
&(pPDev->PPData),
NULL,
MAKELONG(0xFFFF, pPDev->pPlotGPC->MaxPens),
(PPENDATA)pPDev->pPlotGPC->Pens.pData);
}
//
// common code for DrvEnablePDEV and DrvRestartPDEV
// we must first copy the device name to the pPDev->PlotDM
// then call the common stuff
//
WCPYFIELDNAME(pPDev->PlotDM.dm.dmDeviceName, pwszDeviceName);
if (!CommonStartPDEV(pPDev,
pPlotDMIn,
cPatterns,
phsurfPatterns,
cjDevCaps,
pDevCaps,
cjDevInfo,
pDevInfo)) {
FreeAllocMem(pPDev);
pPDev = NULL;
PLOTRIP(("DrvEnablePDEV: CommonStartPDEV() failed."));
}
}
return((DHPDEV)pPDev);
}
BOOL
DrvResetPDEV(
DHPDEV dhpdevOld,
DHPDEV dhpdevNew
)
/*++
Routine Description:
Called when an application wishes to change the output style in the
midst of a job. Typically this would be to change from portrait to
landscape or vice versa. Any other sensible change is permitted.
Arguments:
dhpdevOld - the OLD pPDev which we returned in DrvEnablePDEV
dhpdevNew - the NEW pPDev which we returned in DrvEnablePDEV
Return Value:
BOOLEAN
Author:
23-Nov-1993 Tue 20:07:45 updated -by- Daniel Chou (danielc)
totaly re-write
17:30 on Mon 1 Apr 1991 -by- Steve Cathcart [stevecat]
Took skeletal code from RASDD printer driver
Revision History:
--*/
{
#define pPDevOld ((PDEV *) dhpdevOld)
#define pPDevNew ((PDEV *) dhpdevNew)
//
// Make sure we got the correct pPlotDMin for this pPDev
//
if ((pPDevOld->PlotDM.dm.dmDriverVersion !=
pPDevNew->PlotDM.dm.dmDriverVersion) ||
(wcscmp((LPWSTR)pPDevOld->PlotDM.dm.dmDeviceName,
(LPWSTR)pPDevNew->PlotDM.dm.dmDeviceName))) {
PLOTERR(("DrvResetPDEV: Incompatible PLOTDEVMODE"));
EngSetLastError(ERROR_INVALID_PARAMETER);
return(FALSE);
}
//
// We have nothing to carry over from old to new
//
return(TRUE);
#undef pPDevNew
#undef pPDevOld
}
VOID
DrvCompletePDEV(
DHPDEV dhpdev,
HDEV hpdev
)
/*++
Routine Description:
Called when the engine has completed installation of the physical
device. Basically it provides the connection between the
engine's hpdev and ours. Some functions require us to pass in
the engines's hpdev, so we save it now in our pdev so that we
can get to it later.
Arguments:
dhpdev - Returned from dhpdevCreatePDEV
hpdev - Engine's corresponding handle
Return Value:
VOID
Author:
01-Dec-1993 Wed 01:56:58 created -by- Daniel Chou (danielc)
Revision History:
--*/
{
//
// Simply record the value in the PDEV we have allocated.
//
((PPDEV)dhpdev)->hpdev = hpdev;
PLOTDBG(DBG_COMPLETEPDEV, ("CompletePDEV: Done!"));
}
VOID
DrvDisablePDEV(
DHPDEV dhpdev
)
/*++
Routine Description:
Called when the engine has finished with this PDEV. Basically we throw
away all connections etc. then free the memory.
Arguments:
dhpdev - OUR handle to the pdev
Return Value:
VOID
Author:
01-Dec-1993 Wed 01:55:43 created -by- Daniel Chou (danielc)
Revision History:
--*/
{
#define pPDev ((PDEV *) dhpdev)
//
// Undo all that has been done with the PDEV. Basically this means
// freeing the memory we consumed.
//
FreeAllocMem(pPDev);
PLOTDBG(DBG_DISABLEPDEV, ("DrvDisablePDEV: FreeAllocMem() completes"));
#undef pPDev
}
HSURF
DrvEnableSurface(
DHPDEV dhpdev
)
/*++
Routine Description:
Function to create the physical drawing surface for the pdev
that was created earlier. Since we don't really have a bitmap surface,
all we do here is allocate the output buffer.
Arguments:
dhpdev - OUR handle to the pdev
Return Value:
HSURF for the surface we created
Author:
01-Dec-1993 Wed 01:47:36 created -by- Daniel Chou (danielc)
10-Dec-1993 Fri 16:36:37 updated -by- Daniel Chou (danielc)
Move PlotCreatePalette() to here to prevent GP
16-Dec-1993 Thu 12:16:11 updated -by- Daniel Chou (danielc)
Move PlotCreatePalette() out to SendPageHeader() in output.c so that
we do not sending some PC commands which has no effects.
06-Jan-1994 Thu 04:12:37 updated -by- Daniel Chou (danielc)
Re-arrange the code sequence.
Adding Error codes so it will failed the call if engine said so.
Revision History:
--*/
{
#define pPDev ((PPDEV)dhpdev)
PDRVHTINFO pDrvHTInfo;
SIZEL SurfSize;
pDrvHTInfo = (PDRVHTINFO)(pPDev->pvDrvHTData);
//
// Make sure we delete this xlate table before we process to the new
// surface
//
if (pDrvHTInfo->pHTXB) {
LocalFree((HLOCAL)pDrvHTInfo->pHTXB);
pDrvHTInfo->pHTXB = NULL;
}
pDrvHTInfo->Flags = 0;
pDrvHTInfo->PalXlate[0] = 0xff;
pDrvHTInfo->HTPalXor = HTPALXOR_SRCCOPY;
//
// Since output is expected to follow this call, allocate storage for the
// output buffer. This used to be statically allocated within PDEV but
// now we can save that space for INFO type DCs.
//
if (!AllocOutBuffer(pPDev)) {
PLOTERR(("DrvEnableSurface: AllocOutBuffer() failed"));
return(NULL);
}
//
// For now pass in my PDev pointer as the dhsurf value. If I actually
// need to pass back an hsurf to the engine later, I can use this value
// as a pointer to the hsurf value stored in my PDev.
//
SurfSize.cx = pPDev->HorzRes;
SurfSize.cy = pPDev->VertRes;
if (!(pPDev->hsurf = EngCreateDeviceSurface((DHSURF)pPDev, SurfSize,
IS_RASTER(pPDev) ? BMF_24BPP : BMF_4BPP))) {
PLOTERR(("DrvEnableSurface: EngCreateDeviceSurface() failed"));
return(NULL);
}
//
// Now need to associate this surface with the pdev passed in at
// DrvCompletePDev time. Nothing to it! BUT need to indicate which
// functions we want to hook.
//
if (!EngAssociateSurface(pPDev->hsurf,
(HDEV)pPDev->hpdev,
HOOK_BITBLT |
HOOK_STRETCHBLT |
HOOK_COPYBITS |
HOOK_STROKEPATH |
HOOK_FILLPATH |
HOOK_STROKEANDFILLPATH |
HOOK_PAINT |
HOOK_TEXTOUT)) {
PLOTERR(("DrvEnableSurface: EngAssociateSurface() failed"));
DrvDisableSurface((DHPDEV)pPDev->hpdev);
EngDeleteSurface(pPDev->hsurf);
return(NULL);
}
return(pPDev->hsurf);
#undef pPDev
}
VOID
DrvDisableSurface(
DHPDEV dhpdev
)
/*++
Routine Description:
The drawing surface is no longer required, so we can delete any
memory we allocated in conjunction with it.
Arguments:
dhpdev - our pPDev
Return Value:
VOID
Author:
01-Dec-1993 Wed 01:45:39 created -by- Daniel Chou (danielc)
Revision History:
--*/
{
#define pPDev ((PPDEV)dhpdev)
if (pPDev->hsurf) {
EngDeleteSurface(pPDev->hsurf);
}
#undef pPDev
}
DWORD
hypot(
DWORD x,
DWORD y
)
/*++
Routine Description:
Returns the length of the hypotenous of a xRight triangle whose sides
are passed in as the parameters.
Arguments:
x - x side of the triangle
y - y size of the triangle
Return Value:
hypotenous
Author:
13:54 on Tue 02 Feb 1993 -by- Lindsay Harris [lindsayh]
Re-instated from Win 3.1, for compatability.
01-Dec-1993 Wed 01:10:55 updated -by- Daniel Chou (danielc)
update to DWORD
Revision History:
--*/
{
DWORD hypo;
DWORD Delta;
DWORD Target;
//
// Finds the hypoteneous of a xRight triangle with legs equal to x and y.
// Assumes x, y, hypo are integers. Use sq(x) + sq(y) = sq(hypo);
// Start with MAX(x, y), use sq(x + 1) = sq(x) + 2x + 1 to incrementally
// get to the target hypotenouse.
//
hypo = max(x, y);
Target = min(x, y);
Target *= Target;
for (Delta = 0; Delta < Target; hypo++) {
Delta += (DWORD)((hypo << 1) + 1);
}
return(hypo);
}
VOID
FillDeviceCaps(
PPDEV pPDev,
GDIINFO *pGDIInfo
)
/*++
Routine Description:
Set up the device caps for this particular plotter. Some fields require
calculations based on device resolution, etc.
We simply fill the GDIINFO structure passed to us. The calling
function will take care of copying the information into the
Graphics Engine's buffer.
Arguments:
pPDev - Pointer to the PDEV data structure
pGDIInfo - Pointer to the GDIINFO data structure to be filled in
Return Value:
VOID
Author:
24-Nov-1993 Wed 22:38:10 updated -by- Daniel Chou (danielc)
Re-write, and using CurForm to replace the pform and PAPER_DIM
23-Dec-1993 Thu 21:56:20 updated -by- Daniel Chou (danielc)
Make halftone bitmap surface also look at dmColor which set by the
user if it want to print grey scale or device is not color
07-Feb-1994 Mon 20:37:13 updated -by- Daniel Chou (danielc)
When is DMCOLOR_COLOR the ulNumColors return to the engine will be
MaxPens which specified in the PCD file not 8
Revision History:
--*/
{
PDRVHTINFO pDrvHTInfo;
LONG Scale;
//
// we will always start from clean state
//
ZeroMemory(pGDIInfo, sizeof(GDIINFO));
//
// Get pDrvHTInfo data pointer and set the basic version information
//
pDrvHTInfo = (PDRVHTINFO)pPDev->pvDrvHTData;
pGDIInfo->ulVersion = DRIVER_VERSION;
pGDIInfo->ulTechnology = (IS_RASTER(pPDev) ? DT_RASPRINTER : DT_PLOTTER);
//
// We have pPDev->PlotForm updated during ValidateSetPLOTDM() call, so use
// it, we need to look into the dmScale see if we need to scale all of them
//
Scale = (LONG)pPDev->PlotDM.dm.dmScale;
pGDIInfo->ulHorzSize = pPDev->PlotForm.LogExt.cx / (Scale * 10);
pGDIInfo->ulVertSize = pPDev->PlotForm.LogExt.cy / (Scale * 10);
pPDev->HorzRes =
pGDIInfo->ulHorzRes = SPLTOENGUNITS(pPDev, pPDev->PlotForm.LogExt.cx);
pPDev->VertRes =
pGDIInfo->ulVertRes = SPLTOENGUNITS(pPDev, pPDev->PlotForm.LogExt.cy);
PLOTDBG(DBG_GDICAPS, ("GDICAPS: H/V Size=%d x %d, H/V Res=%ld x %ld",
pGDIInfo->ulHorzSize, pGDIInfo->ulVertSize,
pGDIInfo->ulHorzRes, pGDIInfo->ulVertRes));
pGDIInfo->szlPhysSize.cx = SPLTOENGUNITS(pPDev,pPDev->PlotForm.LogSize.cx);
pGDIInfo->szlPhysSize.cy = SPLTOENGUNITS(pPDev,pPDev->PlotForm.LogSize.cy);
pGDIInfo->ptlPhysOffset.x = SPLTOENGUNITS(pPDev,pPDev->PlotForm.PhyOrg.x);
pGDIInfo->ptlPhysOffset.y = SPLTOENGUNITS(pPDev,pPDev->PlotForm.PhyOrg.y);
PLOTDBG(DBG_GDICAPS, ("GDICAPS: PhySize= %d x %d, PhyOff=(%ld, %ld)",
pGDIInfo->szlPhysSize.cx, pGDIInfo->szlPhysSize.cy,
pGDIInfo->ptlPhysOffset.x, pGDIInfo->ptlPhysOffset.y));
//
// For this first version of the plotter driver we will only assume that
// device always have 1:1 aspect ratio
//
// TODO this may need to be updated to take account scaling, if we decide
// to support this in the dmScale field of the passed in DEVMODE
// TODO Set the aspect ratio, these fields are not in the DDI spec, so we
// will simply mimick the Postscript driver for now
//
pGDIInfo->ulLogPixelsX =
pGDIInfo->ulLogPixelsY = (pPDev->lCurResolution * Scale / 100);
PLOTDBG(DBG_GDICAPS, ("GDICAPS: LogPixelsX/Y = %d x %d",
pGDIInfo->ulLogPixelsX, pGDIInfo->ulLogPixelsY));
pGDIInfo->ulAspectX =
pGDIInfo->ulAspectY = pPDev->lCurResolution;
pGDIInfo->ulAspectXY = hypot(pGDIInfo->ulAspectX, pGDIInfo->ulAspectY);
//
// TODO: We may have to scale the ulHTPatternSize, since we fake by
// enlarge the device resolution
pGDIInfo->ciDevice = pPDev->pPlotGPC->ci;
pGDIInfo->ulDevicePelsDPI = (DWORD)pPDev->pPlotGPC->DevicePelsDPI *
(DWORD)Scale / (DWORD)100;
pGDIInfo->ulHTPatternSize = pPDev->pPlotGPC->HTPatternSize;
pGDIInfo->flHTFlags = HT_FLAG_HAS_BLACK_DYE;
pGDIInfo->ulPrimaryOrder = PRIMARY_ORDER_CBA;
PLOTDBG(DBG_GDICAPS, ("GDICAPS: HTPatSize=%ld, DevPelsDPI=%ld, PrimaryOrder=%ld",
pGDIInfo->ulHTPatternSize, pGDIInfo->ulDevicePelsDPI,
pGDIInfo->ulPrimaryOrder));
//
// Now start worry about the color, and must initialize pDrvHTInfo now
// before we do any other thing
//
if (pPDev->PlotDM.dm.dmColor == DMCOLOR_COLOR) {
//
// Do this only if we really want to do color in R/G/B not C/M/Y
//
PLOTDBG(DBG_DEVCAPS, ("FillDeviceCaps: Doing Color Output"));
pDrvHTInfo->HTPalCount = 8;
pDrvHTInfo->HTBmpFormat = (BYTE)BMF_4BPP;
pDrvHTInfo->AltBmpFormat = (BYTE)BMF_1BPP;
pGDIInfo->ulHTOutputFormat = HT_FORMAT_4BPP;
} else {
pDrvHTInfo->HTPalCount = 2;
pDrvHTInfo->HTBmpFormat = (BYTE)BMF_1BPP;
pDrvHTInfo->AltBmpFormat = (BYTE)0xff;
pGDIInfo->ulHTOutputFormat = HT_FORMAT_1BPP;
//
// Using this flag will give us a good benefit, the flag tell gdi and
// halftone that the output from halftone will be 0=white and 1=black
// rater than typicall 0=black, 1=white, so that at 99% of time we do
// not have to flip the B/W buffer except if CopyBits is from apps.
//
// pGDIInfo->flHTFlags |= HT_FLAG_OUTPUT_CMY;
//
PLOTDBG(DBG_DEVCAPS, ("FillDeviceCaps: Doing GREY SCALE (%hs) Output",
(pGDIInfo->flHTFlags & HT_FLAG_OUTPUT_CMY) ? "CMY: 0=W, 1=K" :
"RGB: 0=K, 1=W"));
}
pGDIInfo->ulNumColors = pPDev->pPlotGPC->MaxPens;
pDrvHTInfo->Flags = 0;
pDrvHTInfo->PalXlate[0] = 0xff;
pDrvHTInfo->HTPalXor = HTPALXOR_SRCCOPY;
//
// TODO: Check on this cBitsPixel stuff, we may need to think about it
//
pGDIInfo->cBitsPixel = 24;
pGDIInfo->cPlanes = 1;
//
// Some other stupid infomation we have to returned to the engine
//
pGDIInfo->ulDACRed = 0;
pGDIInfo->ulDACGreen = 0;
pGDIInfo->ulDACBlue = 0;
pGDIInfo->flRaster = 0;
pGDIInfo->flTextCaps = 0;
pGDIInfo->xStyleStep = 1;
pGDIInfo->yStyleStep = 1;
pGDIInfo->denStyleStep = PLOT_STYLE_STEP(pPDev);
}
BOOL
FillDevInfo(
PPDEV pPDev,
DEVINFO *pDevInfo
)
/*++
Routine Description:
Set up the device info for this particular plotter. Some fields
require calculations based on device resolution, etc.
We simply fill the DevInfo structure passed to us. The calling
function will take care of copying the information into the
Graphics Engine's buffer.
Arguments:
pPDev - pointer to the PDEV data structure
pDevInfo - pointer to the DEVINFO to be filled
Return Value:
TRUE if sucessful FALSE otherwise
Author:
01-Dec-1993 Wed 00:46:00 created -by- Daniel Chou (danielc)
10-Dec-1993 Fri 16:37:06 updated -by- Daniel Chou (danielc)
Temp. disable and move the PlotCreatePalette to EnableSurf call
17-Dec-1993 Fri 16:37:06 updated -by- James Bratsanos (v-jimbr)
Move PlotCreatePalette to StartDoc time
05-Jan-1994 Wed 22:54:21 updated -by- Daniel Chou (danielc)
Move PenColor Reference to this file and reference that directly as
DWORD generate by RGB() marco
14-Jan-1994 Fri 15:35:02 updated -by- Daniel Chou (danielc)
Remove HTPatternSize param
23-Feb-1994 Wed 13:02:09 updated -by- Daniel Chou (danielc)
Make sure we return GCAPS_HALFTONE so that we will get DrvStretchBlt()
callback
Revision History:
--*/
{
//
// Start with a clean slate.
//
ZeroMemory(pDevInfo, sizeof(DEVINFO));
//
// fill in the graphics capabilities flags--can't do a damn thing
//
pDevInfo->flGraphicsCaps = GCAPS_ALTERNATEFILL |
GCAPS_HORIZSTRIKE |
GCAPS_VERTSTRIKE |
GCAPS_VECTORFONT;
//
// If RGB mode is on for color handling then make text can be opaque
// TODO: we have to think about if user want grey scale
//
if (IS_RASTER(pPDev)) {
pDevInfo->flGraphicsCaps |= GCAPS_HALFTONE;
if (IS_COLOR(pPDev)) {
pDevInfo->flGraphicsCaps |= GCAPS_OPAQUERECT;
}
}
//
// Check and set the BEZIER capability of the device....
//
if (IS_BEZIER(pPDev)) {
pDevInfo->flGraphicsCaps |= GCAPS_BEZIERS;
}
if (IS_WINDINGFILL(pPDev)) {
pDevInfo->flGraphicsCaps |= GCAPS_WINDINGFILL;
}
//
// TODO we really should review the rest of the flags in devinfo, as
// others might be useable.
//
//
// We don't process DrvDitherColor (perhaps later?), so set the size of
// the Dither Brush to 0 to indicate this to the engine. THIS IS IN THE
// SPEC FOR DrvDitherBrush () function.
//
pDevInfo->cxDither = 0;
pDevInfo->cyDither = 0;
//
// the following line is set by patrickh. According to patrickh, we need
// to have 16 colors. We cannot only have 9 colors. May be the engine
// won't like that. For 16 colors, we need to set ditherformat as follows
//
// [t-kenl] Mar 31, 93
//
// 01-Dec-1993 Wed 01:31:16 updated -by- Daniel Chou (danielc)
// The reason that engine need 16 colors is it optimized by using bit 3
// as duplicate bit (used only bit 0/1/2) and bit 3 always mask off, so
// that engine can do faster comparsion
//
// TODO: For pen plotter we only need to dither to 4bpp???
// TODO: this needs to be set via mono color model based on REAL target
// surface, still needs fixing for mono.......
//
if (IS_RASTER(pPDev)) {
pDevInfo->iDitherFormat = BMF_24BPP;
} else {
pDevInfo->iDitherFormat = BMF_4BPP;
}
if (pPDev->hPalDefault) {
EngDeletePalette(pPDev->hPalDefault);
pPDev->hPalDefault = NULL;
}
//
// Ceate the Pen palette based only total pens which device allowed
//
if (IS_RASTER(pPDev)) {
//
// This is raster device, we will always make it 24-bit device to
// the engine so that we can dither/halftone user passed in color
//
// TODO: we may need to destroy this palette???
//
if (!(pDevInfo->hpalDefault =
EngCreatePalette(PAL_BGR, 0, 0, 0, 0, 0))) {
//
// The create failed so raise an error
//
PLOTERR(("FillDevInfo: EngCreatePalette(PAL_BGR) failed."));
return(FALSE);
}
} else {
DWORD DevColor[MAX_PENPLOTTER_PENS + 2];
PDWORD pdwCur;
PPENDATA pPenData;
PALENTRY PalEntry;
UINT cPens;
extern PALENTRY PlotPenPal[];
PLOTASSERT(1, "Too many pens defined for pen plotter (%ld)",
(pPDev->pPlotGPC->Pens.Count <= MAX_PENPLOTTER_PENS),
pPDev->pPlotGPC->Pens.Count);
//
// Get the start of where to fill colors
//
pdwCur = &DevColor[0];
//
// 1st Entry is always WHITE
//
*pdwCur++ = RGB(255, 255, 255);
//
// Now go into a loop loading up the rest of the colors
//
PLOTDBG(DBG_PENPAL, ("Pen Palette #%02ld = 255:255:255", 0));
for (cPens = 1, pPenData = (PPENDATA)pPDev->pPlotGPC->Pens.pData;
cPens <= (UINT)pPDev->pPlotGPC->Pens.Count;
pPenData++) {
//
// Place the RGB value into the palette
//
PalEntry = PlotPenPal[pPenData->ColorIdx];
*pdwCur++ = RGB(PalEntry.R, PalEntry.G, PalEntry.B);
PLOTDBG(DBG_PENPAL, ("Pen Palette #%02ld = %03ld:%03ld:%03ld",
cPens,
(LONG)PalEntry.R, (LONG)PalEntry.G, (LONG)PalEntry.B));
//
// Track total pens been set at here
//
++cPens;
}
//
// Last Pen is BRIGHT YELLOW WHITE so that a non-white will mappped to
// this pen. If GDI mapped to this pen then we will pick the closet
// non-white pen
//
*pdwCur++ = RGB(255, 255, 254);
cPens++;
PLOTDBG(DBG_PENPAL, ("Pen Palette #%02ld = 255:255:254", cPens - 1));
//
// Now create the engine palette
//
if (!(pDevInfo->hpalDefault = EngCreatePalette(PAL_INDEXED,
cPens,
DevColor,
0,
0,
0))) {
//
// The create failed so raise an error
//
PLOTERR(("FillDevInfo: EngCreatePalette(PAL_INDEXED=%ld) failed.",
cPens));
return(FALSE);
}
}
//
// Save the created palette for later to destroy
//
pPDev->hPalDefault = pDevInfo->hpalDefault;
return(TRUE);
}
BOOL
CommonStartPDEV(
PDEV *pPDev,
DEVMODEW *pPlotDMIn,
ULONG cPatterns,
HSURF *phsurfPatterns,
ULONG cjDevCaps,
ULONG *pDevCaps,
ULONG cjDevInfo,
DEVINFO *pDevInfo
)
/*++
Routine Description:
Function to perform the PDEV initialisation. This is common to
DrvEnablePDEV and DrvRestartPDEV. These individual functions
do whatever is required before calling in here.
Arguments:
pPDev - the pPDev which we returned in DrvEnablePDEV
pPlotDMIn - Pointer to the DEVMODE data structure
cPatterns - Count of pattern to be set in phsurfPatterns
phsurfPatterns - pointer to the standard pattern HSURF array
cjDevCaps - total size of pDevCaps pointed to.
pDevCaps - pointer to the device cap DWORDs
cjDevInfo - total size of pDevInfo pointed to
pDevInfo - pointer to the DEVINFO data structure
Return Value:
BOOLEAN
Author:
23-Nov-1993 Tue 20:13:10 created -by- Daniel Chou (danielc)
Re-write
05-Jan-1994 Wed 23:34:18 updated -by- Daniel Chou (danielc)
Make PlotXDPI for the Pen Plotter rather than PLOTTER_UNITS_DPI
06-Jan-1994 Thu 13:10:11 updated -by- Daniel Chou (danielc)
Change RasterDPI always be the resoluton reports back to the engine
Revision History:
--*/
{
GDIINFO GdiInfo;
DEVINFO DevInfo;
DWORD dmErrBits;
//
// Validate the DEVMODE structure passed in by the user, If OK, set the
// appropriate fields in the PDEV, the validateSetPlotDM() will always
// return a valid PLOTDEVMODE so we just grap it and used it
//
if (dmErrBits = ValidateSetPLOTDM(pPDev->hPrinter,
pPDev->pPlotGPC,
pPDev->PlotDM.dm.dmDeviceName,
(PPLOTDEVMODE)pPlotDMIn,
&(pPDev->PlotDM),
&(pPDev->CurForm))) {
PLOTWARN(("CommonStartPDEV: ValidateSetPLOTDM() ErrBits=%08lx",
dmErrBits));
}
//
// fill in our PDEV structure...
//
// The RasterDPI will be used for raster printer resolution, for pen
// plotter this is the GPC's ideal resolution
//
pPDev->lCurResolution = (LONG)pPDev->pPlotGPC->RasterXDPI;
PLOTDBG(DBG_GDICAPS, ("CURRENT Resolution = %ld", pPDev->lCurResolution));
SetPlotForm(&(pPDev->PlotForm),
pPDev->pPlotGPC,
&(pPDev->CurPaper),
&(pPDev->CurForm),
&(pPDev->PlotDM),
&(pPDev->PPData));
//
// fill in the device capabilities in GDIINFO data structure for engine
//
if ((cjDevCaps) && (pDevCaps)) {
FillDeviceCaps(pPDev, &GdiInfo);
CopyMemory(pDevCaps, &GdiInfo, min(cjDevCaps, sizeof(GDIINFO)));
}
//
// Fill in DevInfo data structrue
//
if ((cjDevInfo) && (pDevInfo)) {
if (!FillDevInfo(pPDev, &DevInfo)) {
return(FALSE);
}
CopyMemory(pDevInfo, &DevInfo, min(cjDevInfo, sizeof(DEVINFO)));
}
//
// Set it to NULL so that the engine can create halftone one for us
//
if ((cPatterns) && (phsurfPatterns)) {
ZeroMemory(phsurfPatterns, sizeof(HSURF) * cPatterns);
}
return(TRUE);
}