Annotation of ntddk/src/print/pscript/header.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.