[mod.amiga.sources] ScreenDump.c

doc@pucc-j.UUCP (08/12/86)

Reply-To: ihnp4!cbmvax!carolyn (Carolyn Scheppner)

/**************************************************************************
*  ScreenDump.c --  Dump RastPort of highest screen/window to printer
*                    by Carolyn Scheppner  CBM  02/86
*
* Linkage information:
* FROM     LStartup.obj, ScreenDump.o
* TO       ScreenDump
* LIBRARY  LC.lib, Amiga.lib
***************************************************************************/

#include <exec/types.h>
#include <exec/memory.h>
#include <libraries/dos.h>
#include <graphics/gfxbase.h>
#include <graphics/rastport.h>
#include <graphics/gfx.h>
#include <graphics/view.h>

#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>

#include <devices/printer.h>
#include <lattice/stdio.h>

struct IntuitionBase *IntuitionBase;
struct GfxBase       *GfxBase;

struct Window   *firstWindow, *nextWindow, *highWindow;
struct Screen   *firstScreen, *nextScreen, *highScreen;

struct ViewPort *viewPort;
struct RastPort *rastPort;
struct ColorMap *colorMap;

SHORT  topEdge;

BOOL   Borderless, WindowPrint, Relative, pOpened;
int    dLeft, dRight, dTop, dBottom;   /* default border adjustments */
int    bLeft, bRight, bTop, bBottom;   /* current border adjustments */
int    srcX, srcY, srcWidth, srcHeight;
int    destCols, destRows, special;
int    openError, dumpError, multiplier, i;
char   sbuf[80], ch;

struct MsgPort   *printerPort;

union  printerIO {
	struct IOStdReq    ios;
	struct IODRPReq    iodrp;
	struct IOPrtCmdReq iopc;
};

union printerIO  *request;


/* main */

main()
{
	if ((IntuitionBase =
	    (struct IntuitionBase *)OpenLibrary("intuition.library",0))==NULL)
		cleanexit("Can't open Intuition.\n");

	if ((GfxBase =
	    (struct GfxBase *)OpenLibrary("graphics.library",0))==NULL)
		cleanexit("Can't open Graphics.\nn");


	/* Printer stuff */
	pOpened = FALSE;
	printerPort = (struct MsgPort *)CreatePort("myPrtPort",0);
	if(printerPort == NULL)  cleanexit("Can't open printer port.\n");

	request = (union printerIO *)CreateExtIO(printerPort,
	sizeof(union printerIO));
	if(request == NULL)  cleanexit("Can't allocate ExtIO.\n");

	openError = OpenPrinter(request);
	if(openError)  cleanexit("Can't open printer.\n");
	pOpened = TRUE;
	/* */

	printf("\n>> SCREENDUMP <<       C. Scheppner     CBM  02/86\n");
	printf("\nDefault settings: Full Image, Relative Size Output\n");

	WindowPrint = FALSE;
	Borderless  = FALSE;
	Relative   = TRUE;
	dLeft   = 2;                  /* defaults for Borderless option */
	dRight  = 2;
	dTop    = 10;
	dBottom = 10;
	multiplier = 125;             /* default for Relative calculation */

	newImage();        /* get pointers to rastport, etc */

	do {
		printf("\nSELECT: <P>rint, <I>mageOpts, <O>utputOpts,");
		printf(" <N>ewImage or <Q>uit ? ");
		getLch();
		if (ch =='p')       doPrint();
		else if (ch =='i')  doImOpts();
		else if (ch =='o')  doOutOpts();
		else if (ch =='n')  newImage();
	}
	while (ch != 'q');

	cleanup();
}

/*--------------------------------------------------------------------*/

newImage()
{
	printf("\nNEW IMAGE: <W>indow or <S>creen ? ");
	getLch();
	if (ch =='w')
	{
		WindowPrint = TRUE;
		printf("\nMove Screens so Windows's Screen is highest.\n");
		printf("Move Windows so Window to print is highest.\n");
	}
	else if (ch =='s')
	{
		WindowPrint = FALSE;
		printf("\nMove Screens so Screen to print is highest.\n");
	}
	ch = NULL;

	printf("\nClick here and press <RET> when ready: ");
	getLch();

	getPointers();
}


