home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Overload
/
ShartewareOverload.cdr
/
graf
/
macpnt1.zip
/
PRINTER.C
< prev
next >
Wrap
Text File
|
1987-01-16
|
10KB
|
433 lines
/*
***************************************************************
* PRINTER.C - routines to support the printer
*
*
* (c) Copyright 1987 by:
*
* Computerwise Consulting Services
* P.O. Box 813
* McLean, VA 22101
* (703) 280-2809
*
* All rights reserved.
*
* Permission is granted for personal use of this program, with the
* exception that the following potential users ARE EXPLICITLY DENIED
* PERMISSION TO RECEIVE, USE, OR TRANSFER THIS PROGRAM IN SOURCE OR
* OBJECT OR EXECUTABLE OR ANY OTHER FORM:
*
* 1) Lotus Development Corporation, and any employee thereof
* or consultant thereto;
*
* 2) ADAPSO, and any firm which is a member thereof, or any
* employee of such a firm.
*
* These two organizations have - in the opinion of CCS - acted as
* "software pirates" by continually and intentionally violating
* U.S. Copyright law, specifically by first "copy-protecting" software
* disks and then zealously prosecuting innocent users who exercised
* their rights under the law to make copies of their own property.
*
* Further, permission is granted to transfer this program only if
* it is transferred absolutely unmodified in any form.
*
***************************************************************
*/
/*
* Explicitly ask user for a printer type, and set print_type per his selection
*/
ptype()
{
static BYTE inline[255];
int i;
mode(TEXT); /* In case we're in graphics mode */
fprintf(stderr, "What type of printer do you have?\n");
for ( i = 0; i < NUMPRINT; i++ )
{
fprintf(stderr, "\n%-6s = %s", printers[i].name, printers[i].desc );
}
fprintf(stderr, "\n\nPrinter = ");
inline[0] = '-';
gets( &inline[1] );
pswitch(inline);
}
/*
* Send mem_image to the printer
*/
print()
{
static BYTE graphics_data[MAC_HORIZ + 2];
static BYTE masks[16] =
{
0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, /* For normal bytes */
0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01 /* For reversed bytes */
};
BYTE mask;
unsigned line, pixel; /* Where we're at */
struct _printer *p; /* Our printer's info */
BYTE *s;
BYTE c;
int i;
int aborted; /* Non-zero if he pressed a key to abort printout */
/*
* Make sure that we have selected a printer
*/
while ( print_type == -1 )
{
ptype();
}
p = &printers[print_type]; /* Point to its params */
if ( p->ignore )
{
return; /* We are to ignore this */
}
print_error = 0; /* Reset error flag */
aborted = 0; /* We're not aborted yet! */
string( p->page_init ); /* Init the printer */
/*
* Dump the image one print line (7 or 8 wires) at a time
*/
mask = 0xff; /* Mask everything on for now */
if ( p->delta == 7 ) /* Except lost bit in 7-wire data */
{
mask = (p->reversed) ? 0x7f : 0xfe;
}
for ( line = 0; line < MAC_VERT; line += p->delta )
{
if ( kbhit() )
{
/*
* We are to cancel this printout, because
* he has pressed a key. Go through all of the
* CRLF's to get us to the bottom of the page,
* but don't waste time assembling graphics
* bytes that won't be printed.
*/
aborted = -1;
key(); /* Swallow his keypress */
}
/*
* If doing a wierd delta (like 7), we must not grab
* up to 6 lines after end of image. So we mask out
* any bits that come from lines MAC_VERT+. We do this by
* here figuring out a mask byte for this whole line,
* and applying it later.
*/
if ( line > 712 )
{
mask = masks[ (line - 712) + (p->reversed ? 8 : 0) ];
}
/*
* Get a line full of pixels. When we're done, c will be
* zero if the entire line is zero.
*/
s = graphics_data;
c = 0;
if ( !print_error && !aborted )
{
for ( pixel = 0; pixel < MAC_HORIZ; pixel++ )
{
c |= (*s++ = vslice(line, pixel, p->reversed) & mask);
}
}
/*
* Pass it to printer, per whatever method we're supposed
* to use. If this entire line is zero (blank), then don't
* bother.
*/
if ( c && !print_error && !aborted )
{
string( p->line_init ); /* Init printer for graphics data */
if ( p->buffered == 1 )
{
/*
* line_init has taken care of everything. Just blast
* all data out there.
*/
prints(MAC_HORIZ, graphics_data);
}
else
{
/*
* line_init has merely put the printer into
* graphics mode. The printer has no idea how
* many bytes are coming. Send 'em one at a time,
* checking for special editing as we do.
*/
for ( i = 0; i < MAC_HORIZ; i++ )
{
c = graphics_data[i]; /* Get next byte of graphics data */
switch(p->special) /* Edit it properly */
{
case 1:
/*
* The Data Products (boo!) will
* interpret 0x03 as a command. So change
* it to 0x03 0x03 to get it through as
* a graphics data byte.
*/
if ( c == 3 )
{
printchar(3);
}
printchar(c);
break;
default:
printchar(c);
}
}
}
string(p->line_end); /* Wrap up line */
}
string(p->crlf); /* Move to next line */
}
/*
* Wrap up printed page
*/
string(p->wrapup);
/*
* If we are in "print all files automatically" mode and we were
* aborted by a keypress, then pass this state back to the mainline
* so that it can exit.
*/
if ( aborted && print_all )
{
time2quit = -1;
}
}
/*
* Construct and return a one-byte vertical slice of mem_image, consisting
* of 1 bit from each of 8 consecutive screen lines. This is how many printers
* expect to see bit-image graphics.
*
* Input is the line number n (0 - 712) of the first of 8 lines, and a pixel
* offset p (0 - 575) within the line.
*
* Output is the vertical slice of those 8 lines at that pixel offset, as
* graphically illustrated:
*
* pixel: p p+1 p+2 p+3 p+4 p+5 p+6 p+7 p+8 p+9
* +---+
* mem_image line n | 1 | 1 1 1 1 1 1 1 0 0
* n+1 | 1 | 1 1 1 1 1 1 1 0 0
* n+2 | 0 | 0 0 1 1 0 0 0 0 0
* n+3 | 0 | 0 0 1 1 0 0 0 0 0
* n+4 | 0 | 0 0 1 1 0 0 0 0 0
* n+5 | 0 | 0 0 1 1 0 0 0 0 0
* n+6 | 0 | 0 0 1 1 0 0 0 0 0
* n+7 | 0 | 0 0 1 1 0 0 0 0 0
* +---+
* ^
* |
* +--- Returned byte
*
* For printers which use this method, a printed output line consists of
* 576 bytes as sliced by this routine (with possible leading spacing to
* center the line on the page), preceeded by whatever escape codes are
* needed to put the printer into bit-image graphics mode for this line.
*
* NOTE: The byte returned by this routine can be oriented one of two ways:
*
* 1) With bit 7 being the topmost line's pixel, and bit 0 being
* from the bottom line.
*
* 2) With bit 0 being the topmost line's pixel, and bit 7 being
* from the bottom line.
*
* This depends upon the printer. Some expect data one way, some the other.
* If the arg "reverse" is zero, then you get the returned byte according
* to description (1) above. If "reverse" is non-zero, then the returned
* byte is reversed, and comes back per description (2) above.
*
*/
BYTE vslice(n, p, reverse)
int n; /* Line number (0-712) of first of 8 lines */
int p; /* Pixel number (0-575) of slice within line */
int reverse; /* Non-zero to return reversed byte */
{
int i;
BYTE result;
BYTE *ptr;
BYTE mask;
ptr = &mem_image[n][p / 8]; /* What byte to look at */
mask = 1 << ( 7 - ( p & 7 ) ); /* What bit to look at */
result = 0;
if (reverse)
{
/*
* Produce a reversed byte
*/
for ( i = 0; i < 8; i++ )
{
result >>= 1;
if ( *ptr & mask ) result |= 0x80;
ptr += (MAC_HORIZ/8); /* Move to next line, same byte */
}
}
else
{
/*
* Produce a normal byte (not reversed)
*/
for ( i = 0; i < 8; i++ )
{
result <<= 1;
if ( *ptr & mask ) result |= 1;
ptr += (MAC_HORIZ/8); /* Move to next line, same byte */
}
}
return(result);
}
/*
* Print n bytes, starting at s, to printer.
*/
prints(n, s)
unsigned n; /* # bytes to do */
BYTE *s; /* Data to be sent */
{
if ( !print_error )
{
while( n-- )
{
printchar(*s++);
}
}
}
/*
* Print string s on printer. String s is assumed to be standard C string,
* or a NULL.
*/
string(s)
BYTE *s;
{
if ( s )
{
if ( !print_error ) prints( strlen(s), s );
}
}
/*
* Send char c to printer via ROM BIOS
*/
printchar(c)
BYTE c;
{
if (print_error)
{
return; /* Previous error occurred */
}
inregs.x.dx = 0; /* LPT1: */
inregs.h.ah = 0; /* "Print AL" ROM BIOS func */
inregs.h.al = c; /* Char to print */
again:
int86( 0x17, &inregs, &outregs);
/*
* Check for error printing
*/
while ( outregs.h.ah & 1 )
{
if ( cur_mode != TEXT )
{
mode(TEXT);
}
fprintf(stderr, "\nPrinter error. (C)ancel print or (R)etry: ");
switch( key() )
{
case 0x2e63: /* c = cancel */
case 0x2e43: /* C = Cancel */
fprintf(stderr, "CANCEL");
print_error = -1;
return;
case 0x1372: /* r = retry */
case 0x1352: /* R = Retry */
fprintf(stderr, "RETRY");
goto again;
}
}
}