|
|
Microsoft Windows NT Build 511 (DDK SDK) 11-01-1993
//--------------------------------------------------------------------------
//
// Module Name: DEVCAPS.C
//
// Brief Description: This module contains the PSCRIPT driver's Device
// capabilities function and related routines.
//
// Author: Kent Settle (kentse)
// Created: 16-Apr-1993
//
// Copyright (c) 1992 Microsoft Corporation
//--------------------------------------------------------------------------
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include "pscript.h"
#include "enable.h"
#include <winspool.h>
#include "dlgdefs.h"
#include "pscrptui.h"
extern BOOL SetDefaultPSDEVMODE(PSDEVMODE *, PWSTR, PNTPD, HANDLE);
extern BOOL ValidateSetDEVMODE(PSDEVMODE *, PSDEVMODE *, HANDLE, PNTPD);
extern PFORM_INFO_1 GetFormsDataBase(HANDLE, DWORD *, PNTPD);
extern TABLE_ENTRY PaperSourceTable[];
#define CCHBINNAME 24 // characters allowed for bin name.
#define CCHPAPERNAME 64 // max length of form names.
#define INITIAL_MIN_EXTENT 0x7FFFFFFF
#define INITIAL_MAX_EXTENT 0
// form metrics in the forms database are in .001mm whereas we are to
// return them in .1mm units.
#define FORMS01MM(a) ((a) / 100)
// declarations of routines residing in this module.
DWORD GetBinNumber(PSTR);
//--------------------------------------------------------------------------
// DWORD DrvDeviceCapabilities(hPrinter, pDeviceName, iDevCap, pvOutput, pDMIn)
// HANDLE hPrinter; /* Access to registry via spooler */
// PWSTR pDeviceName; /* Particular printer model name */
// WORD iDevCap; /* Capability required */
// void *pvOutput; /* Output area (for some) */
// DEVMODE *pdevmodeS; /* DEVMODE defining mode of operation etc */
//
// This routine returns the specified device's capabilities.
//
// This routine returns GDI_ERROR for failure, else depends on information requested.
//
// History:
// 16-Apr-1993 -by- Kent Settle (kentse)
// Wrote it, borrowed from RASDD.
//--------------------------------------------------------------------------
DWORD DrvDeviceCapabilities(hPrinter, pDeviceName, iDevCap, pvOutput, pdevmodeS)
HANDLE hPrinter; // handle the to specific printer.
PWSTR pDeviceName; // what it says.
WORD iDevCap; // specific capability.
void *pvOutput; // output buffer.
DEVMODE *pdevmodeS; // source devmode.
{
PNTPD pntpd; // pointer to printer descriptor structure.
PSDEVMODE devmodeT; // target devmode.
DWORD dwRet; // the return value.
PSRESOLUTION *pRes; // pointer to our resolutions structures.
LONG *plOutput; // pointer to LONGs.
SHORT *psOutput; // pointer to SHORTs.
POINT *pptOutput; // pointer to POINTs.
WCHAR *pwchOutput; // pointer to WCHARs.
DWORD i; // counter.
DWORD count; // yac.
LONG lValue; // just a place holder.
PSINPUTSLOT *pslot; // pointer to PSINPUTSLOT structures.
PFORM_INFO_1 pdbForms; // pointer to PFORM_INFO_1 array.
PFORM_INFO_1 pdbForm; // pointer to PFORM_INFO_1 structure.
LONG lMaxX, lMinX; // places to calculate max/min extents.
LONG lMaxY, lMinY; // places to calculate max/min extents.
// get a pointer to our printer descriptor structure.
if (!(pntpd = MapPrinter(hPrinter)))
{
RIP("PSCRPTUI!DrvDeviceCapabilities: MapPrinter failed.\n");
return(GDI_ERROR);
}
// fill in a default PSDEVMODE structure.
if (!(SetDefaultPSDEVMODE(&devmodeT, pDeviceName, pntpd, hPrinter)))
{
RIP("PSCRPTUI!DrvDeviceCapabilities: SetDefaultPSDEVMODE failed.\n");
return(GDI_ERROR);
}
// modify the default devmode if there is a user supplied one.
if (pdevmodeS)
{
if (!(ValidateSetDEVMODE(&devmodeT, (PSDEVMODE *)pdevmodeS, hPrinter, pntpd)))
{
RIP("PSCRPTUI!DrvDeviceCapabilities: ValidateSetDEVMODE failed.\n");
return(GDI_ERROR);
}
}
// set up some handy pointers.
psOutput = (SHORT *)pvOutput;
pptOutput = (POINT *)pvOutput;
pwchOutput = (WCHAR *)pvOutput;
// we now have a valid devmodeT from which to work. so it is time to
// fill in the blanks.
dwRet = 0;
switch (iDevCap)
{
case DC_FIELDS:
dwRet = (DWORD)devmodeT.dm.dmFields;
break;
case DC_PAPERS:
case DC_PAPERSIZE:
case DC_PAPERNAMES:
case DC_MINEXTENT:
case DC_MAXEXTENT:
// enumerate the forms database.
if (!(pdbForms = GetFormsDataBase(hPrinter, &count, pntpd)))
{
RIP("PSCRPTUI!DrvDeviceCapabilities: GetFormsDataBase failed.\n");
return(GDI_ERROR);
}
// for each form that is valid for the current printer, return the
// specified values to the caller.
pdbForm = pdbForms;
lMinX = INITIAL_MIN_EXTENT;
lMaxX = INITIAL_MAX_EXTENT;
lMinY = INITIAL_MIN_EXTENT;
lMaxY = INITIAL_MAX_EXTENT;
for (i = 0; i < count; i++)
{
if (pdbForm->Flags & PSCRIPT_VALID_FORM)
{
// we have a form that is valid for this printer, so
// return the requested information.
dwRet++;
if (pvOutput)
{
switch (iDevCap)
{
case DC_PAPERS:
// return the index of the form.
*psOutput++ = (SHORT)i + 1; // one based indicies.
break;
case DC_PAPERSIZE:
// return the size of the form in .1mm units.
pptOutput->x = FORMS01MM(pdbForm->Size.cx);
pptOutput->y = FORMS01MM(pdbForm->Size.cy);
pptOutput++;
break;
case DC_PAPERNAMES:
// return the formname.
wcsncpy(pwchOutput, pdbForm->pName, CCHPAPERNAME);
pwchOutput += CCHPAPERNAME;
break;
case DC_MINEXTENT:
if (lMinX > pdbForm->Size.cx)
lMinX = pdbForm->Size.cx;
if (lMinY > pdbForm->Size.cy)
lMinY = pdbForm->Size.cy;
break;
case DC_MAXEXTENT:
if (lMaxX < pdbForm->Size.cx)
lMaxX = pdbForm->Size.cx;
if (lMaxY < pdbForm->Size.cy)
lMaxY = pdbForm->Size.cy;
break;
}
if (iDevCap == DC_MINEXTENT)
{
pptOutput->x = lMinX;
pptOutput->y = lMinY;
}
if (iDevCap == DC_MAXEXTENT)
{
pptOutput->x = lMaxX;
pptOutput->y = lMaxY;
}
}
}
// point to the next form.
pdbForm++;
}
break;
case DC_BINS:
// get the count of input bins.
count = pntpd->cInputSlots;
if (pvOutput)
{
// if there is only one inputslot, the count may be zero.
// if so, use the default inputslot.
if (count == 0)
*psOutput = (SHORT)GetBinNumber((CHAR *)pntpd +
pntpd->loDefaultSlot);
else
{
pslot = (PSINPUTSLOT *)((CHAR *)pntpd + pntpd->loPSInputSlots);
for (i = 0; i < count; i++)
{
// fill in the bin id number.
//!!! need to handle > 1 user bins. -kentse.
*psOutput++ = (SHORT)GetBinNumber((CHAR *)pntpd +
pslot->loSlotName);
pslot++;
}
}
}
if (count == 0)
count = 1;
dwRet = count;
break;
case DC_BINNAMES:
// get the count of input bins.
count = pntpd->cInputSlots;
if (pvOutput)
{
// if there is only one inputslot, the count may be zero.
// if so, use the default inputslot.
if (count == 0)
strcpy2WChar(pwchOutput, (CHAR *)pntpd + pntpd->loDefaultSlot);
else
{
pslot = (PSINPUTSLOT *)((CHAR *)pntpd + pntpd->loPSInputSlots);
for (i = 0; i < count; i++)
{
// fill in the bin name.
strcpy2WChar(pwchOutput, (CHAR *)pntpd + pslot->loSlotName);
pwchOutput += CCHBINNAME;
pslot++;
}
}
}
if (count == 0)
count = 1;
dwRet = count;
break;
case DC_DUPLEX:
if ((pntpd->loszDuplexNone) || (pntpd->loszDuplexNoTumble) ||
(pntpd->loszDuplexTumble))
dwRet = 1;
else
dwRet = 0;
break;
case DC_SIZE:
dwRet = (DWORD)devmodeT.dm.dmSize;
break;
case DC_EXTRA:
dwRet = (DWORD)devmodeT.dm.dmDriverExtra;
break;
case DC_VERSION:
dwRet = (DWORD)devmodeT.dm.dmSpecVersion;
break;
case DC_DRIVER:
dwRet = (DWORD)devmodeT.dm.dmDriverVersion;
break;
case DC_ENUMRESOLUTIONS:
// if there is an output buffer, fill it with supported resolutions.
count = pntpd->cResolutions;
if (pvOutput)
{
plOutput = pvOutput;
// if there is only one resolution, the count will be zero.
// fill in the default resolution.
if (count == 0)
{
lValue = (LONG)pntpd->iDefResolution;
*plOutput++ = lValue;
//!!! need to deal with anamorphic resolutions. - kentse.
*plOutput = lValue;
}
else
{
pRes = (PSRESOLUTION *)((CHAR *)pntpd + pntpd->loResolution);
for (i = 0; i < pntpd->cResolutions; i++)
{
lValue = (LONG)pRes->iValue;
*plOutput++ = lValue;
//!!! need to deal with anamorphic resolutions. - kentse.
*plOutput++ = lValue;
pRes++;
}
}
}
// if there is only one resolution, the count will be zero.
// fill in the default resolution.
if (count == 0)
count = 1;
dwRet = count;
break;
case DC_FILEDEPENDENCIES:
// we are supposed to fill in an array of 64 character filenames,
// but, if we are to be of any use, we would need to use the
// fully qualified pathnames, and 64 characters is probably not
// enough.
dwRet = 0;
if (pwchOutput)
*pwchOutput = (WCHAR)0;
break;
case DC_TRUETYPE:
if (!(devmodeT.dm.dmFields & DM_TTOPTION))
{
// truetype option not available, so blow it off.
dwRet = 0;
break;
}
#if defined(DCTT_DOWNLOAD) || defined(DCTT_BITMAP)
// we can do both.
dwRet = DCTT_DOWNLOAD | DCTT_SUBDEV;
#else
// don't know what to return??? -kentse.
dwRet = 0;
#endif
break;
case DC_ORIENTATION:
dwRet = 90; // currently we only support 90 degree landscape.
break;
case DC_COPIES:
dwRet = MAX_COPIES;
break;
default:
dwRet = GDI_ERROR;
}
return (dwRet);
}
//--------------------------------------------------------------------------
// DWORD GetBinNumber(pstrBin)
// PSTR pstrBin;
//
// This routine returns the windows bin id for the given bin name.
//
// History:
// 16-Apr-1993 -by- Kent Settle (kentse)
// Wrote it.
//--------------------------------------------------------------------------
DWORD GetBinNumber(pstrBin)
PSTR pstrBin;
{
TABLE_ENTRY *ptable;
ptable = PaperSourceTable;
while (ptable->szStr)
{
if (!(strcmp(pstrBin, ptable->szStr)))
return(ptable->iValue);
ptable++;
}
// the bin was not one of the predefined ones.
return(DMBIN_USER);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.