getPointers()
{
	Forbid();
	firstScreen  = IntuitionBase->FirstScreen;
	topEdge = 400;
	nextScreen = highScreen = firstScreen;
	while( nextScreen != NULL )
	{
		if(nextScreen->TopEdge < topEdge)
		{
			topEdge = nextScreen->TopEdge;
			highScreen = nextScreen;
		}
		nextScreen = nextScreen->NextScreen;
	}

	if(WindowPrint)
	{
		firstWindow = highScreen->FirstWindow;
		topEdge = 400;
		nextWindow = highWindow = firstWindow;
		while( nextWindow != NULL )
		{
			if(nextWindow->TopEdge < topEdge)
			{
				topEdge = nextWindow->TopEdge;
				highWindow = nextWindow;
			}
			nextWindow = nextWindow->NextWindow;
		}
	}
	Permit();

	viewPort = &(highScreen->ViewPort);
	colorMap = viewPort->ColorMap;
	rastPort = &(highScreen->RastPort);

	getCoords();
}


getCoords()
{
	if(WindowPrint)   /* if Borderless == FALSE, b variables = 0 */
	{
		srcX = highWindow->LeftEdge + bLeft;
		srcY = highWindow->TopEdge + bTop;
		srcWidth  = highWindow->Width -bLeft - bRight;
		srcHeight = highWindow->Height -bTop - bBottom;
	}
	else      /* screen print */
	{
		srcX = bLeft;
		srcY = bTop;
		srcWidth  = viewPort->DWidth -bLeft - bRight;
		srcHeight = viewPort->DHeight - bTop - bBottom;
	}
	if (Relative == TRUE)
	{
		doRelativeSize();
	}
}


doImOpts()
{
	printf("\nIMAGE OPTS: <F>ull, <B>orderless, or <O>ther ? ");
	getLch();
	if (ch == 'f')
	{
		Borderless = FALSE;
		bLeft = bRight = bTop = bBottom = 0;
		getCoords();
	}
	else if (ch == 'b')
	{
		Borderless = TRUE;

		printf("\nBORDERS: Change default borders <Y> or <N> ? ");
		getLch();
		if (ch == 'y')
		{
			printf("\nBORDER ADJUSTMENTS: Enter new value or press <RET>\n");
			dLeft   = promptInt("Left",dLeft);
			dRight  = promptInt("Right",dRight);
			dTop    = promptInt("Top",dTop);
			dBottom = promptInt("Bottom",dBottom);
		}
		bLeft   = dLeft;
		bRight  = dRight;
		bTop    = dTop;
		bBottom = dBottom;
		getCoords();
		ch = NULL;
	}
	else if (ch == 'o')
	{
		otherImOpts();
	}
	ch = NULL;
}   


otherImOpts()
{
	printf("\nOTHER IMAGE OPTIONS:\n");
	printf(" CURRENT OPTIONS: ");
	if (!Borderless) printf("Full ");
	else printf("Borderless ");
	if (!WindowPrint) printf("Screen\n");
	else printf("Window\n");

	printf("\nCURRENT VALUES: Enter new value or press <RET>\n");
	srcX = promptInt("SrcX",srcX);
	srcY = promptInt("SrcY",srcY);
	srcWidth  = promptInt("SrcWidth",srcWidth);
	srcHeight = promptInt("SrcHeight",srcHeight);
}


