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.
814 lines
19 KiB
814 lines
19 KiB
/*++
|
|
|
|
Copyright (c) 1990-2003 Microsoft Corporation
|
|
|
|
|
|
Module Name:
|
|
|
|
devcaps.c
|
|
|
|
|
|
Abstract:
|
|
|
|
This module contains API function DrvDeviceCapabilities and other support
|
|
functions
|
|
|
|
|
|
Author:
|
|
|
|
02-Dec-1993 Thu 16:49:08 created
|
|
|
|
22-Mar-1994 Tue 13:00:04 updated
|
|
Update RESOLUTION caps so it return as not supported, this way the
|
|
application will not used to setup the DMRES_xxx fields
|
|
|
|
|
|
[Environment:]
|
|
|
|
GDI Device Driver - Plotter.
|
|
|
|
|
|
[Notes:]
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
#include "precomp.h"
|
|
#pragma hdrstop
|
|
|
|
#define DBG_PLOTFILENAME DbgDevCaps
|
|
|
|
extern HMODULE hPlotUIModule;
|
|
|
|
|
|
|
|
|
|
#define DBG_DEVCAPS_0 0x00000001
|
|
#define DBG_DEVCAPS_1 0x00000002
|
|
|
|
DEFINE_DBGVAR(0);
|
|
|
|
|
|
//
|
|
// Local defines only used in this module
|
|
//
|
|
// The following sizes are copied from the Win 3.1 driver. They do not appear
|
|
// to be defined in any public place, although it looks like they should be.
|
|
//
|
|
|
|
#define CCHBINNAME 24 // Characters allowed for bin names
|
|
#define CCHPAPERNAME 64 // Max length of paper size names
|
|
#define DC_SPL_PAPERNAMES 0xFFFF
|
|
#define DC_SPL_MEDIAREADY 0xFFFE
|
|
|
|
|
|
#ifdef DBG
|
|
|
|
LPSTR pDCCaps[] = {
|
|
|
|
"FIELDS",
|
|
"PAPERS",
|
|
"PAPERSIZE",
|
|
"MINEXTENT",
|
|
"MAXEXTENT",
|
|
"BINS",
|
|
"DUPLEX",
|
|
"SIZE",
|
|
"EXTRA",
|
|
"VERSION",
|
|
"DRIVER",
|
|
"BINNAMES",
|
|
"ENUMRESOLUTIONS",
|
|
"FILEDEPENDENCIES",
|
|
"TRUETYPE",
|
|
"PAPERNAMES",
|
|
"ORIENTATION",
|
|
"COPIES",
|
|
|
|
//
|
|
// 4.00
|
|
//
|
|
|
|
"BINADJUST",
|
|
"EMF_COMPLIANT",
|
|
"DATATYPE_PRODUCED",
|
|
"COLLATE",
|
|
"MANUFACTURER",
|
|
"MODEL",
|
|
|
|
//
|
|
// 5.00
|
|
//
|
|
|
|
"PERSONALITY",
|
|
"PRINTRATE",
|
|
"PRINTRATEUNIT",
|
|
"PRINTERMEM",
|
|
"MEDIAREADY",
|
|
"STAPLE",
|
|
"PRINTRATEPPM",
|
|
"COLORDEVICE",
|
|
"NUP",
|
|
"NULL"
|
|
};
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
INT
|
|
CALLBACK
|
|
DevCapEnumFormProc(
|
|
PFORM_INFO_1 pFI1,
|
|
DWORD Index,
|
|
PENUMFORMPARAM pEFP
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This is callback function from PlotEnumForm()
|
|
|
|
Arguments:
|
|
|
|
pFI1 - pointer to the current FORM_INFO_1 data structure passed
|
|
|
|
Index - pFI1 index related to the pFI1Base (0 based)
|
|
|
|
pEFP - Pointer to the EnumFormParam
|
|
|
|
|
|
Return Value:
|
|
|
|
> 0: Continue enumerate the next
|
|
= 0: Stop enumerate, but keep the pFI1Base when return from PlotEnumForms
|
|
< 0: Stop enumerate, and free pFI1Base memory
|
|
|
|
the form enumerate will only the one has FI1F_VALID_SIZE bit set in the
|
|
flag field, it also call one more time with pFI1 NULL to give the callback
|
|
function a chance to free the memory (by return < 0)
|
|
|
|
Author:
|
|
|
|
03-Dec-1993 Fri 23:00:25 created
|
|
|
|
27-Jan-1994 Thu 16:06:00 updated
|
|
Fixed the pptOutput which we did not increment the pointer
|
|
|
|
12-Jul-1994 Tue 12:47:22 updated
|
|
Move paper tray checking into the PlotEnumForms() itselft
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
#define pwOutput ((WORD *)pEFP->pCurForm)
|
|
#define pptOutput ((POINT *)pEFP->pCurForm)
|
|
#define pwchOutput ((WCHAR *)pEFP->pCurForm)
|
|
#define DeviceCap (pEFP->ReqIndex)
|
|
|
|
|
|
if (!pwOutput) {
|
|
|
|
PLOTASSERT(0, "DevCapEnumFormProc(DevCaps=%ld) pvOutput=NULL",
|
|
pwOutput, DeviceCap);
|
|
return(0);
|
|
}
|
|
|
|
if (!pFI1) {
|
|
|
|
//
|
|
// extra call, or no pvOutput, return a -1 to free memory for pFI1Base
|
|
// We want to add the custom paper size so that application know we
|
|
// supports that
|
|
//
|
|
|
|
switch (DeviceCap) {
|
|
|
|
case DC_PAPERNAMES:
|
|
|
|
LoadString(hPlotUIModule,
|
|
IDS_USERFORM,
|
|
pwchOutput,
|
|
CCHPAPERNAME);
|
|
|
|
PLOTDBG(DBG_DEVCAPS_1, ("!!! Extra FormName = %s", pwchOutput));
|
|
|
|
break;
|
|
|
|
case DC_PAPERS:
|
|
|
|
*pwOutput = (WORD)DMPAPER_USER;
|
|
|
|
PLOTDBG(DBG_DEVCAPS_1, ("!!! Extra FormID = %ld", *pwOutput));
|
|
|
|
break;
|
|
|
|
case DC_PAPERSIZE:
|
|
|
|
//
|
|
// I'm not sure we should return POINT or POINTS structure here, what
|
|
// is Window 3.1 do, because at here we return as dmPaperWidth and
|
|
// dmPaperLength, these fields only as a SHORT (16 bits), we will do
|
|
// win32 documentation said, POINT (32-bit version)
|
|
//
|
|
//
|
|
// Return custom paper sizes as 8.5" x 11"
|
|
//
|
|
|
|
pptOutput->x = (LONG)2159;
|
|
pptOutput->y = (LONG)2794;
|
|
|
|
PLOTDBG(DBG_DEVCAPS_1, ("!!! Extra FormSize = %ld x %ld",
|
|
pptOutput->x, pptOutput->y));
|
|
|
|
break;
|
|
}
|
|
|
|
return(-1);
|
|
}
|
|
|
|
switch (DeviceCap) {
|
|
|
|
case DC_PAPERNAMES:
|
|
case DC_MEDIAREADY:
|
|
|
|
_WCPYSTR(pwchOutput, pFI1->pName, CCHPAPERNAME);
|
|
pwchOutput += CCHPAPERNAME;
|
|
break;
|
|
|
|
case DC_PAPERS:
|
|
|
|
*pwOutput++ = (WORD)(Index + DMPAPER_FIRST);
|
|
break;
|
|
|
|
case DC_PAPERSIZE:
|
|
|
|
//
|
|
// I'm not sure we should return POINT or POINTS structure here, what
|
|
// is Window 3.1 do, because at here we return as dmPaperWidth and
|
|
// dmPaperLength, these fields only as a SHORT (16 bits), we will do
|
|
// win32 documentation said, POINT (32-bit version)
|
|
//
|
|
|
|
pptOutput->x = (LONG)SPLTODM(pFI1->Size.cx);
|
|
pptOutput->y = (LONG)SPLTODM(pFI1->Size.cy);
|
|
pptOutput++;
|
|
break;
|
|
}
|
|
|
|
return(1);
|
|
|
|
#undef DeviceCap
|
|
#undef pwOutput
|
|
#undef pptOutput
|
|
#undef pwchOutput
|
|
}
|
|
|
|
|
|
|
|
DWORD
|
|
WINAPI
|
|
DrvDeviceCapabilities(
|
|
HANDLE hPrinter,
|
|
LPWSTR pwDeviceName,
|
|
WORD DeviceCap,
|
|
VOID *pvOutput,
|
|
DEVMODE *pDM
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
|
|
|
|
Arguments:
|
|
|
|
hPrinter - handle the to specific printer.
|
|
|
|
pwDeviceName - pointer to the device name
|
|
|
|
DeviceCap - specific capability to get.
|
|
|
|
pvOutput - Pointer to the output buffer
|
|
|
|
pDM - Ponter to the input DEVMODE
|
|
|
|
|
|
Return Value:
|
|
|
|
DWORD depends on the DeviceCap
|
|
|
|
|
|
Author:
|
|
|
|
02-Dec-1993 Thu 16:50:36 created
|
|
|
|
05-Jan-1994 Wed 23:35:19 updated
|
|
Replace PLOTTER_UNIT_DPI with pPlotGPC->PlotXDPI, pPlotGPC->PlotYDPI,
|
|
|
|
06-Jan-1994 Thu 13:10:11 updated
|
|
Change RasterDPI always be the resoluton reports back to the apps
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
#define pbOutput ((BYTE *)pvOutput)
|
|
#define psOutput ((SHORT *)pvOutput)
|
|
#define pwOutput ((WORD *)pvOutput)
|
|
#define pptOutput ((POINT *)pvOutput)
|
|
#define pwchOutput ((WCHAR *)pvOutput)
|
|
#define pdwOutput ((DWORD *)pvOutput)
|
|
#define plOutput ((LONG *)pvOutput)
|
|
#define pptsdwRet ((POINTS *)&dwRet)
|
|
|
|
|
|
PPRINTERINFO pPI;
|
|
ENUMFORMPARAM EnumFormParam;
|
|
DWORD dwRet;
|
|
|
|
ZeroMemory(&EnumFormParam, sizeof(ENUMFORMPARAM));
|
|
|
|
//
|
|
// The MapPrinter will allocate memory, set default devmode, reading and
|
|
// validating the GPC then update from current pritner registry, it also
|
|
// will cached the PlotGPC.
|
|
//
|
|
|
|
if (!(pPI = MapPrinter(hPrinter,
|
|
(PPLOTDEVMODE)pDM,
|
|
NULL,
|
|
(DeviceCap == DC_MEDIAREADY) ?
|
|
MPF_DEVICEDATA : 0))) {
|
|
|
|
PLOTERR(("DrvDeviceCapabilities: MapPrinter() failed"));
|
|
return(GDI_ERROR);
|
|
}
|
|
|
|
//
|
|
// Start checking DeviceCap now, set dwRet to 0 first for anything we do
|
|
// not support. We can do return() at any point in this function because
|
|
// we use cached PI, and it will get destroy when the this module
|
|
// get unloaded.
|
|
//
|
|
|
|
EnumFormParam.cMaxOut = 0x7FFFFFFF;
|
|
dwRet = 0;
|
|
|
|
switch (DeviceCap) {
|
|
|
|
case DC_BINNAMES:
|
|
case DC_BINS:
|
|
|
|
//
|
|
// For current plotter, it always only have ONE bin
|
|
//
|
|
|
|
if (pvOutput) {
|
|
|
|
if (DeviceCap == DC_BINS) {
|
|
|
|
*pwOutput = DMBIN_ONLYONE;
|
|
|
|
} else {
|
|
|
|
if (pPI->pPlotGPC->Flags & PLOTF_ROLLFEED) {
|
|
|
|
dwRet = IDS_ROLLFEED;
|
|
|
|
} else {
|
|
|
|
dwRet = IDS_MAINFEED;
|
|
}
|
|
|
|
LoadString(hPlotUIModule, dwRet, pwchOutput, CCHBINNAME);
|
|
}
|
|
}
|
|
|
|
dwRet = 1;
|
|
|
|
break;
|
|
|
|
case DC_COPIES:
|
|
|
|
dwRet = (DWORD)pPI->pPlotGPC->MaxCopies;
|
|
|
|
break;
|
|
|
|
case DC_DRIVER:
|
|
|
|
dwRet = (DWORD)pPI->PlotDM.dm.dmDriverVersion;
|
|
|
|
break;
|
|
|
|
case DC_COLLATE:
|
|
case DC_DUPLEX:
|
|
|
|
//
|
|
// plotter now have no duplex support or collation support
|
|
//
|
|
|
|
break;
|
|
|
|
case DC_ENUMRESOLUTIONS:
|
|
|
|
//
|
|
// We only have one resolution setting which will be RasterXDPI and
|
|
// RasterYDPI in the GPC data for the raster able plotter, for pen
|
|
// plotter now we returned pPlotGPC->PlotXDPI, pPlotGPC->PlotYDPI
|
|
//
|
|
// The RasterDPI will be used for raster printer resolution, for pen
|
|
// plotter this is the GPC's ideal resolution
|
|
//
|
|
//
|
|
// We will return not supported (dwRet=0) so that application will not
|
|
// use this to set the DEVMODE's print quality and use the DMRES_XXXX
|
|
// as print qualities which is use by us to send to the plotter
|
|
//
|
|
|
|
//
|
|
// 26-Mar-1999 Fri 09:43:38 updated
|
|
// We will return one pair of current PlotXDPI, PlotYDPI for DS
|
|
//
|
|
|
|
if (pdwOutput) {
|
|
|
|
if (pPI->pPlotGPC->Flags & PLOTF_RASTER) {
|
|
|
|
pdwOutput[0] = (DWORD)pPI->pPlotGPC->RasterXDPI;
|
|
pdwOutput[1] = (DWORD)pPI->pPlotGPC->RasterYDPI;
|
|
|
|
} else {
|
|
|
|
pdwOutput[0] = (DWORD)pPI->pPlotGPC->PlotXDPI;
|
|
pdwOutput[1] = (DWORD)pPI->pPlotGPC->PlotYDPI;
|
|
}
|
|
}
|
|
|
|
dwRet = 1;
|
|
break;
|
|
|
|
case DC_EXTRA:
|
|
|
|
dwRet = (DWORD)pPI->PlotDM.dm.dmDriverExtra;
|
|
break;
|
|
|
|
case DC_FIELDS:
|
|
|
|
dwRet = (DWORD)pPI->PlotDM.dm.dmFields;
|
|
break;
|
|
|
|
case DC_FILEDEPENDENCIES:
|
|
|
|
//
|
|
// we are supposed to fill in an array of 64 character filenames,
|
|
// this will include the DataFileName, HelpFileName and UIFileName
|
|
// 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
|
|
|
|
if (pwchOutput) {
|
|
|
|
*pwchOutput = (WCHAR)0;
|
|
}
|
|
|
|
break;
|
|
|
|
case DC_MAXEXTENT:
|
|
|
|
//
|
|
// This is real problem, the document said that we return a POINT
|
|
// structure but a POINT structure here contains 2 LONGs, so for
|
|
// Windows 3.1 compatibility reason we return a POINTS structure, if device have
|
|
// variable length paper support then return 0x7fff as Window 3.1
|
|
// because a maximum positive number in POINTS is 0x7fff, this number
|
|
// will actually only allowed us to support the paper length up to
|
|
// 10.75 feet.
|
|
//
|
|
|
|
pptsdwRet->x = SPLTODM(pPI->pPlotGPC->DeviceSize.cx);
|
|
|
|
if (pPI->pPlotGPC->DeviceSize.cy >= 3276700) {
|
|
|
|
pptsdwRet->y = 0x7fff; // 10.75" maximum.
|
|
|
|
} else {
|
|
|
|
pptsdwRet->y = SPLTODM(pPI->pPlotGPC->DeviceSize.cy);
|
|
}
|
|
|
|
break;
|
|
|
|
case DC_MINEXTENT:
|
|
|
|
//
|
|
// This is real problem, the document said that we return a POINT
|
|
// structure but a POINT structure here contains 2 LONGs, so for Win3.1
|
|
// compatibility reason we return a POINTS structure
|
|
//
|
|
|
|
pptsdwRet->x = MIN_DM_FORM_CX;
|
|
pptsdwRet->y = MIN_DM_FORM_CY;
|
|
|
|
break;
|
|
|
|
case DC_ORIENTATION:
|
|
|
|
//
|
|
// We always rotate the page to the left 90 degree from the user's
|
|
// perspective
|
|
//
|
|
|
|
dwRet = 90;
|
|
|
|
break;
|
|
|
|
|
|
case DC_SPL_PAPERNAMES:
|
|
|
|
if (!pvOutput) {
|
|
|
|
PLOTERR(("DrvDeviceCapabilities: Spool's DC_PAPERNAMES, pvOutput=NULL"));
|
|
dwRet = (DWORD)GDI_ERROR;
|
|
break;
|
|
}
|
|
|
|
EnumFormParam.cMaxOut = pdwOutput[0];
|
|
DeviceCap = DC_PAPERNAMES;
|
|
|
|
//
|
|
// Fall through
|
|
//
|
|
|
|
case DC_PAPERNAMES:
|
|
case DC_PAPERS:
|
|
case DC_PAPERSIZE:
|
|
|
|
//
|
|
// One of the problem here is we can cached the FORM_INFO_1 which
|
|
// enum through spooler, because in between calls the data could
|
|
// changed, such as someone add/delete form through the printman, so
|
|
// at here we always free (LocalAlloc() used in PlotEnumForms) the
|
|
// memory afterward
|
|
//
|
|
|
|
EnumFormParam.pPlotDM = &(pPI->PlotDM);
|
|
EnumFormParam.pPlotGPC = pPI->pPlotGPC;
|
|
EnumFormParam.ReqIndex = DeviceCap;
|
|
EnumFormParam.pCurForm = (PFORMSIZE)pvOutput;
|
|
|
|
if (!PlotEnumForms(hPrinter, DevCapEnumFormProc, &EnumFormParam)) {
|
|
|
|
PLOTERR(("DrvDeviceCapabilities: PlotEnumForms() failed"));
|
|
dwRet = GDI_ERROR;
|
|
|
|
} else {
|
|
|
|
dwRet = EnumFormParam.ValidCount;
|
|
}
|
|
|
|
break;
|
|
|
|
case DC_SIZE:
|
|
|
|
dwRet = (DWORD)pPI->PlotDM.dm.dmSize;
|
|
|
|
break;
|
|
|
|
case DC_TRUETYPE:
|
|
|
|
//
|
|
// For now we do not return anything, because we draw truetype font
|
|
// as truetype (ie. line/curve segment), if we eventually doing ATM or
|
|
// bitmap truetype download then we will return DCFF_BITMAP but for
|
|
// now return 0
|
|
//
|
|
|
|
break;
|
|
|
|
case DC_VERSION:
|
|
|
|
dwRet = (DWORD)pPI->PlotDM.dm.dmSpecVersion;
|
|
|
|
break;
|
|
|
|
case DC_PERSONALITY:
|
|
|
|
if (pwchOutput) {
|
|
|
|
//
|
|
// DDK says an array of string buffers, each 32 characters in length.
|
|
//
|
|
_WCPYSTR(pwchOutput, L"HP-GL/2", 32);
|
|
}
|
|
|
|
dwRet = 1;
|
|
break;
|
|
|
|
case DC_COLORDEVICE:
|
|
|
|
dwRet = (pPI->pPlotGPC->Flags & PLOTF_COLOR) ? 1 : 0;
|
|
break;
|
|
|
|
case DC_SPL_MEDIAREADY:
|
|
|
|
if (!pwchOutput) {
|
|
|
|
PLOTERR(("DrvDeviceCapabilities: Spool's DC_MEDIAREADY, pwchOutput=NULL"));
|
|
dwRet = (DWORD)GDI_ERROR;
|
|
break;
|
|
}
|
|
|
|
EnumFormParam.cMaxOut = pdwOutput[0];
|
|
|
|
//
|
|
// Fall through for DC_MEDIAREADY
|
|
//
|
|
|
|
case DC_MEDIAREADY:
|
|
|
|
PLOTDBG(DBG_DEVCAPS_0,
|
|
("DevCaps(DC_MEDIAREADY:pvOut=%p): CurPaper=%ws, %ldx%ld",
|
|
pwchOutput, pPI->CurPaper.Name,
|
|
pPI->CurPaper.Size.cx, pPI->CurPaper.Size.cy));
|
|
|
|
if (pPI->CurPaper.Size.cy) {
|
|
|
|
//
|
|
// Non Roll Paper
|
|
//
|
|
|
|
dwRet = 1;
|
|
|
|
if (pwchOutput) {
|
|
|
|
if (EnumFormParam.cMaxOut >= 1) {
|
|
|
|
_WCPYSTR(pwchOutput, pPI->CurPaper.Name, CCHPAPERNAME);
|
|
|
|
} else {
|
|
|
|
dwRet = 0;
|
|
}
|
|
}
|
|
|
|
} else {
|
|
|
|
//
|
|
// Roll Paper Installed
|
|
//
|
|
|
|
EnumFormParam.pPlotDM = &(pPI->PlotDM);
|
|
EnumFormParam.pPlotGPC = pPI->pPlotGPC;
|
|
EnumFormParam.ReqIndex = DC_MEDIAREADY;
|
|
EnumFormParam.pCurForm = (PFORMSIZE)pvOutput;
|
|
|
|
if (!PlotEnumForms(hPrinter, DevCapEnumFormProc, &EnumFormParam)) {
|
|
|
|
PLOTERR(("DrvDeviceCapabilities: PlotEnumForms() failed"));
|
|
dwRet = GDI_ERROR;
|
|
|
|
} else {
|
|
|
|
//
|
|
// Remove Custom paper size
|
|
//
|
|
|
|
dwRet = EnumFormParam.ValidCount - 1;
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
case DC_STAPLE:
|
|
case DC_NUP:
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
//
|
|
// something is wrong here
|
|
//
|
|
|
|
PLOTERR(("DrvDeviceCapabilities: Invalid DeviceCap (%ld) passed.",
|
|
DeviceCap));
|
|
dwRet = (DWORD)GDI_ERROR;
|
|
}
|
|
|
|
PLOTDBG(DBG_DEVCAPS_0,
|
|
("DrvDeviceCapabilities: DC_%hs, pvOut=%p, dwRet=%ld",
|
|
pDCCaps[DeviceCap-1], (DWORD_PTR)pvOutput, dwRet));
|
|
|
|
UnMapPrinter(pPI);
|
|
|
|
return(dwRet);
|
|
|
|
|
|
#undef pbOutput
|
|
#undef psOutput
|
|
#undef pwOutput
|
|
#undef pptOutput
|
|
#undef pwchOutput
|
|
#undef pdwOutput
|
|
#undef plOutput
|
|
#undef pptsdwRet
|
|
}
|
|
|
|
|
|
|
|
DWORD
|
|
DrvSplDeviceCaps(
|
|
HANDLE hPrinter,
|
|
LPWSTR pwDeviceName,
|
|
WORD DeviceCap,
|
|
VOID *pvOutput,
|
|
DWORD cchBuf,
|
|
DEVMODE *pDM
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function supports the querrying of device capabilities.
|
|
|
|
Arguments:
|
|
|
|
hPrinter - handle the to specific printer.
|
|
|
|
pwDeviceName - pointer to the device name
|
|
|
|
DeviceCap - specific capability to get.
|
|
|
|
pvOutput - Pointer to the output buffer
|
|
|
|
cchBuf - Count of character for the pvOutput
|
|
|
|
pDM - Ponter to the input DEVMODE
|
|
|
|
|
|
Return Value:
|
|
|
|
DWORD depends on the DeviceCap
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
switch (DeviceCap) {
|
|
|
|
case DC_PAPERNAMES:
|
|
case DC_MEDIAREADY:
|
|
|
|
if (pvOutput) {
|
|
|
|
if (cchBuf >= CCHPAPERNAME) {
|
|
|
|
DeviceCap = (DeviceCap == DC_PAPERNAMES) ?
|
|
DC_SPL_PAPERNAMES :
|
|
DC_SPL_MEDIAREADY;
|
|
*((LPDWORD)pvOutput) = (DWORD)(cchBuf / CCHPAPERNAME);
|
|
|
|
PLOTDBG(DBG_DEVCAPS_0,
|
|
("SplDeviceCap: DC_SPL_MEDIAREADY, cchBuf=%ld (%ld)",
|
|
cchBuf, *((LPDWORD)pvOutput)));
|
|
|
|
} else {
|
|
|
|
return(GDI_ERROR);
|
|
}
|
|
}
|
|
|
|
return(DrvDeviceCapabilities(hPrinter,
|
|
pwDeviceName,
|
|
DeviceCap,
|
|
pvOutput,
|
|
pDM));
|
|
break;
|
|
|
|
default:
|
|
|
|
return(GDI_ERROR);
|
|
}
|
|
|
|
}
|