home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Professional
/
OS2PRO194.ISO
/
os2
/
print
/
prtf
/
prtf.c
< prev
next >
Wrap
Text File
|
1993-09-07
|
15KB
|
507 lines
/*
print a text file.
*/
#pragma strings(readonly)
#define INCL_DEV
#define INCL_WIN
#define INCL_GPI
#define INCL_SPL
#define INCL_SPLDOSPRINT
#define INCL_WINERRORS
#define INCL_GPIERRORS
#define INCL_ERRORS
#include <os2.h>
/* c language includes */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc,char *argv[]);
#define PATHNAME_LENGTH 261
/* limitation of character string graphic order */
#define MAX_OUTPUT_BUFFER 255
#define MAX_INPUT_BUFFER 4096
UCHAR input_buffer[MAX_INPUT_BUFFER];
UCHAR output_buffer[MAX_OUTPUT_BUFFER];
FONTMETRICS fm;
ERRORID erridErrorCode;
HAB hab; /* PM anchor block handle */
HDC hdc; /* Device-context handle for the queue */
HPS hps; /* presentation space handle */
DEVOPENSTRUC dos; /* description of the queue */
FATTRS fat;
LONG l;
USHORT jobno;
ULONG n,linefeed,tab,selection=0,copies=1,pageno=0,output_buffer_l=0,input_buffer_e=0,input_buffer_b=0;
double pointsize=12.0;
UCHAR this_char;
APIRET rc;
CHAR szDocName[PATHNAME_LENGTH],*pszDeviceName,*pszQueueName=NULL,
*pszFaceName="Courier",*pszToken = "*",*pszSpoolerParms=NULL;
SIZEL sizel={0,0};
//GRADIENTL gradlAngle={0L,0L};
SIZEF sizfCharBox; /* Character-box size in world coordinates. */
POINTL pt; /* String screen coordinates */
HFILE FHandle; /* DosOpen file handle */
UCHAR prq3_buffer[2048];
#define prq3 (*(PPRQINFO3)(PVOID)prq3_buffer)
// PRQINFO3 prq3; /* it wants more storage ... */
INT marginflag=0;
LONG widths[256]; /* array of character width values */
int main(int argc,char *argv[])
{
if (0==(hab = WinInitialize( 0 )))
{
printf("WinInitialize failed\n");
goto cleanup;
}
if (argc<2)
{
printf("Syntax: prtf file [-q queue] [-p pointsize] [-f \"Face name\"] [other options]\n");
goto cleanup;
}
/* recognize the arguments (dirty hack) */
n=2;
recargs:
if (n>=argc) goto endargs;
if (0==strcmp(argv[n],"-i"))
selection+=FATTR_SEL_ITALIC;
else if (0==strcmp(argv[n],"-u"))
selection+=FATTR_SEL_UNDERSCORE;
else if (0==strcmp(argv[n],"-b"))
selection+=FATTR_SEL_BOLD;
else if (0==strcmp(argv[n],"-s"))
selection+=FATTR_SEL_STRIKEOUT;
else if (0==strcmp(argv[n],"-o"))
selection+=FATTR_SEL_OUTLINE;
else if (n<argc-1)
{
if (0==strcmp(argv[n],"-f"))
{
n++;
pszFaceName=argv[n];
}
else if (0==strcmp(argv[n],"-q"))
{
n++;
pszQueueName=argv[n];
}
else if (0==strcmp(argv[n],"-p"))
{
n++;
pointsize=atof(argv[n]);
}
else if (0==strcmp(argv[n],"-c"))
{
n++;
copies=atoi(argv[n]);
}
else if (0==strcmp(argv[n],"-a"))
{
n++;
pszSpoolerParms=argv[n];
}
}
else
{
printf("Bad parameter %s\n",argv[n]);
goto cleanup;
}
n++;
goto recargs;
misargs:
printf("Missing parameter after %s\n",argv[n-1]);
goto cleanup;
endargs:
/* open the input file */
if (0!=(rc=DosQueryPathInfo(argv[1], 5, &szDocName,
sizeof(szDocName))))
{
printf("DosQueryPathInfo failed\n");
goto cleanup;
}
if (0!=(rc=DosOpen(szDocName, &FHandle,
&n, 0, FILE_NORMAL,
FILE_OPEN,
OPEN_FLAGS_SEQUENTIAL+
OPEN_SHARE_DENYWRITE+
OPEN_ACCESS_READONLY,
NULL)))
{
printf("DosOpen failed\n");
goto cleanup;
}
if (pszQueueName==NULL)
{
/* get default queue from os2.ini */
pszQueueName=output_buffer;
if (0==PrfQueryProfileString(HINI_PROFILE,
(PSZ)"PM_SPOOLER",
(PSZ)"QUEUE",
NULL,
(PSZ)pszQueueName,
(LONG)sizeof(output_buffer)
))
{
printf("No default queue defined: please define one or use the -q option\n");
goto cleanup;
}
if (NULL!=(pszDeviceName=strchr(pszQueueName,';')))
{
*pszDeviceName='\0';
}
}
if (0!=(rc=SplQueryQueue((PVOID)NULL, pszQueueName, 3L,
&prq3, sizeof(prq3_buffer), &n)))
{
printf("SplQueryQueue failed\n");
goto cleanup;
}
/* this not needed for spl calls, but needed for dev */
#ifndef never
if (NULL!=(pszDeviceName=strchr(prq3.pszPrinters,',')))
{
*pszDeviceName='\0';
}
if (NULL!=(pszDeviceName=strchr(prq3.pszDriverName,'.')))
{
*pszDeviceName='\0';
pszDeviceName++;
}
else
pszDeviceName="";
if (DEV_OK!=(n = DevPostDeviceModes( hab,
prq3.pDriverData,
prq3.pszDriverName,
pszDeviceName,
prq3.pszPrinters,
DPDM_QUERYJOBPROP )))
{
printf("DevPostDeviceModes failed %d:\n",n);
goto cleanup;
}
#endif
printf("queue name='%s' driver='%s' device='%s' printer='%s'\n",
prq3.pszName,prq3.pszDriverName,pszDeviceName,prq3.pszPrinters);
// (*(prq3.pDriverData)).szDeviceName,
// (*(prq3.pDriverData)).lVersion);
memset( &dos, 0, sizeof(dos));
dos.pszLogAddress = prq3.pszName; /* queue name */
dos.pszDriverName = prq3.pszDriverName;
dos.pdriv = prq3.pDriverData;
dos.pszDataType = "PM_Q_STD"; /* RAW if using Spl calls */
dos.pszComment = szDocName;
dos.pszQueueProcName = prq3.pszPrProc;
sprintf(output_buffer,"MAP=N COP=%d",copies);
dos.pszQueueProcParams=output_buffer;
dos.pszSpoolerParams = pszSpoolerParms;
// dos.pszNetworkParams = NULL;
#ifdef never
/* corresponds to DevOpenDc */
hspl = SplQmOpen(pszToken,8,(PQMOPENDATA)&dos);
if ( hspl != SPL_ERROR ) /* Good spooler handle */
{
printf("SplQmOpen handle is %d\n",hspl);
}
else
{
printf("SplQmOpen failed.\n");
goto cleanup;
}
#endif
/* create device context for the queue */
if (DEV_ERROR==( hdc = DevOpenDC(hab, OD_QUEUED, pszToken, 8, (void*)&dos, NULLHANDLE)))
{
printf("DevOpenDC failed\n");
goto cleanup;
}
#ifdef never
SplQmStartDoc(hspl,szDocName);
#endif
/* Issue STARTDOC to begin printing */
if (DEV_OK!=(n=DevEscape( hdc,
DEVESC_STARTDOC,
(int)strlen(szDocName),
szDocName,
(PLONG)NULL, (PBYTE)NULL)))
{
printf("DevEscape STARTDOC failed:\n");
goto cleanup;
}
/* create a presentation space associated with the context */
if (0==(hps = GpiCreatePS(hab, hdc,
&sizel, /* use same page size as device */
PU_TWIPS+GPIF_LONG+GPIT_NORMAL+GPIA_ASSOC)))
{
printf("GpiCreatePS failed:\n");
goto cleanup;
}
GpiSetAttrMode(hps,AM_NOPRESERVE);
GpiQueryPS(hps, &sizel);
GpiSetCharMode(hps,CM_MODE2);
GpiSetColor(hps,CLR_DEFAULT );
/* select a font */
memset(&fat,0,sizeof(fat)); /* defaults */
strcpy(fat.szFacename,pszFaceName);
fat.usRecordLength=sizeof(fat);
fat.fsSelection=selection;
fat.fsFontUse = FATTR_FONTUSE_NOMIX/*+FATTR_FONTUSE_OUTLINE+FATTR_FONTUSE_TRANSFORMABLE*/;
/* 0 for scalable font */
fat.lMaxBaselineExt=fat.lAveCharWidth=pointsize;
if (FONT_MATCH!=(n=GpiCreateLogFont(hps,
(PSTR8)NULL,
1L,
&fat)))
{
if (n==FONT_DEFAULT)
printf("Unable to match the typeface\n");
else
printf("GpiCreateLogFont failed: %d\n",n);
goto cleanup;
}
GpiSetCharSet(hps, 1L );
//GpiSetCharAngle(hps,&gradlAngle);
sizfCharBox.cx = (LONG)(pointsize*20*65536); /* translate to twips and fix */
sizfCharBox.cy = (LONG)(pointsize*20*65536);
GpiSetCharBox(hps,&sizfCharBox);
GpiQueryFontMetrics(hps, sizeof(FONTMETRICS), &fm);
printf("font family='%s' face='%s' at %gpt\n",
fm.szFamilyname,fm.szFacename,fm.lEmHeight/20.0);
/* figure out how much tab and line feed are in this font */
tab=fm.lAveCharWidth*8;
linefeed=fm.lExternalLeading+fm.lMaxBaselineExt;
/* retrieve character width table */
rc=GpiQueryWidthTable(hps,
0,
255,
widths);
home:
pageno++;
printf("Page %d\n",pageno);
pt.x = 0; pt.y = sizel.cy-linefeed;
locate:
if (output_buffer_l)
{
n=GpiCharString(hps, output_buffer_l, output_buffer);
if (n!=GPI_OK)
{
printf("CharString failed:\n");
goto cleanup;
}
output_buffer_l=0;
}
if (pt.y<0)
{
DevEscape( hdc,
DEVESC_NEWFRAME,
0L,
(PBYTE)NULL,
(PLONG)NULL,
(PBYTE)NULL );
goto home;
}
n=GpiMove(hps, &pt );
if (n!=GPI_OK)
{
printf("Move failed:\n");
goto cleanup;
}
if (marginflag) goto normargin; /* reprint char that wrapped around */
q_loop:
if (input_buffer_b<input_buffer_e) goto noread;
if ((rc=DosRead(FHandle, &input_buffer,
sizeof(input_buffer), &input_buffer_e)) != 0)
{
printf("DosRead failed\n");
goto cleanup;
}
if (input_buffer_e==0) goto eof;
input_buffer_b=0;
noread:
this_char=input_buffer[input_buffer_b];
input_buffer_b++;
/* see if it's a control char */
if (this_char!=13) goto notcr;
pt.x=0;
goto locate;
notcr:
if (this_char!=10) goto notlf;
pt.y-=linefeed;
goto locate;
notlf:
if (this_char!=9) goto nottab;
pt.x=(pt.x/tab+1)*tab;
goto locate;
nottab:
if (this_char!=8) goto notbs;
pt.x-=widths[' '];
if (pt.x<0)
pt.x=0;
goto locate;
notbs:
if (this_char!=12) goto notff;
pt.y=-1; /* force form feed */
goto locate;
notff:
/* get its width */
if (widths[this_char]>=sizel.cx)
{
printf("Character %c does not fit on the page\n",this_char);
goto cleanup;
}
if (pt.x+widths[this_char]<sizel.cx) goto normargin;
pt.x=0; /* on wraparound simulate cr and lf */
pt.y-=linefeed;
marginflag=1;
goto locate;
normargin:
marginflag=0;
output_buffer[output_buffer_l]=this_char;
output_buffer_l++;
pt.x+=widths[this_char];
if (output_buffer_l>=MAX_OUTPUT_BUFFER) goto locate;
/* fall thru */
goto q_loop; /* really always */
eof:
DosClose(FHandle);
if (output_buffer_l)
{
n=GpiCharString(hps, output_buffer_l, output_buffer);
if (n!=GPI_OK)
{
printf("CharString failed:\n");
goto cleanup;
}
}
#ifdef never
SplQmWrite(hspl, n, FileBuffer);
n = SplQmEndDoc(hspl);
printf("Job id is %d\n",n);
#endif
/* close the document */
l=2;
n= DevEscape(hdc,
DEVESC_ENDDOC,
0L, (PBYTE)NULL, &l, (PBYTE)&jobno);
if (DEV_OK!=n)
{
printf("DevEscape ENDDOC failed: %d\n",l);
}
if (l==2)
printf("Job id is %d\n",(int)jobno);
/* discard presentation space */
// GpiAssociate(hps, (HDC)NULLHANDLE );
GpiDestroyPS(hps);
/* discard device context */
DevCloseDC(hdc);
#ifdef never
SplQmClose(hspl);
#endif
cleanup:
if (0!=(erridErrorCode = WinGetLastError(hab)))
{
printf("WinGetLastError=%x\n",erridErrorCode);
switch (erridErrorCode&0xFFFF) {
case PMERR_DC_IS_ASSOCIATED: printf("Device context is associated.\n"); break;
case PMERR_ESC_CODE_NOT_SUPPORTED: printf("Escape code is not supported on DevEscape\n"); break;
case PMERR_FONT_AND_MODE_MISMATCH: printf("Font and mode mismatch.\n"); break;
case PMERR_INV_DC_DATA: printf("Invalid data on DevOpenDC.\n"); break;
case PMERR_INV_DC_TYPE: printf("Invalid type parameter on DevOpenDC.\n"); break;
case PMERR_INV_DRIVER_NAME: printf("Invalid driver name.\n"); break;
case PMERR_INV_ESCAPE_DATA: printf("Invalid data on DevEscape.\n"); break;
case PMERR_DEV_FUNC_NOT_INSTALLED: printf("Device function not supported by presentation driver.\n"); break;
case PMERR_INV_HDC: printf("Invalid device-context handle.\n"); break;
case PMERR_INV_HPS: printf("Invalid presentation-space handle.\n"); break;
case PMERR_NOT_IN_IDX: printf("Name not found, possible forms mismatch.\n"); break;
case PMERR_INV_LENGTH_OR_COUNT: printf("Invalid length or count.\n"); break;
case PMERR_INV_LOGICAL_ADDRESS: printf("An invalid device logical address.\n"); break;
case PMERR_INV_OR_INCOMPAT_OPTIONS: printf("An invalid or incompatible presentation space options.\n"); break;
case PMERR_INV_PS_SIZE: printf("Invalid size for presentation space.\n"); break;
case PMERR_PS_BUSY: printf("Presentation space is busy.\n"); break;
case PMERR_SPL_PRINT_ABORT: printf("Spooler print job has been aborted or redirected to a file.\n"); break;
}
}
if (rc!=0)
{
printf("RetCode=%d\n",rc);
switch(rc) {
case ERROR_ACCESS_DENIED: printf("Access is denied.\n"); break;
case ERROR_BAD_NETPATH: printf("The network path cannot be located.\n"); break;
case ERROR_BUFFER_OVERFLOW: printf("Buffer overflow.\n"); break;
case ERROR_DEVICE_IN_USE: printf("Device in use.\n"); break;
case ERROR_DRIVE_LOCKED: printf("Drive locked.\n"); break;
case ERROR_FILE_NOT_FOUND: printf("File not found.\n"); break;
case ERROR_FILENAME_EXCED_RANGE: printf("Filename exceedes range.\n"); break;
case ERROR_INVALID_ACCESS: printf("Invalid access.\n"); break;
case ERROR_INVALID_PARAMETER: printf("Invalid parameter.\n"); break;
case ERROR_MORE_DATA: printf("Additional data is available, buffer to small.\n"); break;
case ERROR_NOT_DOS_DISK: printf("Not a DOS disk.\n"); break;
case ERROR_NOT_SUPPORTED: printf("Request not supported by the network.\n"); break;
case ERROR_OPEN_FAILED: printf("Open failed / file not found.\n"); break;
case ERROR_PATH_NOT_FOUND: printf("Path not found.\n"); break;
case ERROR_SHARING_BUFFER_EXCEEDED: printf("Sharing buffer exceeded.\n"); break;
case ERROR_SHARING_VIOLATION: printf("Sharing violation.\n"); break;
case ERROR_TOO_MANY_OPEN_FILES: printf("Too many open files.\n"); break;
case 2150: printf("The printer queue does not exist.\n"); break;
case 2161: printf("The spooler is not running.\n"); break;
}
}
WinTerminate(hab); /* Terminate the application */
return(TRUE);
}