|
|
1.1 ! root 1: //-------------------------------------------------------------------------- ! 2: // ! 3: // Module Name: HEADER.C ! 4: // ! 5: // Brief Description: This module contains the PSCRIPT driver's header ! 6: // output functions and related routines. ! 7: // ! 8: // Author: Kent Settle (kentse) ! 9: // Created: 26-Nov-1990 ! 10: // ! 11: // Copyright (c) 1990-1993 Microsoft Corporation ! 12: // ! 13: // This routine contains routines to output the PostScript driver's header. ! 14: //-------------------------------------------------------------------------- ! 15: ! 16: #include "pscript.h" ! 17: #include "header.h" ! 18: #include "resource.h" ! 19: #include "enable.h" ! 20: ! 21: ! 22: extern HMODULE ghmodDrv; // GLOBAL MODULE HANDLE. ! 23: extern int NameComp(CHAR *, CHAR *); ! 24: ! 25: BOOL bSendDeviceSetup(PDEVDATA); ! 26: VOID DownloadNTProcSet(PDEVDATA, BOOL); ! 27: VOID SetFormAndTray(PDEVDATA); ! 28: ! 29: //-------------------------------------------------------------------------- ! 30: // BOOL bOutputHeader(pdev) ! 31: // PDEVDATA pdev; ! 32: // ! 33: // This routine sends the driver's header to the output channel. ! 34: // ! 35: // Parameters: ! 36: // pdev: ! 37: // pointer to DEVDATA structure. ! 38: // ! 39: // Returns: ! 40: // This function returns TRUE if the header was successfully sent, ! 41: // FALSE otherwise. ! 42: // ! 43: // History: ! 44: // 26-Nov-1990 -by- Kent Settle (kentse) ! 45: // Wrote it. ! 46: //-------------------------------------------------------------------------- ! 47: ! 48: BOOL bOutputHeader(pdev) ! 49: PDEVDATA pdev; ! 50: { ! 51: CHAR buf[128]; ! 52: CHAR *pstr; ! 53: WCHAR *pwstr; ! 54: DWORD cTmp, i; ! 55: BOOL bDuplex; ! 56: SYSTEMTIME systime; ! 57: DWORD pbgr; ! 58: PSRESOLUTION *pRes; ! 59: PNTPD pntpd; ! 60: ! 61: // don't do anything if the header has already been sent to the printer. ! 62: ! 63: if (pdev->dwFlags & PDEV_PROCSET) ! 64: return TRUE; ! 65: ! 66: // set the header sent flag. this needs to be done before a call ! 67: // to Print is made in order to keep from getting stuck in a loop. ! 68: ! 69: pdev->dwFlags |= PDEV_PROCSET; ! 70: ! 71: // if RAWDATA has already been sent to the printer, then we only want ! 72: // to send down our ProcSet, and not the rest of the header, or any ! 73: // of the device setup commands. ! 74: ! 75: if (pdev->dwFlags & PDEV_RAWDATASENT) ! 76: { ! 77: // define our procedure set, FALSE means don't even think ! 78: // about defining the error handler.. ! 79: ! 80: DownloadNTProcSet(pdev, FALSE); ! 81: ! 82: // output a save command for the first page. this is done in the ! 83: // header as part of the effort to avoid outputting two headers in ! 84: // the raw data case. FALSE means to perform a save and not a gsave. ! 85: ! 86: ps_save(pdev, FALSE); ! 87: pdev->dwFlags |= PDEV_WITHINPAGE; ! 88: ! 89: return(TRUE); ! 90: } ! 91: ! 92: // get a local pointer. ! 93: ! 94: pntpd = pdev->pntpd; ! 95: ! 96: // output the header comments. NOTE, these comments conform to ! 97: // Version 2.0 of the Adobe Structuring Conventions. ! 98: ! 99: // if the printer supports job switching, put the printer into ! 100: // postscript mode now. ! 101: ! 102: if (pntpd->flFlags & PJL_PROTOCOL) ! 103: PrintString(pdev, "\033%-12345X@PJL ENTER LANGUAGE=POSTSCRIPT\n"); ! 104: if (pntpd->flFlags & SIC_PROTOCOL) ! 105: { ! 106: // call directly to bPSWrite to output the necessary escape commands. ! 107: // PrintString will NOT output '\000'. ! 108: ! 109: bPSWrite(pdev, "\033\133\113\030\000\006\061\010\000\000\000\000\000", 13); ! 110: bPSWrite(pdev, "\000\000\000\000\000\000\000\000\004\033\133\113\003", 13); ! 111: bPSWrite(pdev, "\000\006\061\010\004", 5); ! 112: } ! 113: ! 114: //!!! output something different if Encapsulated PS. ! 115: //!!! PrintString(pdev, "%!PS-Adobe-2.0 EPSF-2.0\n"); ! 116: ! 117: PrintString(pdev, "%!PS-Adobe-2.0\n"); ! 118: ! 119: // output the title of the document. ! 120: ! 121: if (pdev->pwstrDocName) ! 122: { ! 123: //!!! need to output UNICODE document name??? -kentse. ! 124: //!!! for now just lop off top word. ! 125: pstr = buf; ! 126: pwstr = pdev->pwstrDocName; ! 127: ! 128: cTmp = min((sizeof(buf) - 1), wcslen(pwstr)); ! 129: ! 130: while (cTmp--) ! 131: *pstr++ = (CHAR)*pwstr++; ! 132: ! 133: // NULL terminate the document name. ! 134: ! 135: *pstr = '\0'; ! 136: ! 137: PrintString(pdev, "%%Title: "); ! 138: PrintString(pdev, buf); ! 139: PrintString(pdev, "\n"); ! 140: } ! 141: else ! 142: PrintString(pdev, "%%Title: Untitled Document\n"); ! 143: ! 144: // let the world know who we are. ! 145: ! 146: PrintString(pdev, "%%Creator: Windows NT 3.1\n"); ! 147: ! 148: // print the date and time of creation. ! 149: ! 150: GetLocalTime(&systime); ! 151: ! 152: PrintString(pdev, "%%CreationDate: "); ! 153: PrintDecimal(pdev, 1, systime.wHour); ! 154: PrintString(pdev, ":"); ! 155: PrintDecimal(pdev, 1, systime.wMinute); ! 156: PrintString(pdev, " "); ! 157: PrintDecimal(pdev, 1, systime.wMonth); ! 158: PrintString(pdev, "/"); ! 159: PrintDecimal(pdev, 1, systime.wDay); ! 160: PrintString(pdev, "/"); ! 161: PrintDecimal(pdev, 1, systime.wYear); ! 162: ! 163: // mark the bounding box of the document. ! 164: ! 165: PrintString(pdev, "\n%%BoundingBox: "); ! 166: PrintDecimal(pdev, 4, pdev->CurForm.imagearea.left, ! 167: pdev->CurForm.imagearea.bottom, ! 168: pdev->CurForm.imagearea.right, ! 169: pdev->CurForm.imagearea.top); ! 170: ! 171: PrintString(pdev, "\n%%DocumentProcSets: Windows_NT_3.1\n"); ! 172: PrintString(pdev, "%%DocumentSuppliedProcSets: Windows_NT_3.1\n"); ! 173: ! 174: if (pdev->cCopies > 1) ! 175: { ! 176: PrintString(pdev, "%%Requirements: numcopies("); ! 177: PrintDecimal(pdev, 1, pdev->cCopies); ! 178: PrintString(pdev, ") collate\n"); ! 179: } ! 180: ! 181: // we are done with the comments portion of the document. ! 182: ! 183: PrintString(pdev, "%%EndComments\n"); ! 184: ! 185: // define our procedure set. ! 186: ! 187: DownloadNTProcSet(pdev, TRUE); ! 188: ! 189: PrintString(pdev, "%%EndProlog\n"); ! 190: ! 191: // do the device setup. ! 192: ! 193: PrintString(pdev, "%%BeginSetup\n"); ! 194: ! 195: // send the resolution selection command, if necessary. ! 196: ! 197: if (pntpd->cResolutions > 0) ! 198: { ! 199: pRes = (PSRESOLUTION *)((CHAR *)pntpd + pntpd->loResolution); ! 200: ! 201: // search each possible resolution until the specified one is ! 202: // found. ! 203: ! 204: for (i = 0; i < (DWORD)pntpd->cResolutions; i++) ! 205: { ! 206: if (pRes[i].iValue == (DWORD)pdev->psdm.dm.dmPrintQuality) ! 207: { ! 208: PrintString(pdev, "%%BeginFeature: *Resolution "); ! 209: PrintDecimal(pdev, 1, pdev->psdm.dm.dmPrintQuality); ! 210: PrintString(pdev, "\n"); ! 211: PrintString(pdev, (CHAR *)pntpd + pRes[i].loInvocation); ! 212: PrintString(pdev, "\n%%EndFeature\n"); ! 213: } ! 214: } ! 215: } ! 216: ! 217: // send form and tray selection commands. ! 218: ! 219: SetFormAndTray(pdev); ! 220: ! 221: // handle duplex if necessary. ! 222: ! 223: if ((pntpd->loszDuplexNone) || ! 224: (pntpd->loszDuplexNoTumble) || ! 225: (pntpd->loszDuplexTumble)) ! 226: bDuplex = TRUE; ! 227: else ! 228: bDuplex = FALSE; ! 229: ! 230: if (bDuplex) ! 231: { ! 232: if (pdev->psdm.dm.dmDuplex == DMDUP_HORIZONTAL) ! 233: { ! 234: if (pdev->psdm.dm.dmOrientation == DMORIENT_LANDSCAPE) ! 235: { ! 236: PrintString(pdev, "%%BeginFeature: *Duplex DuplexNoTumble\n"); ! 237: if (pntpd->loszDuplexNoTumble) ! 238: pstr = (char *)pntpd + pntpd->loszDuplexNoTumble; ! 239: } ! 240: else ! 241: { ! 242: PrintString(pdev, "%%BeginFeature: *Duplex DuplexTumble\n"); ! 243: if (pntpd->loszDuplexTumble) ! 244: pstr = (char *)pntpd + pntpd->loszDuplexTumble; ! 245: } ! 246: } ! 247: else if (pdev->psdm.dm.dmDuplex == DMDUP_VERTICAL) ! 248: { ! 249: if (pdev->psdm.dm.dmOrientation == DMORIENT_LANDSCAPE) ! 250: { ! 251: PrintString(pdev, "%%BeginFeature: *Duplex DuplexTumble\n"); ! 252: if (pntpd->loszDuplexTumble) ! 253: pstr = (char *)pntpd + pntpd->loszDuplexTumble; ! 254: } ! 255: else ! 256: { ! 257: PrintString(pdev, "%%BeginFeature: *Duplex DuplexNoTumble\n"); ! 258: if (pntpd->loszDuplexNoTumble) ! 259: pstr = (char *)pntpd + pntpd->loszDuplexNoTumble; ! 260: } ! 261: } ! 262: else // turn duplex off. ! 263: { ! 264: PrintString(pdev, "%%BeginFeature: *Duplex None\n"); ! 265: if (pntpd->loszDuplexNone) ! 266: pstr = (char *)pntpd + pntpd->loszDuplexNone; ! 267: } ! 268: ! 269: PrintString(pdev, pstr); ! 270: PrintString(pdev, "\n%%EndFeature\n"); ! 271: } ! 272: ! 273: // handle collation if the device supports it. ! 274: ! 275: if (pntpd->loszCollateOn && pntpd->loszCollateOff) ! 276: { ! 277: if (pdev->psdm.dm.dmCollate = DMCOLLATE_TRUE) ! 278: { ! 279: PrintString(pdev, "%%BeginFeature: *Collate True\n"); ! 280: pstr = (char *)pntpd + pntpd->loszCollateOn; ! 281: } ! 282: else ! 283: { ! 284: PrintString(pdev, "%%BeginFeature: *Collate False\n"); ! 285: pstr = (char *)pntpd + pntpd->loszCollateOff; ! 286: } ! 287: ! 288: PrintString(pdev, pstr); ! 289: PrintString(pdev, "\n%%EndFeature\n"); ! 290: } ! 291: ! 292: if (pdev->cCopies > 1) ! 293: { ! 294: PrintString(pdev, "/#copies "); ! 295: PrintDecimal(pdev, 1, pdev->cCopies); ! 296: PrintString(pdev, " def\n"); ! 297: } ! 298: ! 299: PrintString(pdev, "%%EndSetup\n%%Page: 1 1\n%%BeginPageSetup\n"); ! 300: ! 301: // the form / tray information has already been sent for the first page. ! 302: ! 303: pdev->dwFlags &= ~PDEV_CHANGEFORM; ! 304: ! 305: bSendDeviceSetup(pdev); ! 306: ! 307: PrintString(pdev, "%%EndPageSetup\n"); ! 308: ! 309: // output a save command for the first page. this is done in the ! 310: // header as part of the effort to avoid outputting two headers in ! 311: // the raw data case. FALSE means to perform a save and not a gsave. ! 312: ! 313: ps_save(pdev, FALSE); ! 314: pdev->dwFlags |= PDEV_WITHINPAGE; ! 315: ! 316: if (pdev->psdm.dwFlags & PSDEVMODE_NEG) ! 317: { ! 318: // fill the entire imageable area with white, which will get ! 319: // transformed to black. then restore the color to black. ! 320: ! 321: pbgr = RGB_WHITE; ! 322: ps_setrgbcolor(pdev, (BGR_PAL_ENTRY *)&pbgr); ! 323: ! 324: PrintDecimal(pdev, 4, 0, ! 325: (pdev->CurForm.imagearea.left * pdev->psdm.dm.dmScale) / 100, ! 326: (pdev->CurForm.sizlPaper.cy - ! 327: ((pdev->CurForm.imagearea.top * pdev->psdm.dm.dmScale) / 100)), ! 328: (pdev->CurForm.imagearea.right * pdev->psdm.dm.dmScale) / 100, ! 329: (pdev->CurForm.sizlPaper.cy - ! 330: ((pdev->CurForm.imagearea.bottom * pdev->psdm.dm.dmScale) / 100))); ! 331: ! 332: PrintString(pdev, " box\n"); ! 333: pdev->cgs.dwFlags |= CGS_PATHEXISTS; ! 334: ! 335: ps_fill(pdev, (FLONG)FP_WINDINGMODE); ! 336: pbgr = RGB_BLACK; ! 337: ps_setrgbcolor(pdev, (BGR_PAL_ENTRY *)&pbgr); ! 338: } ! 339: ! 340: pdev->dwFlags |= PDEV_COMPLETEHEADER; ! 341: ! 342: return(TRUE); ! 343: } ! 344: ! 345: ! 346: //-------------------------------------------------------------------------- ! 347: // BOOL bSendDeviceSetup(pdev) ! 348: // PDEVDATA pdev; ! 349: // ! 350: // This routine sends the driver's device setup section of the header ! 351: // to the output channel. ! 352: // ! 353: // Parameters: ! 354: // pdev: ! 355: // pointer to DEVDATA structure. ! 356: // ! 357: // Returns: ! 358: // This function returns TRUE if the header was successfully sent, ! 359: // FALSE otherwise. ! 360: // ! 361: // History: ! 362: // 26-Nov-1990 -by- Kent Settle (kentse) ! 363: // Wrote it. ! 364: //-------------------------------------------------------------------------- ! 365: ! 366: BOOL bSendDeviceSetup(pdev) ! 367: PDEVDATA pdev; ! 368: { ! 369: PSTR pstr; ! 370: PNTPD pntpd; ! 371: ! 372: // set up for new form if necessary. ! 373: ! 374: if (pdev->dwFlags & PDEV_CHANGEFORM) ! 375: { ! 376: SetFormAndTray(pdev); ! 377: pdev->dwFlags &= ~PDEV_CHANGEFORM; ! 378: } ! 379: ! 380: pntpd = pdev->pntpd; ! 381: ! 382: // rotate and translate if we are in landscape mode. ! 383: ! 384: if (pdev->psdm.dm.dmOrientation == DMORIENT_LANDSCAPE) ! 385: { ! 386: #ifdef LANDSCAPE_270_ROTATE ! 387: PrintString(pdev, "270 rotate "); ! 388: PrintDecimal(pdev, 2, -pdev->CurForm.sizlPaper.cx, 0); ! 389: PrintString(pdev, " translate\n"); ! 390: #else // 90 degree rotation case. ! 391: PrintString(pdev, "90 rotate "); ! 392: PrintDecimal(pdev, 2, 0, -pdev->CurForm.sizlPaper.cy); ! 393: PrintString(pdev, " translate\n"); ! 394: #endif ! 395: } ! 396: ! 397: // this implementation of mirror imaging is to simply flip over the ! 398: // x axis. ie, the image is reversed in the horizontal direction. ! 399: //!!! perhaps at some point we will want to allow flipping in the ! 400: //!!! vertical direction as well. -kentse. ! 401: ! 402: if (pdev->psdm.dwFlags & PSDEVMODE_MIRROR) ! 403: { ! 404: PrintDecimal(pdev, 1, pdev->CurForm.sizlPaper.cx); ! 405: PrintString(pdev, " 0 translate -1 1 scale\n"); ! 406: } ! 407: ! 408: // send the proper normalized transfer function, if one exists. ! 409: // send the inverted transfer function if the PSDEVMODE_NEG ! 410: // flag is set. ! 411: ! 412: if (pdev->psdm.dwFlags & PSDEVMODE_NEG) ! 413: { ! 414: // if an inverse normalized transfer function is defined for ! 415: // this device, send it to the printer, else send the default ! 416: // inverse transfer function. ! 417: ! 418: if (pntpd->loszInvTransferNorm) ! 419: { ! 420: pstr = (char *)pntpd + pntpd->loszInvTransferNorm; ! 421: PrintString(pdev, pstr); ! 422: } ! 423: else // default inverse transfer function. ! 424: PrintString(pdev, "{1 exch sub}"); ! 425: ! 426: PrintString(pdev, " settransfer\n"); ! 427: } ! 428: else ! 429: { ! 430: // send the normalized transfer function to the printer if ! 431: // one exists for this printer. ! 432: ! 433: if (pntpd->loszTransferNorm) ! 434: { ! 435: pstr = (char *)pntpd + pntpd->loszTransferNorm; ! 436: PrintString(pdev, pstr); ! 437: PrintString(pdev, " settransfer\n"); ! 438: } ! 439: } ! 440: ! 441: // set the default line width (8 / 1000th inch). ! 442: ! 443: pdev->cgs.psfxLineWidth = 0; // force the linewidth to be set. ! 444: ps_setlinewidth(pdev, PSFX_DEFAULT_LINEWIDTH); ! 445: ! 446: return(TRUE); ! 447: } ! 448: ! 449: //-------------------------------------------------------------------- ! 450: // BOOL bSendPSProcSet(pdev, ulPSid) ! 451: // PDEVDATA pdev; ! 452: // ULONG ulPSid; ! 453: // ! 454: // Routine Description: ! 455: // ! 456: // This routine will output the PS Procset Resource referenced by ulPSid ! 457: // to the PS Interpreter. See PSPROC.H for valid ids. ! 458: // ! 459: // Return Value: ! 460: // ! 461: // FALSE if an error occurred. ! 462: // ! 463: // Author: ! 464: // ! 465: // 15-Feb-1993 created -by- Rob Kiesler ! 466: // ! 467: // ! 468: // Revision History: ! 469: //-------------------------------------------------------------------- ! 470: ! 471: BOOL bSendPSProcSet(pdev, ulPSid) ! 472: PDEVDATA pdev; ! 473: ULONG ulPSid; ! 474: { ! 475: HANDLE hRes; ! 476: USHORT usSize; ! 477: HANDLE hProcRes; ! 478: PSZ pntps; ! 479: ! 480: if (pdev->dwFlags & PDEV_CANCELDOC) ! 481: return(TRUE); ! 482: ! 483: if (!(hRes = FindResource(ghmodDrv, MAKEINTRESOURCE(ulPSid), ! 484: MAKEINTRESOURCE(PSPROC)))) ! 485: { ! 486: RIP("PSCRIPT!bSendPSProcSet: Couldn't find proc set resource\n"); ! 487: return(FALSE); ! 488: } ! 489: ! 490: usSize = (USHORT)SizeofResource(ghmodDrv, hRes); ! 491: ! 492: // ! 493: // Get the handle to the resource. ! 494: // ! 495: if (!(hProcRes = LoadResource(ghmodDrv, hRes))) ! 496: { ! 497: RIP("PSCRIPT!bSendPSProcSet: LoadResource failed.\n"); ! 498: return(FALSE); ! 499: } ! 500: ! 501: // ! 502: // Get a pointer to the resource data. ! 503: // ! 504: if (!(pntps = (PSZ) LockResource(hProcRes))) ! 505: { ! 506: RIP("PSCRIPT!bSendPSProcSet: LockResource failed.\n"); ! 507: FreeResource(hProcRes); ! 508: return(FALSE); ! 509: } ! 510: if (!bPSWrite(pdev, pntps, usSize)) ! 511: { ! 512: RIP("PSCRIPT!bSendPSProcSet: Output of Header failed.\n"); ! 513: FreeResource(hProcRes); ! 514: return(FALSE); ! 515: } ! 516: ! 517: FreeResource(hProcRes); ! 518: bPSFlush(pdev); ! 519: return(TRUE); ! 520: } ! 521: ! 522: ! 523: //-------------------------------------------------------------------------- ! 524: // VOID DownloadNTProcSet(pdev, bEhandler) ! 525: // PDEVDATA pdev; ! 526: // BOOL bEhandler; ! 527: // ! 528: // This routine sends the driver's ProcSet to the output channel. ! 529: // ! 530: // Parameters: ! 531: // pdev: ! 532: // pointer to DEVDATA structure. ! 533: // ! 534: // bEhandler: ! 535: // TRUE if we should even consider sending the error handler, ! 536: // otherwise FALSE. ! 537: // ! 538: // Returns: ! 539: // This function returns no value. ! 540: // ! 541: // History: ! 542: // 11-May-1993 -by- Kent Settle (kentse) ! 543: // Broke into a separate routine. ! 544: //-------------------------------------------------------------------------- ! 545: ! 546: VOID DownloadNTProcSet(pdev, bEhandler) ! 547: PDEVDATA pdev; ! 548: BOOL bEhandler; ! 549: { ! 550: PSZ *ppsz; ! 551: ! 552: // define our procedure set. ! 553: ! 554: PrintString(pdev, "%%BeginProcSet: Windows_NT_3.1\n"); ! 555: PrintString(pdev, "% Copyright (c) 1991 - 1993 Microsoft Corporation\n"); ! 556: ! 557: // we need to define the true resolution of the printer. ! 558: ! 559: PrintString(pdev, "100 dict begin "); ! 560: PrintString(pdev, "/DPI "); ! 561: PrintDecimal(pdev, 1, pdev->psdm.dm.dmPrintQuality); ! 562: PrintString(pdev, " def\n"); ! 563: ! 564: PrintString(pdev, "/_snap {transform 36 DPI div sub round 36 DPI div add\n"); ! 565: PrintString(pdev, "exch 36 DPI div sub round 36 DPI div add exch itransform}bind def\n"); ! 566: ! 567: // download our error handler if we are told to. ! 568: ! 569: if (bEhandler) ! 570: { ! 571: if (pdev->psdm.dwFlags & PSDEVMODE_EHANDLER) ! 572: { ! 573: ppsz = apszEHandler; ! 574: while (*ppsz) ! 575: { ! 576: PrintString(pdev, (PSZ)*ppsz++); ! 577: PrintString(pdev, "\n"); ! 578: } ! 579: } ! 580: } ! 581: // download our procedure definitions code. ! 582: ! 583: ppsz = apszHeader; ! 584: while (*ppsz) ! 585: { ! 586: PrintString(pdev, (PSZ)*ppsz++); ! 587: PrintString(pdev, "\n"); ! 588: } ! 589: ! 590: PrintString(pdev, "%%EndProcSet\n"); ! 591: ! 592: pdev->dwFlags |= PDEV_PROCSET; ! 593: } ! 594: ! 595: ! 596: VOID SetFormAndTray(pdev) ! 597: PDEVDATA pdev; ! 598: { ! 599: WCHAR FormName[CCHFORMNAME]; ! 600: WCHAR *pFormName; ! 601: WCHAR *pSlotName; ! 602: WCHAR *pPrinterForm; ! 603: WCHAR ManualName[MAX_SLOT_NAME]; ! 604: WCHAR SearchName[MAX_SLOT_NAME]; ! 605: BOOL bManual, bForm, bFound, bRegion; ! 606: WCHAR *pwstr; ! 607: PSINPUTSLOT *pSlot; ! 608: DWORD i; ! 609: PSFORM *pPSForm; ! 610: PNTPD pntpd; ! 611: ! 612: pntpd = pdev->pntpd; ! 613: ! 614: // select the paper tray. do this by selecting the first tray ! 615: // which contains the form in question. ! 616: ! 617: // get a unicode version of the form name. ! 618: ! 619: strcpy2WChar(FormName, pdev->CurForm.PrinterForm); ! 620: ! 621: // get the manual tray name. ! 622: ! 623: LoadString(ghmodDrv, (SLOT_MANUAL + SLOTS_BASE), ! 624: ManualName, (sizeof(ManualName) / sizeof(ManualName[0]))); ! 625: ! 626: // assume the form is not in manual feed. ! 627: ! 628: if (pdev->dwFlags & PDEV_MANUALFEED) ! 629: { ! 630: PrintString(pdev, "%%BeginFeature: *ManualFeed False\n"); ! 631: PrintString(pdev, (CHAR *)pntpd + pntpd->loszManualFeedFALSE); ! 632: PrintString(pdev, "\n%%EndFeature\n"); ! 633: pdev->dwFlags &= ~PDEV_MANUALFEED; ! 634: } ! 635: ! 636: bManual = FALSE; ! 637: ! 638: // we have the form name, now check the registry to see if this form ! 639: // is in any of the paper trays. ! 640: ! 641: if (pdev->pTrayFormTable) ! 642: { ! 643: pwstr = pdev->pTrayFormTable; ! 644: bForm = FALSE; ! 645: ! 646: while (*pwstr) ! 647: { ! 648: pSlotName = pwstr; ! 649: pFormName = pSlotName + (wcslen(pSlotName) + 1); ! 650: pPrinterForm = pFormName + (wcslen(pFormName) + 1); ! 651: ! 652: if (!(wcscmp(pPrinterForm, FormName))) ! 653: { ! 654: // we found the form question. get the tray name. ! 655: ! 656: if (!(wcscmp(pSlotName, ManualName))) ! 657: { ! 658: // the form is in the manual tray, but see if it is ! 659: // one of the other trays first. ! 660: ! 661: bManual = TRUE; ! 662: ! 663: pwstr = pPrinterForm + (wcslen(pPrinterForm) + 1); ! 664: } ! 665: else ! 666: { ! 667: bForm = TRUE; ! 668: break; ! 669: } ! 670: } ! 671: else ! 672: { ! 673: // this was not the form in question. skip over the ! 674: // tray-form triplet. ! 675: ! 676: pwstr = pPrinterForm + (wcslen(pPrinterForm) + 1); ! 677: } ! 678: } ! 679: ! 680: // if the tray-form pair was found, output the proper commands ! 681: // to select the tray in question. ! 682: ! 683: bFound = FALSE; ! 684: ! 685: if (bForm) ! 686: { ! 687: // select the tray if there are multiple trays to select from. ! 688: ! 689: if (pntpd->cInputSlots > 0) ! 690: { ! 691: pSlot = (PSINPUTSLOT *)((CHAR *)pntpd + pntpd->loPSInputSlots); ! 692: ! 693: // get each slot name from the NTPD, and do a look up in the ! 694: // registry to find the associated form name. ! 695: ! 696: for (i = 0; i < pntpd->cInputSlots; i++) ! 697: { ! 698: strcpy2WChar(SearchName, (CHAR *)pntpd + pSlot->loSlotName); ! 699: ! 700: if (!(wcscmp(pSlotName, SearchName))) ! 701: { ! 702: bFound = TRUE; ! 703: break; ! 704: } ! 705: ! 706: pSlot++; ! 707: } ! 708: ! 709: if (bFound) ! 710: { ! 711: PrintString(pdev, "%%BeginFeature: *InputSlot "); ! 712: PrintString(pdev, (CHAR *)pntpd + pSlot->loSlotName); ! 713: PrintString(pdev, "\n"); ! 714: ! 715: PrintString(pdev, (CHAR *)pntpd + pSlot->loSlotInvo); ! 716: PrintString(pdev, "\n%%EndFeature\n"); ! 717: } ! 718: } ! 719: ! 720: } ! 721: ! 722: // if the form was not found in one of the paper trays, and the printer ! 723: // supports manual feed, see if the form is is the manual feed slot. ! 724: ! 725: if ((!bFound) && (pntpd->loszManualFeedTRUE != 0) && (bManual)) ! 726: { ! 727: // the requested form is in the manual feed slot, ! 728: // so select manual feed. ! 729: ! 730: PrintString(pdev, "%%BeginFeature: *ManualFeed True\n"); ! 731: PrintString(pdev, (CHAR *)pntpd + pntpd->loszManualFeedTRUE); ! 732: PrintString(pdev, "\n%%EndFeature\n"); ! 733: pdev->dwFlags |= PDEV_MANUALFEED; ! 734: } ! 735: } ! 736: ! 737: // select the page region if we are also selecting from multiple ! 738: // paper trays or manual feed, otherwise select page size. ! 739: ! 740: bRegion = FALSE; ! 741: ! 742: if ((pdev->dwFlags & PDEV_MANUALFEED) || (bFound)) ! 743: bRegion = TRUE; ! 744: ! 745: // check for the odd occurence where there are no PageRegions (WANG15FP.PPD). ! 746: ! 747: // find the PSFORM structure in the NTPD for the current form. ! 748: ! 749: pPSForm = (PSFORM *)((CHAR *)pntpd + pntpd->loPSFORMArray); ! 750: ! 751: if (!pntpd->cPageRegions) ! 752: bRegion = FALSE; ! 753: ! 754: if (bRegion) ! 755: PrintString(pdev, "%%BeginFeature: *PageRegion "); ! 756: else ! 757: PrintString(pdev, "%%BeginFeature: *PageSize "); ! 758: ! 759: PrintString(pdev, pdev->CurForm.PrinterForm); ! 760: PrintString(pdev, "\n"); ! 761: ! 762: pPSForm = (PSFORM *)((CHAR *)pntpd + pntpd->loPSFORMArray); ! 763: ! 764: for (i = 0; i < pntpd->cPSForms; i++) ! 765: { ! 766: if (!(NameComp((CHAR *)pdev->CurForm.PrinterForm, ! 767: (CHAR *)pntpd + pPSForm->loFormName))) ! 768: { ! 769: if (bRegion) ! 770: PrintString(pdev, (CHAR *)pntpd + pPSForm->loRegionInvo); ! 771: else ! 772: PrintString(pdev, (CHAR *)pntpd + pPSForm->loSizeInvo); ! 773: ! 774: PrintString(pdev, "\n"); ! 775: break; ! 776: } ! 777: ! 778: // point to the next PSFORM. ! 779: ! 780: pPSForm++; ! 781: } ! 782: ! 783: PrintString(pdev, "%%EndFeature\n"); ! 784: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.