home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frozen Fish 1: Amiga
/
FrozenFish-Apr94.iso
/
bbs
/
alib
/
d5xx
/
d518
/
post.lha
/
Post
/
post16s.lzh
/
postlj.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-04-17
|
16KB
|
639 lines
/* LaserJet print driver for Post V1.6. File "postlj.c"
* (C) Adrian Aylward 1990, 1991
*
* You may freely copy, use, and modify this file.
*
* This program prints PostScript files to a LaserJet. It sends the output
* to the PAR: handler. Page size and orientation are read from the command
* line. There are no printer status checks; if the output hangs check your
* printer is ready. It is totally Amiga specific.
*
* The program was tested using Lattice C V5.05. It has various Lattice
* dependencies.
*/
# include <dos.h>
# include <devices/printer.h>
# include <devices/prtbase.h>
# include <exec/exec.h>
# include <exec/execbase.h>
# include <exec/tasks.h>
# include <graphics/gfx.h>
# include <graphics/rastport.h>
# include <proto/dos.h>
# include <proto/exec.h>
# include <string.h>
# include <stdio.h>
# include <fcntl.h>
# include <ios1.h>
# include "postlib.h"
/* Assembler routines */
extern void insertbreak(void);
extern void deletebreak(void);
extern void insertftrap(void);
extern void deleteftrap(void);
/* Routines defined and referenced only within this module */
extern int strtoint(char **sp, int *ip);
extern void __saveds __asm copypage(register __d0 int num);
extern void prtsetup(void);
extern void prtreset(void);
extern void prtdump(int copies);
extern void prtdumpline(char *buf, int len);
/* Lattice startup */
extern struct UFB _ufbs[];
/* External data (initialised to zero) */
int retcode;
int arec;
BPTR errfh;
FILE *parfp;
struct library *PSbase;
struct PSparm parm;
int breakset, ftrapset;
/* Options */
# define DEFSIZE 3 /* A4 page size */
# define DEFLAND 0 /* Portrait orientation */
# define DEFCOMP 1 /* Allow graphics compression (LJ2P etc.) */
# define MAXSIZE 8
int optsize = DEFSIZE;
int optland = DEFLAND;
int optcomp = DEFCOMP;
int optcopies;
int optbeg, optend;
int pagenum;
/* Page size tables.
* (See Figures 2-2 and 2-3 in the LaserJet 2P Technical Reference Manual.)
*
* Let Legal Exec A4 COM10 Mon C5 DL
*/
int psize[MAXSIZE] = { 2, 3, 1, 26, 81, 80, 91, 90 };
int xsize[MAXSIZE] = { 2550, 2550, 2175, 2480, 1237, 1162, 1913, 1299 };
int ysize[MAXSIZE] = { 3300, 4200, 3150, 3507, 2850, 2250, 2704, 2598 };
int ppoff[MAXSIZE] = { 75, 75, 75, 71, 75, 75, 71, 71 };
int ploff[MAXSIZE] = { 60, 60, 60, 59, 60, 60, 59, 59 };
char *showsize[MAXSIZE] = {"letter", "legal", "executive", "A4",
"COM-10", "monarch", "C5", "DL" };
char *showland[2] = {"portrait", "landscape" };
int compsize;
char *compbuf;
/* Arguments */
char *argto = "par:";
int argfilec, argmemc;
char *argfilev[5], *argmemv[5];
char *argkey[] =
{ "TO", "MEM", NULL };
/* Startup code */
extern void main(int argc, char **argv);
void _main(char *line)
{ char *argv[32];
int argc;
/* Parse the arguments to break words and strip quotes. N.B. the
* main program can determine that the arument was quoted by inspecting
* the preceeding character */
argc = 0;
if (line == NULL) goto endline;
for (;;)
{ while (*line == ' ' || *line == '\t' || *line == '\n') line++;
if (*line == 0) break;
if (argc == 32)
{ argc = 0;
goto endline;
}
if (*line == '"')
{ argv[argc] = ++line;
while (*line != '"')
{ if (*line == 0)
{ argc = 0;
goto endline;
}
line++;
}
}
else
{ argv[argc] = line;
while (*line != ' ' && *line != '\t' && *line != '\n')
{ if (*line == 0)
{ argc++;
goto endline;
}
line++;
}
}
*line++ = 0;
argc++;
}
endline:
/* Set up the standard input/output files */
errfh = Open("*", MODE_OLDFILE);
if (errfh == NULL)
{ retcode = 20;
goto tidyexit;
}
_ufbs[2].ufbfh = (long) errfh;
_ufbs[2].ufbflg |= UFB_WA|O_RAW|UFB_NC;
stderr->_file = 2;
stderr->_flag = _IOWRT;
setbuf(stderr, NULL);
/* Call the main program */
main(argc, argv);
/* Tidy up and exit */
tidyexit:
if (errfh) Close(errfh);
XCEXIT(retcode);
}
/* Main program */
void main(int argc, char **argv)
{ char *s, *t;
int *ip, i, m, n, ch;
/* Open the libraries */
PSbase = OpenLibrary("post.library", POSTVERNO);
if (PSbase == NULL)
{ fprintf(stderr, "postlj: can't open post.library\n");
goto errorexit;
}
/* Parse the arguments and keywords. See the usage string below */
argc--;
argv++;
if (argc == 0 || (argc == 1 && strcmp(*argv, "?") == 0)) goto usage;
while (argc--)
{ s = *argv++;
i = -1;
if (s[-1] != '"')
if (*s == '-')
{ s++;
while (t = s, ch = *s++)
{ switch (ch)
{ case 'S': case 's':
m = MAXSIZE;
ip = &optsize;
break;
case 'L': case 'l':
m = 2;
ip = &optland;
break;
case 'B': case 'b':
m = 10000;
ip = &optbeg;
break;
case 'E': case 'e':
m = 10000;
ip = &optend;
break;
case 'N': case 'n':
m = 100;
ip = &optcopies;
break;
case 'C': case 'c':
m = 2;
ip = &optcomp;
break;
default:
fprintf(stderr,
"postlj: unknown option \"%c\"\n", ch);
goto badusage;
}
if (!strtoint(&s, &i)) goto badvalue;
if ((unsigned) i >= m)
{ fprintf(stderr,
"postlj: option value out of range "
"(0-%d) \"%.*s\"\n", m - 1, s - t, t);
goto errorexit;
}
*ip = i;
}
continue;
}
else
for (;;)
{ i++;
if (argkey[i] == NULL)
{ i = -1;
break;
}
if (stricmp(s, argkey[i]) == 0) break;
}
switch (i)
{ case 0: /* TO */
if (argc == 0) goto badargs;
argc--;
argto = *argv++;
break;
case 1: /* MEM */
if (argc == 0) goto badargs;
argc--;
if (argmemc == 5) goto badargs;
argmemv[argmemc++] = *argv++;
break;
default:
if (argfilec == 5) goto badargs;
argfilev[argfilec++] = s;
}
}
/* Parse the "MEM fhlv.." options */
for (i = 0; i < argmemc; i++)
{ s = argmemv[i];
for (;;)
{ ch = *s++;
if (ch == 0) break;
ch = tolower(ch);
switch (ch)
{ case 'f':
ip = &parm.memflen;
break;
case 'h':
ip = &parm.memhlen;
break;
case 'l':
ip = &parm.memllen;
break;
case 'v':
ip = &parm.memvlen;
break;
default:
goto badvalue;
}
if (!strtoint(&s, ip)) goto badvalue;
}
}
/* Determine the page size */
if (optland)
{ n = xsize[optsize];
m = ysize[optsize];
}
else
{ m = xsize[optsize];
n = ysize[optsize];
}
parm.page.depth = 1;
parm.page.xoff = parm.page.yoff = 0;
parm.page.xsize = m;
parm.page.ysize = n;
parm.page.xbytes = (parm.page.xsize + 7) >> 3;
parm.page.len = parm.page.xbytes * parm.page.ysize;
parm.page.ybase = 0;
parm.page.yheight = parm.page.ysize;
parm.page.xden = parm.page.yden = 300;
parm.page.ydir = -1;
/* Allocate the page buffer */
for (i = 0; i < parm.page.depth; i++)
{ if ((parm.page.buf[i] =
AllocMem(parm.page.len, MEMF_PUBLIC|MEMF_CLEAR)) == NULL)
{ fprintf(stderr, "postlj: can't get page buffer\n");
goto errorexit;
}
}
/* Allocate the print compression buffer */
compsize = parm.page.xbytes + parm.page.xbytes / 128 + 2;
compbuf = AllocMem(compsize, MEMF_PUBLIC);
if (compbuf == NULL)
{ fprintf(stderr, "postlj: can't get memory\n");
goto errorexit;
}
/* Open a file to the par: handler and initialise the printer */
parfp = fopen(argto, "w");
if (parfp == NULL)
{ fprintf(stderr, "postlj: can't open %s\n", argto);
goto errorexit;
}
prtsetup();
if (ferror(parfp))
{ fprintf(stderr, "postlj: error writing printer file\n");
goto errorexit;
}
/* Initialise for interpretation */
insertbreak();
SetExcept(~0, SIGBREAKF_CTRL_C);
breakset = 1;
insertftrap();
ftrapset = 1;
parm.copyfunc = (APTR) copypage;
parm.infh = Input();
parm.outfh = Output();
parm.errfh = errfh;
arec = PScreateact(&parm);
if (arec == 0)
{ fprintf(stderr, "postlj: can't get memory\n");
goto errorexit;
}
if ((unsigned) arec <= errmax)
{ arec = 0;
retcode = 10;
goto tidyexit;
}
/* Interpret the argument files */
fprintf(stderr, "postlj: running (%s, %s)\n",
showsize[optsize], showland[optland]);
pagenum = 0;
for (i = 0; i < argfilec; i++)
if (PSintstring(arec, argfilev[i],
-1, PSFLAGFILE|PSFLAGCLEAR|PSFLAGERASE) != 0)
{ retcode = 10;
goto tidyexit;
}
if (ferror(parfp))
{ fprintf(stderr, "postlj: error writing printer file\n");
goto errorexit;
}
fprintf(stderr, "postlj: finished\n");
goto tidyexit;
/* Argument errors and usage query */
badargs:
fprintf(stderr, "postlj: arguments bad, or value missing\n");
goto badusage;
badvalue:
fprintf(stderr, "postlj: argument bad value\n");
badusage:
retcode = 20;
usage:
fprintf(stderr, "postlj: usage:\n"
" postlj -s.l.b.e.n.c. [files...] [TO tofile] [MEM fhlv..]\n");
goto tidyexit;
/* Tidy up and exit */
errorexit:
retcode = 20;
tidyexit:
if (breakset)
{ SetExcept(0, SIGBREAKF_CTRL_C);
deletebreak();
breakset = 0;
}
if (ftrapset)
{ deleteftrap();
ftrapset = 0;
}
if (arec) PSdeleteact(arec);
if (parfp)
{ prtreset();
fclose(parfp);
}
if (compbuf) FreeMem(compbuf, compsize);
for (i = 0; i < parm.page.depth; i++)
if (parm.page.buf[i])
{ FreeMem(parm.page.buf[i], parm.page.len);
parm.page.buf[i] = NULL;
}
if (PSbase) CloseLibrary(PSbase);
}
/* String to integer conversion; digits only, with error check */
int strtoint(char **sp, int *ip)
{ char *s = *sp;
int i = 0;
int ch;
for (;;)
{ ch = *s;
if (ch < '0' || ch > '9') break;
i = i * 10 + (ch - '0');
s++;
}
if (s == *sp)
return 0;
else
{ *sp = s;
*ip = i;
return 1;
}
}
/* Signal an interrupt */
void __saveds sigint()
{ PSsignalint(arec, 1);
}
/* Signal a floating point error */
void __saveds sigfpe()
{ PSsignalfpe(arec);
}
/* Copy the page to the output */
void __saveds __asm copypage(register __d0 int num)
{ pagenum++;
if ((optbeg == 0 || pagenum >= optbeg) &&
(optend == 0 || pagenum <= optend))
{ prtdump(optcopies == 0 ? num : optcopies);
if (ferror(parfp)) PSerror(arec, errioerror);
}
}
/* Printer setup */
void prtsetup(void)
{
/* Printer reset, Page size, Orientation, Perf skip off, Top Mgn 0 */
fprintf(parfp, "\33E\33&l%da%do0l0E", psize[optsize], optland);
/* Long edge offset, Short edge offset */
if (optland)
fprintf(parfp, "\33&l%dz%dU",
-(150 - ploff[optsize] * 720) / 300, 0);
else
fprintf(parfp, "\33&l%du%dZ",
(150 - ppoff[optsize] * 720) / 300, 0);
}
/* Printer reset */
void prtreset(void)
{ fprintf(parfp, "\33E");
}
/* Printer dump */
void prtdump(int num)
{ char *buf;
int ysize;
/* Set the number of copies */
if (num == 0 || num > 99) num = 1;
fprintf(parfp, "\33&l%dX", num);
/* Set cursor to (0,0), 300 dpi, aligned logical page, start graphics */
fprintf(parfp, "\33*p0x0Y\33*t300R\33*r0f0A");
/* Loop for the rows */
buf = parm.page.buf[0];
ysize = parm.page.ysize;
while (ysize--)
{ prtdumpline(buf, parm.page.xbytes);
buf += parm.page.xbytes;
}
/* End graphics, form feed, reset number of copies */
fprintf(parfp, "\33*rB\14\33&l1X");
}
/* Dump a line of pixels */
void prtdumpline(char *buf, int len)
{ char *ptr;
int b, c, l;
/* Strip trailing zeros */
while (len && buf[len - 1] == 0) len--;
/* Compression */
if (optcomp)
{ ptr = compbuf;
l = 0;
while (len--)
{ b = *buf++; /* Pick up a byte */
c = 1;
while (len && *buf == b && c < 128)
{ c++;
buf++;
len--; /* See if it begins a run */
}
if (c == 2 && /* If a two byte run */
l > 0 && /* and preceeded by literals */
l <= 125 && /* and not more than 125 of them */
(len <= 2 || /* and no more than 2 bytes left */
*buf != *(buf + 1))) /* or not followed by a run */
{ c = 1; /* Then make it a literal */
buf--;
len++;
}
if (c == 1) /* If not a run */
{ l++; /* Then it must be a literal */
c = 0;
}
if (l > 0 && /* If we have some literals */
(c > 1 || /* and beginning a run */
l == 127 || /* or reached 127 */
len == 0)) /* or no more bytes left */
{ *ptr++ = l - 1; /* Then write out the literals */
memcpy(ptr, buf - c - l, l);
ptr += l;
l = 0;
}
if (c > 1) /* If we have a run */
{ *ptr++ = 1 - c; /* Then write it */
*ptr++ = b;
}
}
len = ptr - compbuf;
fprintf(parfp, "\33*b2m%dW", len);
buf = compbuf;
}
/* No compression */
else
fprintf(parfp, "\33*b%dW", len);
fwrite(buf, 1, len, parfp);
}
/* Dummy stub routine */
void stub(void)
{ return;
}
/* Dummy check abort routine */
void chkabort(void)
{ return;
}
/* End of file "postlj.c" */