#include <stdio.h>
#include <exec/types.h>
#include <devices/printer.h>
#include <intuition/intuition.h>
#include <libraries/dosextens.h>

union printerIO *request; /* Zeiger auf Requeststruktur */
union printerIO{
	struct IOStdReq ios;
	struct IODRPReq iodrp;
	struct IOPrtCmdReq iopc;
	};

struct IntuitionBase *IntuitionBase;
struct FileHandle    *newwindow;
struct MsgPort 	     *printerPort;

int ledge,tedge,width,height,dest,spezial,flag;
int error=1;


/***          Funktionen         ***/


openw()
/* Fenster öffnen und warten auf Tastendruck */
{
	struct Window *aktiv, *hrdcpy_window;
	char *zeichen;
	char buffer[70];

	sprintf(buffer,"RAW:0/0/160/80/HRDCPY"); /* Window öffnen */
	if(!(newwindow=Open(buffer,MODE_NEWFILE))) return(1);/* Fehler */

	aktiv=IntuitionBase->ActiveWindow;/* 'aktiv' = das neue Window */
	if(flag==0) Delay(200);

	/* Text ausgeben: */
	sprintf(buffer,"%s","\033[7mBitte wählen ...\033[0m\n\nSHIFT P = PRINT\nSHIFT L = LUPE\n\nSHIFT X = ENDE\n\n");
	Write(newwindow,buffer,strlen(buffer));

	/* Warten auf Shift L, -P oder -X :  */
	while(zeichen!=0x4c && zeichen!=0x50 && zeichen!=0x58){
		/* warten, bis HRDCPY-Window aktiv ist: */
		while((hrdcpy_window=IntuitionBase->ActiveWindow)!=aktiv);
		zeichen=key();
	}	
	if(zeichen==0x58){    		/* Shift X */
			 error=0;
			 return(1);
	}
	flag=0;
	ledge =hrdcpy_window->LeftEdge; /* Shift P oder -L */
	tedge =hrdcpy_window->TopEdge;
	width =hrdcpy_window->Width;
	height=hrdcpy_window->Height;

	Close(newwindow);		/* Fenster schliessen */

	if(zeichen==0x50){		/* Shift P */
		 dest   =width*11;	/* Grösse des Ausdruckes */
		 spezial=SPECIAL_MILCOLS | SPECIAL_ASPECT;
	}
	else{				/* Shift L */
		dest   =0;				  /* so gross wie  */
		spezial=SPECIAL_FULLCOLS | SPECIAL_ASPECT;/* möglich	   */
	}
	return(0);
}


closew()
/* Programmende */
{
	int i;

	if(flag==1){
		DeleteExtIO(request,sizeof(union printerIO));
		DeletePort(printerPort);
	}
	if(error){
		for(i=0;i<5;i++){
			DisplayBeep(0);
			Delay(5);
		}
	}
	else Close(newwindow);

	if(IntuitionBase) CloseLibrary(IntuitionBase);
	exit(0);
}

DumpRPort(request)
/* Raster von bestimmter Grösse auf Drucker ausgeben */
	union printerIO *request;
{
	struct Screen  	 *screen;
	struct ViewPort	 *vp;
	struct RastPort	 *rp;
	struct ColorMap  *cm;
	int mod;

	screen	= IntuitionBase->ActiveScreen;
	rp	= &screen-> RastPort;
	vp	= &screen-> ViewPort;
	cm	= vp	 -> ColorMap;
	mod	= vp	 -> Modes;

	request->iodrp.io_Command  =PRD_DUMPRPORT;
	request->iodrp.io_RastPort =rp;  /* Rasterport das augegeben wird*/
	request->iodrp.io_ColorMap =cm;  /* Zeiger auf  ColorMapStructur */
	request->iodrp.io_Modes    =mod; /* Hires, Interlace oder Sprites*/
	request->iodrp.io_SrcX     =ledge;	/* linke Grenze		 */
	request->iodrp.io_SrcY     =tedge;    	/* obere Grenze		 */
	request->iodrp.io_SrcWidth =width;	/* Breite des Rasters	 */
	request->iodrp.io_SrcHeight=height;	/* Höhe	des Rasters	 */
	request->iodrp.io_DestCols =dest; 	/* Format Spalte	 */
	request->iodrp.io_DestRows =0; 		/* Format Zeile 	 */
	request->iodrp.io_Special  =spezial;	/* Flags 		 */
	return(DoIO(request));			/* DUMP ausfÜhren	 */
}

key()
/* Tastendruck */
{
	char zeichen;

	if(WaitForChar(newwindow,1)==0) return(0); /* keine Taste gedrÜckt  */
	Read(newwindow,&zeichen,1);	/* nach Tastendruck, dessen Wert in */
	return(zeichen);		/* 'zeichen' speichern		    */
}

main()
{

    if(!(IntuitionBase=(struct IntuitionBase *)
	 OpenLibrary("intuition.library",0))) closew();

    for(;;){	/* Endlosschleife */

	if(openw()) closew();	/* Programmende, wenn openw() 1 zurÜckgibt */

	flag=1;	/* flag=1 bedeutet mindestens einen versuchten Ausdruck */
	printerPort=CreatePort(0,0);	/* Printerport öffnen */
	/* mit Funktion CreateExtIO den Request initialisieren: */
	request=(union printerIO *)
			CreateExtIO(printerPort,sizeof(union printerIO));
	/* Drucker Device öffnen */
	if(OpenDevice("printer.device",0,request,0)) closew();

	/* Raster ausgeben */
	if(DumpRPort(request)) closew();

	/* Drucker schliessen */
	CloseDevice(request);
    }
}