doOutOpts()
{
	printf("\nOUTPUT OPTS: <S>mall, <M>edium, <L>arge,");
	printf(" <R>elative or <O>ther ? ");
	getLch();

	if (ch == 's')
	{
		Relative = FALSE;
		special  = SPECIAL_FRACCOLS|SPECIAL_ASPECT;
		destCols = 0x55555555;    /* 1/3 size */
		destRows = 0;
	}
	else if (ch == 'm')
	{
		Relative = FALSE;
		special  = SPECIAL_FRACCOLS|SPECIAL_ASPECT;
		destCols = 0xaaaaaaaa;    /* 2/3 size */
		destRows = 0;
	}
	else if (ch == 'l')
	{
		Relative = FALSE;
		special  = SPECIAL_FULLCOLS|SPECIAL_ASPECT;
		destCols = 0;
		destRows = 0;
	}
	else if (ch == 'r')
	{
		askMultiplier();
		doRelativeSize();
	}
	else if (ch == 'o')
	{
		otherOutOpts();
	}
	ch = NULL;
}   


askMultiplier()
{
	printf("\nRELATIVE: Change default multiplier <Y> or <N> ? ");
	getLch();
	if (ch == 'y')
	{
		printf("\nMULTIPLIER: Enter new value or press <RET>\n");
		multiplier = promptInt("Multiplier",multiplier);
	}
	ch = NULL;
}


doRelativeSize()
{
	Relative = TRUE;
	special  = SPECIAL_ASPECT|SPECIAL_MILCOLS;
	destCols = (int) srcWidth * multiplier / 10;
	if ((viewPort->Modes & HIRES) == NULL) destCols = destCols * 2;
	destRows = 0;
}


otherOutOpts()
{
	printf("\nSpecial Flags Available:\n");
	printf(" MILCOLS   0x001   DestCols specified in 1/1000 inch\n");
	printf(" MILROWS   0x002   DestRows specified in 1/1000 inch\n");
	printf(" FULLCOLS  0x004   Make DestCols maximum possible\n");
	printf(" FULLROWS  0x008   Make DestRows maximum possible\n");
	printf(" FRACCOLS  0x010   DestCols is fraction of FULLCOLS\n");
	printf(" FRACROWS  0x020   DestRows is fraction of FULLROWS\n");
	printf(" ASPECT    0x080   Ensure correct aspect ratio\n");
	printf(" DENSITY1  0x100   Lowest Res\n");
	printf(" DENSITY2  0x200   Next Res\n");
	printf(" DENSITY3  0x400   Next Res\n");
	printf(" DENSITY4  0x800   Highest Res\n");
	printf(" MASK      0xF00   Mask out density bits\n");

	printf("\nCURRENT VALUES: Enter new value or press <RET>\n");
	destCols = promptInt("DestCols",destCols);
	destRows = promptInt("DestRows",destRows);
	special  = promptInt("Special",special);
}


promptInt(stp,value)   /* Prompt for and input new value */
char   *stp;
int    value;
{
	printf(" %s = %ld  [ Hex 0x%lx ]   New value ? ",stp,value,value);
	value = getInt(value);
	return(value);
}

getLch()     /* ch = input char converted to lower case or NULL */
{
	gets(&sbuf[0]);
	if ((ch=(sbuf[0])) != NULL)  ch = ch|0x20;
}

getInt(value)         /* Get decimal or hex (0xnnnn) value */
int value;            /* If none entered, return previous  */
{
	int count;

	gets(&sbuf[0]);
	if (sbuf[0] != NULL)
	{
		if ((sbuf[1]|0x20) =='x') count = stch_i(&sbuf[2],&value);
		else count = stcd_i(&sbuf[0],&value);
	}
	return(value);
}



doPrint()
{
	printf("\nPrinting will start in 10 seconds.\n");
	printf(" ( Time to hide this window, etc. )\n\n");
	for(i=0;i<10*60;i++) WaitTOF();  /* 10 second delay */

	/* Printer stuff */
	dumpError = DumpRPort( request,
	rastPort,
	colorMap,
	viewPort->Modes,
	srcX,                       /* RastPort offsets */
	srcY,
	srcWidth,                   /* origin sizes  */
	srcHeight,
	destCols,                   /* printed sizes */
	destRows,
	special );                  /* io_Special */

	if (dumpError)  printf("\n Can't Dump. PDERR = %ld\n",dumpError);
}


