home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / print / prtf / prtf.c < prev    next >
Text File  |  1993-09-07  |  15KB  |  507 lines

  1. /*
  2.  
  3. print a text file.
  4.  
  5. */
  6.  
  7. #pragma strings(readonly)
  8. #define INCL_DEV
  9. #define INCL_WIN
  10. #define INCL_GPI
  11. #define INCL_SPL
  12. #define INCL_SPLDOSPRINT
  13. #define INCL_WINERRORS
  14. #define INCL_GPIERRORS
  15. #define INCL_ERRORS
  16. #include <os2.h>
  17.  
  18. /* c language includes */
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22.  
  23. int main(int argc,char *argv[]);
  24.  
  25. #define PATHNAME_LENGTH    261
  26.  
  27. /* limitation of character string graphic order */
  28. #define MAX_OUTPUT_BUFFER 255
  29. #define MAX_INPUT_BUFFER 4096
  30.  
  31. UCHAR input_buffer[MAX_INPUT_BUFFER];
  32. UCHAR output_buffer[MAX_OUTPUT_BUFFER];
  33. FONTMETRICS fm;
  34. ERRORID erridErrorCode;
  35. HAB hab;                      /* PM anchor block handle       */
  36. HDC hdc;              /* Device-context handle for the queue  */
  37. HPS hps;              /* presentation space handle */
  38. DEVOPENSTRUC dos;     /* description of the queue */
  39. FATTRS fat;
  40. LONG l;
  41. USHORT jobno;
  42. ULONG n,linefeed,tab,selection=0,copies=1,pageno=0,output_buffer_l=0,input_buffer_e=0,input_buffer_b=0;
  43. double pointsize=12.0;
  44. UCHAR this_char;
  45. APIRET rc;
  46. CHAR szDocName[PATHNAME_LENGTH],*pszDeviceName,*pszQueueName=NULL,
  47.   *pszFaceName="Courier",*pszToken = "*",*pszSpoolerParms=NULL;
  48. SIZEL sizel={0,0};
  49. //GRADIENTL gradlAngle={0L,0L};
  50. SIZEF sizfCharBox; /* Character-box size in world coordinates.     */
  51. POINTL pt;                        /* String screen coordinates    */
  52. HFILE FHandle;           /* DosOpen file handle */
  53. UCHAR prq3_buffer[2048];
  54. #define prq3 (*(PPRQINFO3)(PVOID)prq3_buffer)
  55. // PRQINFO3 prq3; /* it wants more storage ... */
  56. INT marginflag=0;
  57. LONG widths[256];   /* array of character width values */
  58.  
  59. int main(int argc,char *argv[])
  60. {
  61.  
  62.    if (0==(hab = WinInitialize( 0 )))
  63.        {
  64.        printf("WinInitialize failed\n");
  65.        goto cleanup;
  66.        }
  67.  
  68.   if (argc<2)
  69.      {
  70.      printf("Syntax: prtf file [-q queue] [-p pointsize] [-f \"Face name\"] [other options]\n");
  71.      goto cleanup;
  72.      }
  73.  
  74.     /* recognize the arguments (dirty hack) */
  75.     n=2;
  76. recargs:
  77.     if (n>=argc) goto endargs;
  78.     if (0==strcmp(argv[n],"-i"))
  79.      selection+=FATTR_SEL_ITALIC;
  80.     else if (0==strcmp(argv[n],"-u"))
  81.      selection+=FATTR_SEL_UNDERSCORE;
  82.     else if (0==strcmp(argv[n],"-b"))
  83.      selection+=FATTR_SEL_BOLD;
  84.     else if (0==strcmp(argv[n],"-s"))
  85.      selection+=FATTR_SEL_STRIKEOUT;
  86.     else if (0==strcmp(argv[n],"-o"))
  87.      selection+=FATTR_SEL_OUTLINE;
  88.     else if (n<argc-1)
  89.      {
  90.     if (0==strcmp(argv[n],"-f"))
  91.      {
  92.      n++;
  93.      pszFaceName=argv[n];
  94.      }
  95.     else if (0==strcmp(argv[n],"-q"))
  96.      {
  97.      n++;
  98.      pszQueueName=argv[n];
  99.      }
  100.     else if (0==strcmp(argv[n],"-p"))
  101.      {
  102.      n++;
  103.      pointsize=atof(argv[n]);
  104.      }
  105.     else if (0==strcmp(argv[n],"-c"))
  106.      {
  107.      n++;
  108.      copies=atoi(argv[n]);
  109.      }
  110.     else if (0==strcmp(argv[n],"-a"))
  111.      {
  112.      n++;
  113.      pszSpoolerParms=argv[n];
  114.      }
  115.     }
  116.    else
  117.      {
  118.      printf("Bad parameter %s\n",argv[n]);
  119.      goto cleanup;
  120.      }
  121.      n++;
  122.      goto recargs;
  123. misargs:
  124.      printf("Missing parameter after %s\n",argv[n-1]);
  125.      goto cleanup;
  126. endargs:
  127.  
  128.       /* open the input file */
  129.     if (0!=(rc=DosQueryPathInfo(argv[1], 5, &szDocName,
  130.                              sizeof(szDocName))))
  131.        {
  132.        printf("DosQueryPathInfo failed\n");
  133.        goto cleanup;
  134.        }
  135.  
  136.       if (0!=(rc=DosOpen(szDocName, &FHandle,
  137.                           &n, 0, FILE_NORMAL,
  138.                           FILE_OPEN,
  139.                            OPEN_FLAGS_SEQUENTIAL+
  140.                            OPEN_SHARE_DENYWRITE+
  141.                            OPEN_ACCESS_READONLY,
  142.                           NULL)))
  143.        {
  144.        printf("DosOpen failed\n");
  145.        goto cleanup;
  146.        }
  147.  
  148.      if (pszQueueName==NULL)
  149.       {
  150.        /* get default queue from os2.ini */
  151.    pszQueueName=output_buffer;
  152.    if (0==PrfQueryProfileString(HINI_PROFILE,
  153.                             (PSZ)"PM_SPOOLER",
  154.                             (PSZ)"QUEUE",
  155.                              NULL,
  156.                             (PSZ)pszQueueName,
  157.                             (LONG)sizeof(output_buffer)
  158.                             ))
  159.         {
  160.         printf("No default queue defined: please define one or use the -q option\n");
  161.         goto cleanup;
  162.         }
  163.      if (NULL!=(pszDeviceName=strchr(pszQueueName,';')))
  164.       {
  165.       *pszDeviceName='\0';
  166.       }
  167.       }
  168.  
  169.      if (0!=(rc=SplQueryQueue((PVOID)NULL, pszQueueName, 3L,
  170.                                  &prq3, sizeof(prq3_buffer), &n)))
  171.        {
  172.        printf("SplQueryQueue failed\n");
  173.        goto cleanup;
  174.        }
  175.  
  176. /* this not needed for spl calls, but needed for dev */
  177. #ifndef never
  178.      if (NULL!=(pszDeviceName=strchr(prq3.pszPrinters,',')))
  179.       {
  180.       *pszDeviceName='\0';
  181.       }
  182.      if (NULL!=(pszDeviceName=strchr(prq3.pszDriverName,'.')))
  183.       {
  184.       *pszDeviceName='\0';
  185.       pszDeviceName++;
  186.       }
  187.      else
  188.       pszDeviceName="";
  189.  
  190.    if (DEV_OK!=(n = DevPostDeviceModes( hab,
  191.                            prq3.pDriverData,
  192.                            prq3.pszDriverName,
  193.                            pszDeviceName,
  194.                            prq3.pszPrinters,
  195.                            DPDM_QUERYJOBPROP )))
  196.        {
  197.        printf("DevPostDeviceModes failed %d:\n",n);
  198.        goto cleanup;
  199.        }
  200.  
  201. #endif
  202.  
  203.     printf("queue name='%s' driver='%s' device='%s' printer='%s'\n",
  204.     prq3.pszName,prq3.pszDriverName,pszDeviceName,prq3.pszPrinters);
  205. //  (*(prq3.pDriverData)).szDeviceName,
  206. //  (*(prq3.pDriverData)).lVersion);
  207.  
  208.     memset( &dos,   0, sizeof(dos));
  209.      dos.pszLogAddress      = prq3.pszName;           /* queue name */
  210.      dos.pszDriverName      = prq3.pszDriverName;
  211.      dos.pdriv              = prq3.pDriverData;
  212.      dos.pszDataType        = "PM_Q_STD";  /* RAW if using Spl calls */
  213.      dos.pszComment         = szDocName;
  214.      dos.pszQueueProcName   = prq3.pszPrProc;
  215.      sprintf(output_buffer,"MAP=N COP=%d",copies);
  216.      dos.pszQueueProcParams=output_buffer;
  217.      dos.pszSpoolerParams   = pszSpoolerParms;
  218. //   dos.pszNetworkParams   = NULL;
  219.  
  220. #ifdef never
  221.        /* corresponds to DevOpenDc */
  222.      hspl = SplQmOpen(pszToken,8,(PQMOPENDATA)&dos);
  223.  
  224.      if ( hspl != SPL_ERROR )        /* Good spooler handle */
  225.      {
  226.         printf("SplQmOpen handle is %d\n",hspl);
  227.      }
  228.      else
  229.      {
  230.         printf("SplQmOpen failed.\n");
  231.         goto cleanup;
  232.      }
  233. #endif
  234.  
  235.  /* create device context for the queue */
  236.    if (DEV_ERROR==( hdc = DevOpenDC(hab, OD_QUEUED, pszToken, 8, (void*)&dos, NULLHANDLE)))
  237.        {
  238.        printf("DevOpenDC failed\n");
  239.        goto cleanup;
  240.        }
  241.  
  242. #ifdef never
  243.     SplQmStartDoc(hspl,szDocName);
  244. #endif
  245.  
  246.          /* Issue STARTDOC to begin printing */
  247.     if (DEV_OK!=(n=DevEscape( hdc,
  248.                     DEVESC_STARTDOC,
  249.                     (int)strlen(szDocName),
  250.                     szDocName,
  251.                     (PLONG)NULL, (PBYTE)NULL)))
  252.        {
  253.        printf("DevEscape STARTDOC failed:\n");
  254.        goto cleanup;
  255.        }
  256.  
  257.  /* create a presentation space associated with the context */
  258.  
  259.  if (0==(hps = GpiCreatePS(hab, hdc,
  260.  &sizel, /* use same page size as device */
  261.  PU_TWIPS+GPIF_LONG+GPIT_NORMAL+GPIA_ASSOC)))
  262.        {
  263.        printf("GpiCreatePS failed:\n");
  264.        goto cleanup;
  265.        }
  266.  
  267.  GpiSetAttrMode(hps,AM_NOPRESERVE);
  268.  GpiQueryPS(hps, &sizel);
  269.  
  270.  GpiSetCharMode(hps,CM_MODE2);
  271.  GpiSetColor(hps,CLR_DEFAULT );
  272.  
  273. /* select a font */
  274.  memset(&fat,0,sizeof(fat)); /* defaults */
  275.  strcpy(fat.szFacename,pszFaceName);
  276.  fat.usRecordLength=sizeof(fat);
  277.  fat.fsSelection=selection;
  278.  fat.fsFontUse = FATTR_FONTUSE_NOMIX/*+FATTR_FONTUSE_OUTLINE+FATTR_FONTUSE_TRANSFORMABLE*/;
  279. /* 0 for scalable font */
  280.  fat.lMaxBaselineExt=fat.lAveCharWidth=pointsize;
  281.  
  282.    if (FONT_MATCH!=(n=GpiCreateLogFont(hps,
  283.                                  (PSTR8)NULL,
  284.                                  1L,
  285.                                  &fat)))
  286.       {
  287.       if (n==FONT_DEFAULT)
  288.        printf("Unable to match the typeface\n");
  289.       else
  290.        printf("GpiCreateLogFont failed: %d\n",n);
  291.       goto cleanup;
  292.       }
  293.  
  294.   GpiSetCharSet(hps, 1L );
  295. //GpiSetCharAngle(hps,&gradlAngle);
  296.   sizfCharBox.cx = (LONG)(pointsize*20*65536); /* translate to twips and fix */
  297.   sizfCharBox.cy = (LONG)(pointsize*20*65536);
  298.   GpiSetCharBox(hps,&sizfCharBox);
  299.  
  300.   GpiQueryFontMetrics(hps, sizeof(FONTMETRICS), &fm);
  301.  
  302.    printf("font family='%s' face='%s' at %gpt\n",
  303.    fm.szFamilyname,fm.szFacename,fm.lEmHeight/20.0);
  304.  
  305.    /* figure out how much tab and line feed are in this font */
  306.    tab=fm.lAveCharWidth*8;
  307.    linefeed=fm.lExternalLeading+fm.lMaxBaselineExt;
  308.  
  309.   /* retrieve character width table */
  310.    rc=GpiQueryWidthTable(hps,
  311.                     0,
  312.                     255,
  313.                     widths);
  314.  
  315.  
  316. home:
  317.       pageno++;
  318.       printf("Page %d\n",pageno);
  319.       pt.x = 0; pt.y = sizel.cy-linefeed;
  320. locate:
  321.       if (output_buffer_l)
  322.        {
  323.        n=GpiCharString(hps, output_buffer_l, output_buffer);
  324.       if (n!=GPI_OK)
  325.          {
  326.          printf("CharString failed:\n");
  327.          goto cleanup;
  328.          }
  329.        output_buffer_l=0;
  330.        }
  331.       if (pt.y<0)
  332.        {
  333.          DevEscape( hdc,
  334.                     DEVESC_NEWFRAME,
  335.                     0L,
  336.                     (PBYTE)NULL,
  337.                     (PLONG)NULL,
  338.                     (PBYTE)NULL );
  339.        goto home;
  340.        }
  341.       n=GpiMove(hps, &pt );
  342.      if (n!=GPI_OK)
  343.        {
  344.        printf("Move failed:\n");
  345.        goto cleanup;
  346.        }
  347.       if (marginflag) goto normargin; /* reprint char that wrapped around */
  348. q_loop:
  349.   if (input_buffer_b<input_buffer_e) goto noread;
  350.   if ((rc=DosRead(FHandle, &input_buffer,
  351.            sizeof(input_buffer), &input_buffer_e)) != 0)
  352.        {
  353.        printf("DosRead failed\n");
  354.        goto cleanup;
  355.        }
  356.    if (input_buffer_e==0) goto eof;
  357.    input_buffer_b=0;
  358. noread:
  359.    this_char=input_buffer[input_buffer_b];
  360.    input_buffer_b++;
  361. /* see if it's a control char */
  362.    if (this_char!=13) goto notcr;
  363.     pt.x=0;
  364.     goto locate;
  365. notcr:
  366.    if (this_char!=10) goto notlf;
  367.    pt.y-=linefeed;
  368.    goto locate;
  369. notlf:
  370.    if (this_char!=9) goto nottab;
  371.    pt.x=(pt.x/tab+1)*tab;
  372.    goto locate;
  373. nottab:
  374.    if (this_char!=8) goto notbs;
  375.    pt.x-=widths[' '];
  376.    if (pt.x<0)
  377.     pt.x=0;
  378.    goto locate;
  379. notbs:
  380.    if (this_char!=12) goto notff;
  381.    pt.y=-1; /* force form feed */
  382.    goto locate;
  383. notff:
  384. /* get its width */
  385.   if (widths[this_char]>=sizel.cx)
  386.    {
  387.    printf("Character %c does not fit on the page\n",this_char);
  388.    goto cleanup;
  389.    }
  390.   if (pt.x+widths[this_char]<sizel.cx) goto normargin;
  391.     pt.x=0;  /* on wraparound simulate cr and lf */
  392.     pt.y-=linefeed;
  393.     marginflag=1;
  394.     goto locate;
  395. normargin:
  396.     marginflag=0;
  397.     output_buffer[output_buffer_l]=this_char;
  398.     output_buffer_l++;
  399.     pt.x+=widths[this_char];
  400.     if (output_buffer_l>=MAX_OUTPUT_BUFFER) goto locate;
  401.   /* fall thru */
  402.     goto q_loop;  /* really always */
  403.  
  404. eof:
  405.        DosClose(FHandle);
  406.  
  407.       if (output_buffer_l)
  408.        {
  409.        n=GpiCharString(hps, output_buffer_l, output_buffer);
  410.       if (n!=GPI_OK)
  411.          {
  412.          printf("CharString failed:\n");
  413.          goto cleanup;
  414.          }
  415.        }
  416.  
  417. #ifdef never
  418.    SplQmWrite(hspl, n, FileBuffer);
  419.  
  420.    n = SplQmEndDoc(hspl);
  421.  
  422.    printf("Job id is %d\n",n);
  423. #endif
  424.  
  425.     /* close the document */
  426.      l=2;
  427.      n=  DevEscape(hdc,
  428.                    DEVESC_ENDDOC,
  429.                     0L, (PBYTE)NULL, &l, (PBYTE)&jobno);
  430.     if (DEV_OK!=n)
  431.        {
  432.        printf("DevEscape ENDDOC failed: %d\n",l);
  433.        }
  434.    if (l==2)
  435.     printf("Job id is %d\n",(int)jobno);
  436.  
  437.     /* discard presentation space */
  438. //     GpiAssociate(hps, (HDC)NULLHANDLE );
  439.          GpiDestroyPS(hps);
  440.  
  441.     /* discard device context */
  442.     DevCloseDC(hdc);
  443.  
  444. #ifdef never
  445.     SplQmClose(hspl);
  446. #endif
  447.  
  448. cleanup:
  449.  
  450.  if (0!=(erridErrorCode = WinGetLastError(hab)))
  451.    {
  452.    printf("WinGetLastError=%x\n",erridErrorCode);
  453.  
  454. switch (erridErrorCode&0xFFFF) {
  455. case PMERR_DC_IS_ASSOCIATED: printf("Device context is associated.\n"); break;
  456. case PMERR_ESC_CODE_NOT_SUPPORTED: printf("Escape code is not supported on DevEscape\n"); break;
  457. case PMERR_FONT_AND_MODE_MISMATCH: printf("Font and mode mismatch.\n"); break;
  458. case PMERR_INV_DC_DATA: printf("Invalid data on DevOpenDC.\n"); break;
  459. case PMERR_INV_DC_TYPE: printf("Invalid type parameter on DevOpenDC.\n"); break;
  460. case PMERR_INV_DRIVER_NAME: printf("Invalid driver name.\n"); break;
  461. case PMERR_INV_ESCAPE_DATA: printf("Invalid data on DevEscape.\n"); break;
  462. case PMERR_DEV_FUNC_NOT_INSTALLED: printf("Device function not supported by presentation driver.\n"); break;
  463. case PMERR_INV_HDC: printf("Invalid device-context handle.\n"); break;
  464. case PMERR_INV_HPS: printf("Invalid presentation-space handle.\n"); break;
  465. case PMERR_NOT_IN_IDX: printf("Name not found, possible forms mismatch.\n"); break;
  466. case PMERR_INV_LENGTH_OR_COUNT: printf("Invalid length or count.\n"); break;
  467. case PMERR_INV_LOGICAL_ADDRESS: printf("An invalid device logical address.\n"); break;
  468. case PMERR_INV_OR_INCOMPAT_OPTIONS: printf("An invalid or incompatible presentation space options.\n"); break;
  469. case PMERR_INV_PS_SIZE: printf("Invalid size for presentation space.\n"); break;
  470. case PMERR_PS_BUSY: printf("Presentation space is busy.\n"); break;
  471. case PMERR_SPL_PRINT_ABORT: printf("Spooler print job has been aborted or redirected to a file.\n"); break;
  472.   }
  473.   }
  474.  
  475.   if (rc!=0)
  476.    {
  477.    printf("RetCode=%d\n",rc);
  478.    switch(rc) {
  479. case ERROR_ACCESS_DENIED: printf("Access is denied.\n"); break;
  480. case ERROR_BAD_NETPATH: printf("The network path cannot be located.\n"); break;
  481. case ERROR_BUFFER_OVERFLOW: printf("Buffer overflow.\n"); break;
  482. case ERROR_DEVICE_IN_USE: printf("Device in use.\n"); break;
  483. case ERROR_DRIVE_LOCKED: printf("Drive locked.\n"); break;
  484. case ERROR_FILE_NOT_FOUND: printf("File not found.\n"); break;
  485. case ERROR_FILENAME_EXCED_RANGE: printf("Filename exceedes range.\n"); break;
  486. case ERROR_INVALID_ACCESS: printf("Invalid access.\n"); break;
  487. case ERROR_INVALID_PARAMETER: printf("Invalid parameter.\n"); break;
  488. case ERROR_MORE_DATA: printf("Additional data is available, buffer to small.\n"); break;
  489. case ERROR_NOT_DOS_DISK: printf("Not a DOS disk.\n"); break;
  490. case ERROR_NOT_SUPPORTED: printf("Request not supported by the network.\n"); break;
  491. case ERROR_OPEN_FAILED: printf("Open failed / file not found.\n"); break;
  492. case ERROR_PATH_NOT_FOUND: printf("Path not found.\n"); break;
  493. case ERROR_SHARING_BUFFER_EXCEEDED: printf("Sharing buffer exceeded.\n"); break;
  494. case ERROR_SHARING_VIOLATION: printf("Sharing violation.\n"); break;
  495. case ERROR_TOO_MANY_OPEN_FILES: printf("Too many open files.\n"); break;
  496. case 2150: printf("The printer queue does not exist.\n"); break;
  497. case 2161: printf("The spooler is not running.\n"); break;
  498.    }
  499.    }
  500.  
  501.  
  502.   WinTerminate(hab);                   /* Terminate the application    */
  503.  
  504. return(TRUE);
  505. }
  506.  
  507.