(c)  Copyright 1989 Commodore-Amiga, Inc.   All rights reserved.
The information contained herein is subject to change without notice, and 
is provided "as is" without warranty of any kind, either expressed or implied.  
The entire risk as to the use of this information is assumed by the user.



                   Printer.c - A Printer Text 
                     and Graphics Module
             
                      by Carolyn Scheppner 


     One strong feature of the Amiga system software is the built-in support 
for a wide variety of printers.  By supporting printers at the system level,
print functions can be device-independent.  This allows the application 
developer to concentrate on the code instead of worrying about the many 
printer prototcol details which differ from one printer to another.  The 
printer.c program listed below is a C source module which lets you easily 
add printer text and graphic capability to your C programs.  

The program provides you with 6 functions:  openPrinter(), pString(), pText(), 
dumpScreen(), dumpRpVp() and closePrinter().  When using this module or any 
other printer code, always remember to close the printer when you are not 
actively using it.  This will allow other tasks which may be running to 
access the printer.

Here is a summary of the printer.c functions:


   o  openPrinter() -  Allocates and initializes iodrp, and opens the 
                       printer.device.  

                       Usage: iodrp = (struct IODRPReq *)openPrinter();

   o  closePrinter() - Closes the printer.device and deallocates the 
                       iodrp.

                       Usage: closePrinter(iodrp);


The following functions all require an open iodrp.  Note that the text 
functions reference the larger iodrp as a simple IOStdRequest.
   

   o  pString()      - Prints a null terminated text string.

                       Usage: error = pString(ioreq,string);


   o  pText()        - Prints an arbitrary string of a specified 
                       length.

                       Usage: error = pText(ioreq,string,length);


   o  dumpScreen()   - Does a raster dump of the entire screen to the
                       printer.

                       Usage: error = dumpScreen(iodrp,screen);


   o  dumpRpVp()     - Does a raster dump of the specified portion of
                       any rastport to the printer.

                       Usage: error = dumpRpVp(iodrp,rp,vp,x,y,w,h);
 
The printer.c code takes care of setting up the appropriate IO blocks and 
reply port and opens and closes the device for you.  Simply call 
openPrinter().  If a valid (non-zero) iodrp is returned, you may use it
in calls to any of the printer.c output routines.  When you are finished,
pass the iodrp to the closePrinter() routine to free up the printer for other
tasks.

/*
 * printer.c - routines to print text or dump rastport
 *             C. Scheppner
 */


#include "exec/types.h"
#include "intuition/intuition.h"
#include "devices/printer.h"

extern struct IODRPReq  *openPrinter();
extern struct IODRPReq  *CreateExtIO();
extern struct MsgPort   *CreatePort();


/* pString() - Prints null terminated string
 *             You supply ioreq from openPrinter, and ptr to string
 *             Returns 0 or error
 */
pString(ioreq,s)
struct IOStdReq *ioreq;
UBYTE *s;
   {
   return(pText(ioreq,s,strlen(s)));
   }


   
/* pText() - Prints non-null-terminated text
 *           You supply ioreq from openPrinter, ptr to text, text length
 *           Returns 0 or error
 */
pText(ioreq,s,l)
struct IOStdReq *ioreq;
UBYTE *s;
ULONG l;
   {
   int error = 1;
   if(ioreq)
      {
      ioreq->io_Data = (APTR)s;
      ioreq->io_Length = l;
      ioreq->io_Command = CMD_WRITE;
      error = DoIO(ioreq);
      }
   return(error);
   }













/* dumpScreen() - Dumps whole screen
 *                You supply open iodrp and pointer to Screen
 *                Returns 0 or error
 */
dumpScreen(iodrp,sc)
struct IODRPReq *iodrp;
struct Screen *sc;
   {
   return(dumpRpVp(iodrp,&sc->RastPort,&sc->ViewPort,0,0,sc->Width,sc->Height));
   }




 
/* dumpRpVp() - Dumps specified portion of supplied rastport
 *              You supply open iodrp, ptrs to RastPort and ViewPort,
 *              upper left source x,y, and pixel w,h of source
 *              Returns 0 or error
 */
dumpRpVp(iodrp,rp,vp,x,y,w,h)
struct IODRPReq *iodrp;
struct RastPort *rp;
struct ViewPort *vp;
ULONG  x, y, h, w;
   {
   int error = -1;

   if(iodrp)
      {
      iodrp->io_Command = PRD_DUMPRPORT;
      iodrp->io_RastPort = rp;
      iodrp->io_ColorMap = vp->ColorMap;
      iodrp->io_Modes = (ULONG)vp->Modes;
      iodrp->io_SrcX = x;
      iodrp->io_SrcY = y;
      iodrp->io_SrcWidth = w;
      iodrp->io_SrcHeight = h;
      /* iodrp->io_DestCols = 0; MEMF_CLEAR zeroed this  */
      /* iodrp->io_DestRows = 0; MEMF_CLEAR zeroed this  */
      iodrp->io_Special = SPECIAL_FULLCOLS|SPECIAL_ASPECT;

      error = DoIO(iodrp);
      }
   return(error);
   }













/* openPrinter() - Returns largest printer IORequest (iodrp) or 0=failure
 *                 Cast return as IOStdReq for plain text printing
 */
struct IODRPReq *
openPrinter()
   {
   struct IODRPReq *iodrp;    /* Largest printer request */
   struct MsgPort  *printerPort;
   int error = 1;

   if(printerPort = CreatePort("CBM_prtport",0))
      {
      if(iodrp=CreateExtIO(printerPort,sizeof(struct IODRPReq)))
         {
         if(!(error=OpenDevice("printer.device",0,iodrp,0)))
            {
            return(iodrp);
            }
         DeleteExtIO(iodrp);
         }
      DeletePort(printerPort);
      }
   return((struct IODRPReq *)NULL);  /* failure */
   }




closePrinter(iodrp)
struct IODRPReq *iodrp;
   {
   struct MsgPort *msgport;

   if(iodrp)
      {
      CloseDevice(iodrp);
      msgport = iodrp->io_Message.mn_ReplyPort;
      DeleteExtIO(iodrp);
      DeletePort(msgport);
      }
   }





