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

/*
**	   S C R E E N   I M A G E   P R I N T E R (SCRIMPER)
**
**	         Copyright 1986 By Perry S. Kivolowitz
**
**	The author grants permission to duplicate and reproduce
**	this software  provided  that no commercial gain can be
**	had as a consequence of  use  or  reproduction  of this
**	software and that  this and other identifying informat-
**	be left intact.
**
**	This software is provided as  a  service to the readers
**	of Amazing Computing and does not imply  any commitment
**	on behalf of the author to  provide support nor can the
**	author be held liable  for  the  consequences of use or
**	misuse of this software.
**
*/

static struct IODRPReq  request;
static struct MsgPort  	*pport;
extern struct Message   *GetMsg();
extern struct MsgPort  	*CreatePort();
extern PLANEPTR 	AllocRaster();
extern struct Window    *w;

static struct BitMap   bm;
static struct RastPort rp;
static int    close_mask;
static int    rast_count;

#define	PPORT		0x0001
#define	PRINTER		0x0004

static struct IntuiText no_port = {
	0,1,JAM1,10,16,NULL,(UBYTE *) "Could Not Allocate Printer Port" , NULL
};

static struct IntuiText no_lp = {
	0,1,JAM1,20,16,NULL,(UBYTE *) "Could Not Open Printer" , NULL
};

static struct IntuiText no_mem2 = {
	0,1,JAM1,10,16,NULL,(UBYTE *) "asynchronous print. Continue?",NULL
};

static struct IntuiText no_mem = {
	0,1,JAM1,30,5,NULL,(UBYTE *) "Not enough chip memory for",&no_mem2
};

static struct IntuiText ru_sure = {
	0,1,JAM1,22,5,NULL,(UBYTE *) "Print The Screen?" , NULL
};

static struct IntuiText yes = {
	0 , 1 , JAM1 , 6 , 4 , NULL , (UBYTE *) "Yes" , NULL
};

static struct IntuiText ok = {
	0 , 1 , JAM1 , 7 , 4 , NULL , (UBYTE *) "OK" , NULL
};

static struct IntuiText no = {
	0 , 1 , JAM1 , 7 , 4, NULL , (UBYTE *) "No" , NULL
};

dump_screen(s , bx , by , width , height)
struct Screen *s;
{
	register struct IODRPReq *req = &request;
	struct RastPort *drp = &rp;
	int result;
	int i;

	if (s->FirstWindow == NULL) DisplayBeep(s);
	else {
		close_mask = 0;
		ScreenToFront(s);
		Delay(30L);
		ScreenToFront(w->WScreen);
		result = AutoRequest(w,&ru_sure,&yes,&no,0L,0L,200L,60L);
		if (!result) return;
		InitRastPort(&rp);
		InitBitMap(&bm,(long)s->BitMap.Depth,(long)width,(long)height);
		rp.BitMap = &bm;
		for (i = 0 , rast_count = 0; i < s->BitMap.Depth; i++) {
			bm.Planes[i] = AllocRaster((long) width,(long) height);
			if (!bm.Planes[i]) {
				free_rasters(width , height);
				result = AutoRequest(w,&no_mem, &yes,&no,0L,0L,300L,60L);
				if (!result) return;
				drp = &s->RastPort;
				break;
			}
			rast_count++;
		}
		if (drp == &rp) {
			Delay(60L);
			ClipBlit(&s->RastPort,(long)bx,(long)by,drp,0L,0L,(long)width,(long)height,0xC0L);
			bx = by = 0;
		}
		if ((pport = CreatePort(NULL , 0L)) == NULL) {
			(void) AutoRequest(w,&no_port,&ok,NULL,0L,0L,300L,60L);
			close_down_printer(width , height);
			return;
		}
		close_mask |= PPORT;
		if (OpenDevice("printer.device",0L,req,0L)) {
			(void) AutoRequest(w,&no_lp,&ok,NULL,0L,0L,300L,60L);
			close_down_printer(width , height);
			return;
		} 
		close_mask |= PRINTER;
		req->io_Message.mn_ReplyPort = pport;
		req->io_Command = PRD_DUMPRPORT;
		req->io_RastPort = drp;
		req->io_ColorMap = s->ViewPort.ColorMap;
		req->io_Modes    = s->ViewPort.Modes;
		req->io_SrcX = bx; req->io_SrcY = by;
		req->io_DestCols = req->io_SrcWidth = width;
		req->io_DestRows = req->io_SrcHeight = height;
		req->io_Special = 0x8C;
		DoIO(req);
		close_down_printer(width , height);
	}
}

close_down_printer(w , h)
{
	while (GetMsg(pport));
	free_rasters(w , h);
	if (close_mask & PRINTER) CloseDevice(&request);
	if (close_mask & PPORT) DeletePort(pport);
}

free_rasters(width , height)
{
	register int i;

	for (i = 0; i < rast_count; i++) FreeRaster(bm.Planes[i] , (long) width , (long) height);
}

