summaryrefslogtreecommitdiffstats
path: root/private/mvdm/fax/wowfax/wowfax.c
diff options
context:
space:
mode:
Diffstat (limited to 'private/mvdm/fax/wowfax/wowfax.c')
-rw-r--r--private/mvdm/fax/wowfax/wowfax.c461
1 files changed, 461 insertions, 0 deletions
diff --git a/private/mvdm/fax/wowfax/wowfax.c b/private/mvdm/fax/wowfax/wowfax.c
new file mode 100644
index 000000000..c6f494b77
--- /dev/null
+++ b/private/mvdm/fax/wowfax/wowfax.c
@@ -0,0 +1,461 @@
+//************************************************************************
+// Generic Win 3.1 fax printer driver support. 32-bit printer driver
+// functions. Runs in the graphics engine context (CSRSS).
+//
+// History:
+// 02-jan-95 nandurir created.
+// 01-feb-95 reedb Clean-up, support printer install and bug fixes.
+// 14-mar-95 reedb Use GDI hooks to move most functionality to UI.
+// 16-aug-95 reedb Move to kernel mode. Debug output and validate
+// functions moved from FAXCOMM.C.
+//
+//************************************************************************
+
+#include "wowfaxdd.h"
+
+//************************************************************************
+// Globals
+//************************************************************************
+
+DRVFN DrvFnTab[] = {
+ {INDEX_DrvEnablePDEV, (PFN)DrvEnablePDEV },
+ {INDEX_DrvDisablePDEV, (PFN)DrvDisablePDEV },
+ {INDEX_DrvCompletePDEV, (PFN)DrvCompletePDEV },
+ {INDEX_DrvEnableSurface, (PFN)DrvEnableSurface },
+ {INDEX_DrvDisableSurface, (PFN)DrvDisableSurface },
+ {INDEX_DrvStartDoc, (PFN)DrvStartDoc },
+ {INDEX_DrvStartPage, (PFN)DrvStartPage },
+ {INDEX_DrvSendPage, (PFN)DrvSendPage },
+ {INDEX_DrvEndDoc, (PFN)DrvEndDoc },
+ {INDEX_DrvDitherColor, (PFN)DrvDitherColor },
+ {INDEX_DrvEscape, (PFN)DrvEscape},
+ };
+
+#define NO_DRVFN (sizeof(DrvFnTab) / sizeof(DrvFnTab[0]))
+
+
+#if DBG
+
+//************************************************************************
+// faxlogprintf - Driver version of the debug output function.
+//
+//************************************************************************
+
+VOID faxlogprintf(PCHAR pszFmt, ...)
+{
+ va_list ap;
+ char buffer[256];
+
+ va_start(ap, pszFmt);
+
+ EngDebugPrint("", pszFmt, ap);
+
+ va_end(ap);
+}
+
+#endif
+
+//************************************************************************
+// ValidateFaxDev - Validates the FAXDEV structure by checking the DWORD
+// signature, which is a known fixed value.
+//
+//************************************************************************
+
+BOOL ValidateFaxDev(LPFAXDEV lpFaxDev)
+{
+ if (lpFaxDev) {
+ if (lpFaxDev->id == FAXDEV_ID) {
+ return TRUE;
+ }
+ LOGDEBUG(("ValidateFaxDev failed, bad id, lpFaxDev: %X\n", lpFaxDev));
+ }
+ else {
+ LOGDEBUG(("ValidateFaxDev failed, lpFaxDev: NULL\n"));
+ }
+ return FALSE;
+}
+
+//************************************************************************
+// DllInitProc
+//************************************************************************
+
+BOOL DllInitProc(HMODULE hModule, DWORD Reason, PCONTEXT pContext)
+{
+ UNREFERENCED_PARAMETER(hModule);
+ UNREFERENCED_PARAMETER(Reason);
+ UNREFERENCED_PARAMETER(pContext);
+
+ return TRUE;
+}
+
+
+//***************************************************************************
+// DrvEnableDriver
+//***************************************************************************
+
+BOOL DrvEnableDriver(ULONG iEngineVersion, ULONG cb, DRVENABLEDATA *pded)
+{
+ LOGDEBUG(("WOWFAX!DrvEnableDriver, iEngineVersion: %X, cb: %X, pded: %X\n", iEngineVersion, cb, pded));
+
+ pded->iDriverVersion = DDI_DRIVER_VERSION;
+
+ if (cb < sizeof(DRVENABLEDATA)) {
+ LOGDEBUG(("WOWFAX!DrvEnableDriver, failed\n"));
+ return FALSE;
+ }
+
+ pded->c = NO_DRVFN;
+ pded->pdrvfn = DrvFnTab;
+
+ return TRUE;
+
+}
+
+//***************************************************************************
+// DrvDisableDriver
+//***************************************************************************
+
+VOID DrvDisableDriver(VOID)
+{
+ LOGDEBUG(("WOWFAX!DrvDisableDriver\n"));
+ return;
+}
+
+//***************************************************************************
+// DrvEnablePDEV
+//***************************************************************************
+DHPDEV DrvEnablePDEV(DEVMODEW *pdevmode, // Driver data, Client FAXDEV
+ PWSTR pwstrPrtName, // Printer's name in CreateDC()
+ ULONG cPatterns, // Count of standard patterns
+ HSURF *phsurfPatterns, // Buffer for standard patterns
+ ULONG cjGdiInfo, // Size of buffer for GdiInfo
+ ULONG *pulGdiInfo, // Buffer for GDIINFO
+ ULONG cjDevInfo, // Number of bytes in devinfo
+ DEVINFO *pdevinfo, // Device info
+ HDEV hdev,
+ PWSTR pwstrDeviceName, // Device Name - "LaserJet II"
+ HANDLE hDriver // Printer handle for spooler access
+)
+{
+ LPFAXDEV lpCliFaxDev, lpSrvFaxDev = NULL;
+
+ LOGDEBUG(("WOWFAX!DrvEnablePDEV, pdevmode: %X, pwstrPrtName: %S\n", pdevmode, pwstrPrtName));
+
+ if (pdevmode) {
+ // Point to the end of the DEVMODE where the FAXDEV is located.
+ lpCliFaxDev = (LPFAXDEV) ((PBYTE)pdevmode + pdevmode->dmSize);
+
+ // Allocate a server side FAXDEV to be passed back to GDI. Copy the
+ // client side FAXDEV to the server side FAXDEV. Note all pointers in
+ // the client FAXDEV reference client side memory and cannot be
+ // dereferenced on the server side.
+ lpSrvFaxDev = (LPFAXDEV)EngAllocMem(0, sizeof(FAXDEV), FAXDEV_ID);
+ LOGDEBUG(("WOWFAX!DrvEnablePDEV, allocated lpSrvFaxDev: %X\n", lpSrvFaxDev));
+
+ if (InitPDEV(lpCliFaxDev, lpSrvFaxDev,
+ cPatterns, phsurfPatterns,
+ cjGdiInfo, pulGdiInfo,
+ cjDevInfo, pdevinfo)) {
+
+ lpSrvFaxDev->hDriver = hDriver;
+ return (DHPDEV)lpSrvFaxDev;
+ }
+ else {
+ LOGDEBUG(("WOWFAX!DrvEnablePDEV, failed\n"));
+ if (lpSrvFaxDev) {
+ EngFreeMem(lpSrvFaxDev);
+ lpSrvFaxDev = NULL;
+ }
+ }
+ }
+ return (DHPDEV)lpSrvFaxDev;
+}
+
+//***************************************************************************
+// InitPDEV - Called by DrvEnablePDEV and DrvRestartPDEV to initialize the
+// server side PDEV/FAXDEV.
+//***************************************************************************
+
+
+BOOL InitPDEV(
+ LPFAXDEV lpCliFaxDev, // Pointer to the client side FAXDEV
+ LPFAXDEV lpSrvFaxDev, // Pointer to the server side FAXDEV
+ ULONG cPatterns, // Count of standard patterns
+ HSURF *phsurfPatterns, // Buffer for standard patterns
+ ULONG cjGdiInfo, // Size of buffer for GdiInfo
+ ULONG *pulGdiInfo, // Buffer for GDIINFO
+ ULONG cjDevInfo, // Number of bytes in devinfo
+ DEVINFO *pdevinfo // Device info
+)
+{
+ PGDIINFO pgdiinfo = (PGDIINFO)pulGdiInfo;
+ ULONG uColors[2];
+
+ if (!ValidateFaxDev(lpCliFaxDev)) {
+ return FALSE;
+ }
+
+ // lpSrvFaxDev hasn't been initialized yet, so just check pointer.
+ if (lpSrvFaxDev == NULL) {
+ LOGDEBUG(("WOWFAX!InitPDEV, failed, NULL lpSrvFaxDev parameter\n"));
+ return FALSE;
+ }
+
+ // Copy client FAXDEV to server.
+ RtlCopyMemory(lpSrvFaxDev, lpCliFaxDev, sizeof(FAXDEV));
+
+ // Copy GDIINFO from client FAXDEV to the GDI buffer for GDIINFO.
+ RtlCopyMemory(pgdiinfo, &(lpCliFaxDev->gdiinfo), sizeof(GDIINFO));
+
+ // Initialize the DEVINFO structure.
+ uColors[0] = RGB(0x00, 0x00, 0x00);
+ uColors[1] = RGB(0xff, 0xff, 0xff);
+
+ pdevinfo->hpalDefault = EngCreatePalette(PAL_INDEXED, 2, uColors, 0, 0, 0);
+ pdevinfo->iDitherFormat = BMF_1BPP;
+
+ // Make sure we don't journal.
+ pdevinfo->flGraphicsCaps |= GCAPS_DONTJOURNAL;
+
+ // Make sure we do dither.
+ pdevinfo->flGraphicsCaps |= GCAPS_HALFTONE | GCAPS_MONO_DITHER |
+ GCAPS_COLOR_DITHER;
+
+ // Copy the DEVINFO data to the server side FAXDEV.
+ RtlCopyMemory(&(lpSrvFaxDev->devinfo), pdevinfo, sizeof(DEVINFO));
+
+ return TRUE;
+}
+
+//***************************************************************************
+// DrvCompletePDEV
+//***************************************************************************
+
+VOID DrvCompletePDEV(DHPDEV dhpdev, HDEV hdev)
+{
+ LPFAXDEV lpSrvFaxDev = (LPFAXDEV) dhpdev;
+
+ LOGDEBUG(("WOWFAX!DrvCompletePDEV, dhpdev %X\n", dhpdev));
+
+ if (ValidateFaxDev(lpSrvFaxDev)) {
+ // Store the gdi handle.
+ lpSrvFaxDev->hdev = hdev;
+ }
+ else {
+ LOGDEBUG(("WOWFAX!DrvCompletePDEV, failed\n"));
+ }
+
+ return;
+}
+
+//***************************************************************************
+// DrvDisablePDEV
+//***************************************************************************
+
+VOID DrvDisablePDEV(DHPDEV dhpdev)
+{
+ LPFAXDEV lpSrvFaxDev = (LPFAXDEV) dhpdev;
+
+ LOGDEBUG(("WOWFAX!DrvDisablePDEV, dhpdev %X\n", dhpdev));
+
+ if (ValidateFaxDev(lpSrvFaxDev)) {
+ if (lpSrvFaxDev->devinfo.hpalDefault) {
+ EngDeletePalette(lpSrvFaxDev->devinfo.hpalDefault);
+ }
+ EngFreeMem(lpSrvFaxDev);
+ LOGDEBUG(("WOWFAX!DrvDisablePDEV, deallocated lpSrvFaxDev: %X\n", lpSrvFaxDev));
+ }
+ else {
+ LOGDEBUG(("WOWFAX!DrvDisablePDEV, failed\n"));
+ }
+ return;
+}
+
+
+//***************************************************************************
+// DrvEnableSurface
+//***************************************************************************
+
+HSURF DrvEnableSurface(DHPDEV dhpdev)
+{
+
+ LPFAXDEV lpFaxDev = (LPFAXDEV)dhpdev;
+ HBITMAP hbm = 0;
+
+ LOGDEBUG(("WOWFAX!DrvEnableSurface, lpFaxDev: %X\n", lpFaxDev));
+
+ if (ValidateFaxDev(lpFaxDev)) {
+ // GDI will allocate space for the bitmap bits. We'll use a DrvEscape
+ // to copy them to the client side.
+ hbm = EngCreateBitmap(lpFaxDev->gdiinfo.szlPhysSize,
+ lpFaxDev->bmWidthBytes,
+ lpFaxDev->bmFormat, BMF_TOPDOWN, NULL);
+ if (hbm) {
+ lpFaxDev->hbm = hbm;
+ EngAssociateSurface((HSURF)hbm, lpFaxDev->hdev, 0);
+ return (HSURF)hbm;
+ }
+ LOGDEBUG(("WOWFAX!DrvEnableSurface, EngCreateBitmap failed\n"));
+ }
+
+ return (HSURF)hbm;
+}
+
+//***************************************************************************
+// DrvDisableSurface
+//***************************************************************************
+
+VOID DrvDisableSurface(
+ DHPDEV dhpdev
+)
+{
+ LPFAXDEV lpFaxDev = (LPFAXDEV)dhpdev;
+
+ LOGDEBUG(("WOWFAX!DrvDisableSurface, lpFaxDev: %X\n", lpFaxDev));
+
+ if (ValidateFaxDev(lpFaxDev)) {
+ if (lpFaxDev->hbm) {
+ EngDeleteSurface((HSURF)lpFaxDev->hbm);
+ lpFaxDev->hbm = 0;
+ return;
+ }
+ }
+ return;
+}
+
+//***************************************************************************
+// DrvStartDoc
+//***************************************************************************
+
+BOOL DrvStartDoc(
+ SURFOBJ *pso,
+ PWSTR pwszDocName,
+ DWORD dwJobId
+)
+{
+ LOGDEBUG(("WOWFAX!DrvStartDoc, pso: %X, pwszDocName: %S, dwJobId: %X\n", pso, pwszDocName, dwJobId));
+ return TRUE;
+}
+
+//***************************************************************************
+// DrvStartPage
+//***************************************************************************
+
+BOOL DrvStartPage(
+ SURFOBJ *pso
+)
+{
+ LPFAXDEV lpFaxDev = (LPFAXDEV)pso->dhpdev;
+ BITMAP bm;
+ RECTL rc;
+
+ LOGDEBUG(("WOWFAX!DrvStartPage, pso: %X\n", pso));
+
+ // Calculate the size of the rectangle based on the input data
+ // in 'pso' - this will ensure that the entire bitmap is erased.
+
+ if (ValidateFaxDev(lpFaxDev)) {
+ rc.left = 0;
+ rc.top = 0;
+ rc.right = pso->lDelta * lpFaxDev->cPixPerByte;
+ rc.bottom = pso->cjBits / pso->lDelta;
+
+ EngEraseSurface(pso, &rc, COLOR_INDEX_WHITE);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+//***************************************************************************
+// DrvSendPage
+//***************************************************************************
+
+BOOL DrvSendPage(SURFOBJ *pso)
+{
+ LOGDEBUG(("WOWFAX!DrvSendPage, pso %X\n", pso));
+ return TRUE;
+}
+
+
+//***************************************************************************
+// DrvEndDoc
+//***************************************************************************
+
+BOOL DrvEndDoc(SURFOBJ *pso, FLONG fl)
+{
+ LOGDEBUG(("WOWFAX!DrvEndDoc, pso %X\n", pso));
+ return TRUE;
+}
+
+ULONG
+DrvDitherColor(
+ DHPDEV dhpdev,
+ ULONG iMode,
+ ULONG rgbColor,
+ ULONG *pulDither
+ )
+
+{
+ return DCR_HALFTONE;
+}
+
+//***************************************************************************
+// DrvEscape - Allows client side to get server side data.
+//***************************************************************************
+
+ULONG DrvEscape(
+ SURFOBJ *pso,
+ ULONG iEsc,
+ ULONG cjIn,
+ PVOID *pvIn,
+ ULONG cjOut,
+ PVOID *pvOut
+)
+{
+ LPFAXDEV lpSrvFaxDev;
+ ULONG ulRet = 0;
+
+ LOGDEBUG(("WOWFAX!DrvEscape, pso %X, iEsc: %X\n", pso, iEsc));
+ if (pso) {
+ lpSrvFaxDev = (LPFAXDEV)pso->dhpdev;
+ if (ValidateFaxDev(lpSrvFaxDev)) {
+ LOGDEBUG(("WOWFAX!DrvEscape, lpSrvFaxDev: %X\n", lpSrvFaxDev));
+ switch (iEsc) {
+ case DRV_ESC_GET_DEVMODE_PTR:
+ return (ULONG) lpSrvFaxDev->pdevmode;
+
+ case DRV_ESC_GET_FAXDEV_PTR:
+ return (ULONG) lpSrvFaxDev->lpClient;
+
+ case DRV_ESC_GET_SURF_INFO:
+ if (pvOut) {
+ if (cjOut == sizeof(LONG)) {
+ (LONG) *pvOut = pso->lDelta;
+ return (ULONG) pso->cjBits;
+ }
+ }
+ break;
+
+ case DRV_ESC_GET_BITMAP_BITS:
+ // Validate the buffer pointer and copy the bits.
+ if (pvOut) {
+ if (cjOut == pso->cjBits) {
+ RtlCopyMemory(pvOut, pso->pvBits, cjOut);
+ return cjOut;
+ }
+ LOGDEBUG(("WOWFAX!DrvEscape, bitmap size mismatch cjIn: %X, pso->cjBits: %X\n", cjIn, pso->cjBits));
+ }
+ break;
+
+// default:
+ LOGDEBUG(("WOWFAX!DrvEscape, unknown escape: %X\n", iEsc));
+ } //switch
+ }
+ }
+ LOGDEBUG(("WOWFAX!DrvEscape, failed\n"));
+
+ return ulRet;
+}
+
+