cleanexit(errMsg)
char *errMsg;
{
	printf(errMsg);
	cleanup();
	exit(-1);
}

cleanup()
{
	pcleanup();
	if (IntuitionBase)     CloseLibrary(IntuitionBase);
	if (GfxBase)           CloseLibrary(GfxBase);
}

pcleanup()
{
	if (pOpened)           ClosePrinter(request);
	if (printerPort)       DeletePort(printerPort);
	if (request)           DeleteExtIO(request);
}


/************************************************************************/
/* printersupport.c rtns  for example page 3-202  1.1 Rom Kernel manual */
/************************************************************************/

#include        "exec/types.h"
#include        "exec/nodes.h"
#include        "exec/lists.h"
#include        "exec/ports.h"
#include        "exec/tasks.h"
#include        "exec/io.h"
#include        "devices/printer.h"


/*  This union is defined above in my main
    If you are compiling these rtns separately,
     uncomment this union definition

union printerIO {
       struct IOStdReq ios;
       struct IODRPReq iodrp;
       struct IOPrtCmdReq iopc;
       };
*/


/* OPEN THE PRINTER */
int
OpenPrinter(request)
union printerIO *request;
{
	return(OpenDevice("printer.device",0,request,0));
}


/* CLOSE THE PRINTER */
int
ClosePrinter(request)
union printerIO *request;
{
	CloseDevice(request);
	return(0);
}


/* Send a NULL terminated string to the printer
 * Assumes printer device is open and printerMsg
 * is correctly initialized.  Watches for embedded
 * "escape-sequences" and handles them as defined.
 */

int
PrintString(request,string)
union printerIO *request;
char *string;
{
	request->ios.io_Command = CMD_WRITE;
	request->ios.io_Data = (APTR)string;
	request->ios.io_Length = -1;
	/* if -1, the printer assumes it has been given
	    * a null terminated string.
	    */
	return(DoIO(request));
}


/* Send RAW character stream to the printer directly,
 * avoid "escape-sequence" parsing by the device.
 */
int
PrintRaw(request,buffer,count)
union printerIO *request;  /* a properly initialized request block */
char *buffer;              /* where is the output stream of characters */
int count;                 /* how many characters to output */
{
	/* queue a printer raw write */
	request->ios.io_Command = PRD_RAWWRITE;
	request->ios.io_Data = (APTR)buffer;
	request->ios.io_Length = count;

	return(DoIO(request));
}


/* Send Printer Command */
int
PrintCommand(request,command, p0, p1, p2, p3)
union printerIO *request;
int command, p0, p1, p2, p3;    /* command and its parameters */
{
	/* queue a printer command */
	request->iopc.io_Command = PRD_PRTCOMMAND;
	request->iopc.io_PrtCommand = command;
	request->iopc.io_Parm0 = p0;
	request->iopc.io_Parm1 = p1;
	request->iopc.io_Parm2 = p2;
	request->iopc.io_Parm3 = p3;
	return(DoIO(request));
}


/* Dump RastPort */
int
DumpRPort(request,rastPort, colorMap, modes, sx,sy, sw,sh, dc,dr, s)
union printerIO *request;
struct RastPort *rastPort;
struct ColorMap *colorMap;
ULONG modes;
UWORD sx, sy, sw, sh;
LONG dc, dr;
UWORD s;
{
	request->iodrp.io_Command = PRD_DUMPRPORT;
	request->iodrp.io_RastPort = rastPort;
	request->iodrp.io_ColorMap = colorMap;
	request->iodrp.io_Modes = modes;
	request->iodrp.io_SrcX = sx;
	request->iodrp.io_SrcY = sy;
	request->iodrp.io_SrcWidth = sw;
	request->iodrp.io_SrcHeight = sh;
	request->iodrp.io_DestCols = dc;
	request->iodrp.io_DestRows = dr;
	request->iodrp.io_Special = s;
	return(DoIO(request));
}