462 lines
8.5 KiB
C
462 lines
8.5 KiB
C
|
/*++
|
|||
|
|
|||
|
Copyright (c) 1996 Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
devcaps.c
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
Implementation of DrvDeviceCapabilities
|
|||
|
|
|||
|
Environment:
|
|||
|
|
|||
|
Fax driver user interface
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
01/09/96 -davidx-
|
|||
|
Created it.
|
|||
|
|
|||
|
mm/dd/yy -author-
|
|||
|
description
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
#include "faxui.h"
|
|||
|
#include "forms.h"
|
|||
|
|
|||
|
//
|
|||
|
// Forward declaration for local functions
|
|||
|
//
|
|||
|
|
|||
|
DWORD
|
|||
|
CalcMinMaxExtent(
|
|||
|
PPOINT pOutput,
|
|||
|
FORM_INFO_1 *pFormsDB,
|
|||
|
DWORD cForms,
|
|||
|
INT wCapability
|
|||
|
);
|
|||
|
|
|||
|
DWORD
|
|||
|
EnumResolutions(
|
|||
|
PLONG pResolutions
|
|||
|
);
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DWORD
|
|||
|
DrvDeviceCapabilities(
|
|||
|
HANDLE hPrinter,
|
|||
|
LPTSTR pDeviceName,
|
|||
|
WORD wCapability,
|
|||
|
PVOID pOutput,
|
|||
|
PDEVMODE pdm
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Provides information about the specified device and its capabilities
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
hPrinter - Identifies a printer object
|
|||
|
pDeviceName - Points to a null-terminated device name string
|
|||
|
wCapability - Specifies the interested device capability
|
|||
|
pOutput - Points to the output buffer
|
|||
|
pdm - Points to the source devmode structure
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
The return value depends on wCapability.
|
|||
|
|
|||
|
Note:
|
|||
|
|
|||
|
Please refer for DDK documentation for more details.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
FORM_INFO_1 *pFormsDB;
|
|||
|
DWORD cForms;
|
|||
|
PVOID pdmAlloced;
|
|||
|
DWORD result = 0;
|
|||
|
|
|||
|
Verbose(("Entering DrvDeviceCapabilities: %d %x...\n", wCapability, pOutput));
|
|||
|
|
|||
|
//
|
|||
|
// Validate input devmode and combine it with driver default
|
|||
|
//
|
|||
|
|
|||
|
if (! (pdmAlloced = MemAlloc(sizeof(DRVDEVMODE)))) {
|
|||
|
|
|||
|
Error(("Memory allocation failed\n"));
|
|||
|
return GDI_ERROR;
|
|||
|
}
|
|||
|
|
|||
|
DriverDefaultDevmode(pdmAlloced, pDeviceName, hPrinter);
|
|||
|
pdm = pdmAlloced;
|
|||
|
result = 0;
|
|||
|
|
|||
|
//
|
|||
|
// Return appropriate information depending upon wCapability
|
|||
|
//
|
|||
|
|
|||
|
switch (wCapability) {
|
|||
|
|
|||
|
case DC_VERSION:
|
|||
|
|
|||
|
result = pdm->dmSpecVersion;
|
|||
|
break;
|
|||
|
|
|||
|
case DC_DRIVER:
|
|||
|
|
|||
|
result = pdm->dmDriverVersion;
|
|||
|
break;
|
|||
|
|
|||
|
case DC_SIZE:
|
|||
|
|
|||
|
result = pdm->dmSize;
|
|||
|
break;
|
|||
|
|
|||
|
case DC_EXTRA:
|
|||
|
|
|||
|
result = pdm->dmDriverExtra;
|
|||
|
break;
|
|||
|
|
|||
|
case DC_FIELDS:
|
|||
|
|
|||
|
result = pdm->dmFields;
|
|||
|
break;
|
|||
|
|
|||
|
case DC_COPIES:
|
|||
|
|
|||
|
//
|
|||
|
// Pretend that we can handle huge number of copies so that
|
|||
|
// the apps won't try to do multi-copies themselves.
|
|||
|
//
|
|||
|
|
|||
|
result = 1000;
|
|||
|
break;
|
|||
|
|
|||
|
case DC_ORIENTATION:
|
|||
|
|
|||
|
//
|
|||
|
// Landscape rotates counterclockwise
|
|||
|
//
|
|||
|
|
|||
|
result = 90;
|
|||
|
break;
|
|||
|
|
|||
|
case DC_PAPERNAMES:
|
|||
|
case DC_PAPERS:
|
|||
|
case DC_PAPERSIZE:
|
|||
|
case DC_MINEXTENT:
|
|||
|
case DC_MAXEXTENT:
|
|||
|
|
|||
|
//
|
|||
|
// Get a list of forms in the forms database
|
|||
|
//
|
|||
|
|
|||
|
pFormsDB = GetFormsDatabase(hPrinter, &cForms);
|
|||
|
|
|||
|
if (pFormsDB == NULL || cForms == 0) {
|
|||
|
|
|||
|
Error(("Cannot get system forms\n"));
|
|||
|
return GDI_ERROR;
|
|||
|
}
|
|||
|
|
|||
|
result = (wCapability == DC_MINEXTENT || wCapability == DC_MAXEXTENT) ?
|
|||
|
CalcMinMaxExtent(pOutput, pFormsDB, cForms, wCapability) :
|
|||
|
EnumPaperSizes(pOutput, pFormsDB, cForms, wCapability);
|
|||
|
|
|||
|
MemFree(pFormsDB);
|
|||
|
break;
|
|||
|
|
|||
|
case DC_BINNAMES:
|
|||
|
|
|||
|
//
|
|||
|
// Simulate a single input slot
|
|||
|
//
|
|||
|
|
|||
|
if (pOutput)
|
|||
|
LoadString(ghInstance, IDS_SLOT_ONLYONE, pOutput, CCHBINNAME);
|
|||
|
result = 1;
|
|||
|
break;
|
|||
|
|
|||
|
case DC_BINS:
|
|||
|
|
|||
|
if (pOutput)
|
|||
|
*((PWORD) pOutput) = DMBIN_ONLYONE;
|
|||
|
result = 1;
|
|||
|
break;
|
|||
|
|
|||
|
case DC_ENUMRESOLUTIONS:
|
|||
|
|
|||
|
result = EnumResolutions(pOutput);
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
|
|||
|
Error(("Unknown device capability: %d\n", wCapability));
|
|||
|
result = GDI_ERROR;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
MemFree(pdmAlloced);
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DWORD
|
|||
|
EnumPaperSizes(
|
|||
|
PVOID pOutput,
|
|||
|
FORM_INFO_1 *pFormsDB,
|
|||
|
DWORD cForms,
|
|||
|
INT wCapability
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Retrieves a list of supported paper sizes
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
pOutput - Specifies a buffer for storing requested information
|
|||
|
pFormsDB - Pointer to an array of forms from the forms database
|
|||
|
cForms - Number of forms in the array
|
|||
|
wCapability - Specifies what the caller is interested in
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Number of paper sizes supported
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
DWORD index, count = 0;
|
|||
|
LPTSTR pPaperNames = NULL;
|
|||
|
PWORD pPapers = NULL;
|
|||
|
PPOINT pPaperSizes = NULL;
|
|||
|
|
|||
|
//
|
|||
|
// Figure out what the caller is interested in
|
|||
|
//
|
|||
|
|
|||
|
switch (wCapability) {
|
|||
|
|
|||
|
case DC_PAPERNAMES:
|
|||
|
pPaperNames = pOutput;
|
|||
|
break;
|
|||
|
|
|||
|
case DC_PAPERSIZE:
|
|||
|
pPaperSizes = pOutput;
|
|||
|
break;
|
|||
|
|
|||
|
case DC_PAPERS:
|
|||
|
pPapers = pOutput;
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
Assert(FALSE);
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Go through each form in the forms database
|
|||
|
//
|
|||
|
|
|||
|
for (index=0; index < cForms; index++, pFormsDB++) {
|
|||
|
|
|||
|
//
|
|||
|
// If the form is supported on the printer, then increment the count
|
|||
|
// and collect requested information
|
|||
|
//
|
|||
|
|
|||
|
if (! IsSupportedForm(pFormsDB))
|
|||
|
continue;
|
|||
|
|
|||
|
count++;
|
|||
|
|
|||
|
//
|
|||
|
// Return the size of the form in 0.1mm units.
|
|||
|
// The unit used in FORM_INFO_1 is 0.001mm.
|
|||
|
//
|
|||
|
|
|||
|
if (pPaperSizes) {
|
|||
|
|
|||
|
pPaperSizes->x = pFormsDB->Size.cx / 100;
|
|||
|
pPaperSizes->y = pFormsDB->Size.cy / 100;
|
|||
|
pPaperSizes++;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Return the formname.
|
|||
|
//
|
|||
|
|
|||
|
if (pPaperNames) {
|
|||
|
|
|||
|
CopyString(pPaperNames, pFormsDB->pName, CCHPAPERNAME);
|
|||
|
pPaperNames += CCHPAPERNAME;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Return one-based index of the form.
|
|||
|
//
|
|||
|
|
|||
|
if (pPapers)
|
|||
|
*pPapers++ = (WORD) index + DMPAPER_FIRST;
|
|||
|
}
|
|||
|
|
|||
|
return count;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DWORD
|
|||
|
CalcMinMaxExtent(
|
|||
|
PPOINT pOutput,
|
|||
|
FORM_INFO_1 *pFormsDB,
|
|||
|
DWORD cForms,
|
|||
|
INT wCapability
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Retrieves the minimum or maximum paper size extent
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
pOutput - Specifies a buffer for storing requested information
|
|||
|
pFormsDB - Pointer to an array of forms from the forms database
|
|||
|
cForms - Number of forms in the array
|
|||
|
wCapability - What the caller is interested in: DC_MAXEXTENT or DC_MINEXTENT
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Number of paper sizes supported
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
DWORD index, count = 0;
|
|||
|
LONG minX, minY, maxX, maxY;
|
|||
|
|
|||
|
//
|
|||
|
// Go through each form in the forms database
|
|||
|
//
|
|||
|
|
|||
|
minX = minY = MAX_LONG;
|
|||
|
maxX = maxY = 0;
|
|||
|
|
|||
|
for (index=0; index < cForms; index++, pFormsDB++) {
|
|||
|
|
|||
|
//
|
|||
|
// If the form is supported on the printer, then increment the count
|
|||
|
// and collect the requested information
|
|||
|
//
|
|||
|
|
|||
|
if (! IsSupportedForm(pFormsDB))
|
|||
|
continue;
|
|||
|
|
|||
|
count++;
|
|||
|
|
|||
|
if (pOutput == NULL)
|
|||
|
continue;
|
|||
|
|
|||
|
if (minX > pFormsDB->Size.cx)
|
|||
|
minX = pFormsDB->Size.cx;
|
|||
|
|
|||
|
if (minY > pFormsDB->Size.cy)
|
|||
|
minY = pFormsDB->Size.cy;
|
|||
|
|
|||
|
if (maxX < pFormsDB->Size.cx)
|
|||
|
maxX = pFormsDB->Size.cx;
|
|||
|
|
|||
|
if (maxY < pFormsDB->Size.cy)
|
|||
|
maxY = pFormsDB->Size.cy;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// If an output buffer is provided, store the calculated
|
|||
|
// minimum and maximum extent information.
|
|||
|
//
|
|||
|
|
|||
|
if (pOutput != NULL) {
|
|||
|
|
|||
|
//
|
|||
|
// NOTE: What unit does the caller expect?! The documentation
|
|||
|
// doesn't mention anything about this. I assume this should
|
|||
|
// be in the same unit as DEVMODE.dmPaperLength, which is 0.1mm.
|
|||
|
//
|
|||
|
|
|||
|
if (wCapability == DC_MINEXTENT) {
|
|||
|
|
|||
|
pOutput->x = minX / 100;
|
|||
|
pOutput->y = minY / 100;
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
pOutput->x = maxX / 100;
|
|||
|
pOutput->y = maxY / 100;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return count;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DWORD
|
|||
|
EnumResolutions(
|
|||
|
PLONG pResolutions
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Retrieves a list of supported resolutions
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
pResolutions - Specifies a buffer for storing resolution information
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Number of resolutions supported
|
|||
|
|
|||
|
Note:
|
|||
|
|
|||
|
Each resolution is represented by two LONGs representing
|
|||
|
horizontal and vertical resolutions (in dpi) respectively.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
if (pResolutions != NULL) {
|
|||
|
|
|||
|
//
|
|||
|
// We support the following resolution settings:
|
|||
|
// Normal = 200x200 dpi
|
|||
|
// Draft = 200x100 dpi
|
|||
|
//
|
|||
|
|
|||
|
*pResolutions++ = FAXRES_HORIZONTAL;
|
|||
|
*pResolutions++ = FAXRES_VERTICAL;
|
|||
|
|
|||
|
*pResolutions++ = FAXRES_HORIZONTAL;
|
|||
|
*pResolutions++ = FAXRES_VERTDRAFT;
|
|||
|
}
|
|||
|
|
|||
|
return 2;
|
|||
|
}
|
|||
|
|