[comp.sources.amiga] v02i076: gimme.lib - misc library routines, Part03/07

page@swan.ulowell.edu (Bob Page) (12/02/88)

Submitted-by: oscvax!jan@uunet.UU.NET (Jan Sven Trabandt)
Posting-number: Volume 2, Issue 76
Archive-name: libraries/gimme.3

#	This is a shell archive.
#	Remove everything above and including the cut line.
#	Then run the rest of the file through sh.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar:    Shell Archiver
#	Run the following text with /bin/sh to create:
#	DOCS.part3
#	test.c
#	GIMMELIB.DOC
#	Makefile
#	README
#	TODO
#	USENET.NOTE
#	dme.refs
#	tags
# This archive created: Thu Dec  1 19:45:59 1988
cat << \SHAR_EOF > DOCS.part3
 *
 * INPUTS:	struct timerequest  *tr;	pointer to a time-request
 *
 * DESCRIPTION: Stop (abort) a "master" or "slave" time-request.
 *
 * RESULTS:	Returns zero if ok, or non-zero ala AbortIO() on error.
 *
 * SEE ALSO:	gimmeTimeRequest, getRidOfTimeRequest, accessTimer, releaseTimer
 */

/*
 * NAME:	getSysTime
 *
 * REQUISITES:	struct Device *TimerBase;	    properly initialized
 *
 * SYNOPSIS:	err = getSysTime( secs, micros, mytr );
 *		short err;
 *
 * INPUTS:	ULONG		    *secs;	ptr for storing #seconds
 *		ULONG		    *micros;	ptr for storing #microseconds
 *		struct timerequest  *mytr;	ptr to a time-request, or NULL
 *
 * DESCRIPTION: Get the system time, placing it into the timeval struct
 *		pointed at by "tv".
 *		If mytr is non-NULL, that time-request is used, otherwise
 *		a "master" time request is created and destroyed internally.
 *
 *		NOTE: you must have a global variable named TimerBase,
 *		declared as a "struct Device *", which should be properly
 *		initialized if you supply a valid non-NULL mytr. Otherwise
 *		the TimerBase will be initialized when a temporary timerequest
 *		is created by this routine.
 *		If you supply a non-NULL mytr parameter, you should have done
 *		one of the following to initialize the TimerBase,
 *		by extracting the "library" pointer from the timer.device
 *		with code similar to the following:
 *		either 1)   struct timerequest *tr;
 *			    tr = accessTimer(<appropriate parms>);
 *
 *		    or 2)   struct timerequest tr;
 *			    err = OpenDevice(TIMERNAME, <unit-no>, &tr, 0L);
 *			    { check for error }
 *			    TimerBase = tr.tr_node.io_Device;
 *
 * RESULTS:	Returns non-zero on error.
 *		Note that the seconds and microseconds are stored where the
 *		respective parameters point to.
 *
 * SEE ALSO:	accessTimer, releaseTimer
 */

/*
 * NAME:	setSysTime
 *
 * REQUISITES:	struct Device *TimerBase;	    properly initialized
 *
 * SYNOPSIS:	err = setSysTime( secs, micros, mytr );
 *		short err;
 *
 * INPUTS:	ULONG		    secs;	seconds since Jan 1, 1978
 *		ULONG		    micros;	microseconds to set
 *		struct timerequest  *mytr;	ptr to a time-request, or NULL
 *
 * DESCRIPTION: Set the system time according to the number of seconds
 *		since (previous midnight) of January 1st, 1978.
 *		If mytr is non-NULL, that time-request is used, otherwise
 *		a "master" time request is created and destroyed internally.
 *
 *		NOTE: you must have a global variable named TimerBase,
 *		declared as a "struct Device *", which should be properly
 *		initialized if you supply a valid non-NULL mytr. Otherwise
 *		the TimerBase will be initialized when a temporary timerequest
 *		is created by this routine.
 *		If you supply a non-NULL mytr parameter, you should have done
 *		one of the following to initialize the TimerBase,
 *		by extracting the "library" pointer from the timer.device
 *		with code similar to the following:
 *		either 1)   struct timerequest *tr;
 *			    tr = accessTimer(<appropriate parms>);
 *
 *		    or 2)   struct timerequest tr;
 *			    err = OpenDevice(TIMERNAME, <unit-no>, &tr, 0L);
 *			    { check for error }
 *			    TimerBase = tr.tr_node.io_Device;
 *
 * RESULTS:	Returns non-zero on error.
 *
 * SEE ALSO:	accessTimer, releaseTimer
 */

/*
 * NAME:	gimmeNewWindow
 *
 * SYNOPSIS:	nw = gimmeNewWindow( title, screen, leftedge, topedge,
 *						IDCMPflags, flags );
 *		struct NewWindow *nw;
 *
 * INPUTS:	UBYTE	*title; 	    title string
 *		struct Screen	*screen;    ptr to Intuition screen, or NULL
 *		SHORT	leftedge;	    offset of left edge in pixels
 *		SHORT	topedge;	    offset of right edge in pixels
 *		ULONG	IDCMPflags;	    IDCMP flags ala nw->IDCMPFlags field
 *		ULONG	flags;		    window flags ala nw->Flags field
 *
 * DESCRIPTION: Allocate and initialize a NewWindow structure.
 *		Max width and height is taken from screen or WorkBench screen.
 *		Initial width and height is set to largest possible with
 *		regards to leftedge and topedge.
 *
 *		Note: if SUPER_BITMAP is specified, a BitMap will NOT be
 *		allocated here -- gimmeWindow will do that.
 *		You can customize the NewWindow structure before opening
 *		the window.
 *
 * RESULTS:	Returns pointer to NewWindow structure, or NULL on error.
 *
 * SEE ALSO:	getRidOfNewWindow, gimmeWindow, getRidOfWindow
 */

/*
 * NAME:	getRidOfNewWindow
 *
 * SYNOPSIS:	err = getRidOfNewWindow( nw );
 *		short err;
 *
 * INPUTS:	struct NewWindow    *nw;	pointer to NewWindow structure
 *
 * DESCRIPTION: De-allocate a NewWindow structure that was dynamically
 *		allocated by gimmeNewWindow.
 *
 * RESULTS:	Returns non-zero on error.
 *
 * SEE ALSO:	gimmeNewWindow, gimmeWindow, getRidOfWindow
 */

/*
 * NAME:	gimmeWindow
 *
 * SYNOPSIS:	window = gimmeWindow( nw, depth, width, height );
 *		struct Window *window;
 *
 * INPUTS:	struct NewWindow    *nw;	    ptr to initialized NewWindow
 *		SHORT	depth, width, height;	    dimensions for bitmap
 *
 * DESCRIPTION: Open an Intuition window.
 *		If the NewWindow pointer "nw" in NULL, then a default NewWindow
 *		structure is temporarily created, used and deleted
 *		(see gimmelib/window.h for the default flags used).
 *		If SUPER_BITMAP is NOT specified in the nw->Flags field,
 *		depth, width and height are ignored (however, set them to 0
 *		for future compatability).
 *
 *		Otherwise: a bitmap is allocated and linked into nw.
 *		If the bitmap allocation fails, no window will be opened.
 *		If all goes well, the pointer to the BitMap is stored in the
 *		window->UserData field. You must preserve this pointer!!
 *		If you need to use the UserData yourself, be sure to save
 *		window->UserData somewhere safe after calling gimmeWindow.
 *		When you are done with the window you must ensure that the
 *		bitmap pointer is restored into window->UserData and then
 *		call getRidOfWindow.
 *
 * RESULTS:	Returns a pointer to an open Intuition window, or NULL if
 *		anything went wrong.
 *
 * SEE ALSO:	getRidOfNewWindow, gimmeWindow, getRidOfWindow, gimmeBitMap
 */

/*
 * NAME:	getRidOfWindow
 *
 * SYNOPSIS:	err = getRidOfWindow( window );
 *		short err;
 *
 * INPUTS:	struct Window	*window;	pointer to Intuition window
 *
 * DESCRIPTION: Close a window, clearing the menustrip and replying to any
 *		outstanding messages on its UserPort first.
 *		If it is a SUPER_BITMAP window, also calls getRidOfBitMap
 *		using the bitmap pointer in window->UserData -- see details
 *		in description of gimmeWindow.
 *
 * RESULTS:	Returns non-zero on error.
 *
 * SEE ALSO:	gimmeNewWindow, getRidOfNewWindow, gimmeWindow, getRidOfBitMap
 */

SHAR_EOF
cat << \SHAR_EOF > test.c
#include <stdio.h>
#include "gimmelib/gimmeall.h"
#define GIM_BUILTIN
#include "gimmelib/macros.h"

/***
 *  NOTE: graphing from a subtask does not work
 *  unfortunately I haven't figured out why yet!!
 *
 *
 *  this looks more complicated than it is --
 *  it's just that there are a lot of options for different features to demo
 *  just think of all the left-aligned if-statements, like this:
 *	if( COLOR ) {
 *	    ...
 *	} comment COLOR comment
 *  as equivalent to
 *	#ifdef COLOR
 *	    ...
 *	#endif COLOR
 *
 *  As a matter of fact, that's what they were but I hated recompiling
 *  all the time for different options, so I changed them.
 */


#define SBMDEPTH	3

#define IDCMP_FLAGS	(CLOSEWINDOW | GADGETUP | GADGETDOWN | MENUPICK)
#define WIN_FLAGS	(ACTIVATE | BACKDROP | BORDERLESS | WINDOWCLOSE \
			    | SMART_REFRESH | NOCAREREFRESH | RMBTRAP)

#define STDSTUFF	(GSS_INTUITION | GSS_GFX | GSS_DISKFONT | GSS_TIMER \
			    | GSS_SUBTASK | GSS_MEMCHAIN | GSS_DISABLEABORT)

#define SYS_GADG	0	/* system gadget -- do not use for my IDs */
#define BOOL_GADG	1
#define CLEAR_GADG	2
#define BOOL_TOG_GADG	3
#define BOOL_IMAG_GADG	4
#define STRING_GADG	5
#define STRING_INT_GADG 6
#define PROP_H_GADG	7
#define PROP_V_GADG	8
#define H_SCROLLBAR	9
#define V_SCROLLBAR	10
#define ONESCROLL1	100	/* secondary gadgets */
#define ONESCROLL2	101

#define MAX_GADG	10
#define FIRST_GADG	BOOL_GADG-1

#define DI_Z		2	/* size of image data below */
#define DI_X		64
#define DI_Y		5

USHORT firstImageData[] = {		/* garbage image */
    0x0110, 0x3420, 0x7862, 0xefca,
    0x0110, 0x3420, 0x7862, 0xefca,
    0x0110, 0x3420, 0x7862, 0xefca,
    0x0110, 0x3420, 0x7862, 0xefca,
    0x0110, 0x3420, 0x7862, 0xefca,

    0x0435, 0x3428, 0x7092, 0xe97a,
    0x0110, 0x3440, 0x7062, 0xef34,
    0x2340, 0x3445, 0x7060, 0xef4a,
    0x0150, 0x3420, 0x7862, 0xe4ca,
    0x0140, 0x6520, 0x7782, 0xef56
  };

struct TextAttr ta = {
    (STRPTR) "topaz.font",
    9,
    FS_NORMAL,
    FPF_DISKFONT
  };

NEWGRAPH newgraph = {
    (UBYTE *) "GIMME GRAPH", (UBYTE *) "howdy! any luck?",
    (UBYTE *) "MONEY $$$",
    NULL, NULL, &ta,
    GIM_RED, GIM_BLACK, GIM_CYAN, GIM_YELLOW,
    GGR_FILLTOX | GGR_BLACKTOX | GGR_X_SPACING | GGR_Y_MAX,
    GGR_INITORIGIN | GGR_HIRES | GGR_NOCLEARSTART,
    {70, 200,  0, 2,  0,  0, 1, 1},
    {100, 60,  0, 100,	0,  0, 2, 1},
    NULL
  };

#define NUM_COORDS1	5
SHORT graphData[NUM_COORDS1][2] = {
    03, 10,
    16, 25,
    29, 40,
    48, 90,
    82, 30
  };

struct Screen *Screen = NULL;
struct Window *BackWindow = NULL;
struct Window *MyWindow = NULL;
struct Window *SubWindow = NULL;
struct BitMap *secbm = NULL;
SHORT SWidth = 0, SHeight = 0;
ULONG winflags = WIN_FLAGS;

struct Gadget *gadg[MAX_GADG];		/* initialize later */
struct Requester *request = NULL;

struct TextFont *tf = NULL;

struct IOStdReq *inputIOreq = NULL;

GRAPH *mygraph = NULL;
struct Task *mysubtask = NULL;
struct Menu *menustrip = NULL;


BYTE COLOR = 0, FONT = 0, GADGET = 0, MENU = 0, MYGRAPH = 0, POSTEXT = 0;
BYTE REQUESTER = 0, SUBTASK = 0, TIMER = 0, WINDOW = 0;
BYTE DBUF = 0, INPHAND = 0;


/* forward declarations */
struct Screen *initscreen();
HandlerInterface();
subtaskRoutine();


main( argc, argv )
    int argc;
    char **argv;
{
    register char   *temp;
    char	    *fontname = NULL;
    SHORT	    fontsize = 0;
    register SHORT  i;

    if( argc < 2 ) {
	help( argc, argv );
    } else {
	for( i = 1; i < argc; ++i ) {
	    temp = argv[i];
	    if( *temp == '-' ) {
		++temp;
next_flag: {}
		switch( tolower(*temp) ) {
		  case 'c':
		    COLOR = 1; break;
		  case 'd':
		    DBUF = 1; break;
		  case 'f':
		    FONT = 1; break;
		  case 'g':
		    GADGET = 1; break;
		  case 'h':
		  case '?':
		    help(); break;
		  case 'i':
		    INPHAND = 1; break;
		  case 'j':
		    MYGRAPH = 1; break;
		  case 'm':
		    MENU = 1; break;
		  case 'p':
		    POSTEXT = 1; break;
		  case 'r':
		    REQUESTER = 1; break;
		  case 's':
		    SUBTASK = 1; break;
		  case 't':
		    TIMER = 1; break;
		  case 'w':
		    WINDOW = 1; break;
		  default:
		    printf("unknown option '%c' ignored\n", *temp);
		    break;
		} /* switch */
		if( *(++temp) ) {
		    goto next_flag;
		}
	    } else if( !fontname ) {
		fontname = temp;
		if( argv[i+1][0] != '-' ) {
		    fontsize = atoi( argv[++i] );
		}
	    } else {
		help( argc, argv );
	    }
	} /* for */
    }
    if( fontname ) {
	ta.ta_Name = (STRPTR) fontname;
	if( fontsize ) {
	    ta.ta_YSize = fontsize;
	}
    }
    if( !openStuff() ) {
	runIt( argc, argv, BackWindow );
    }
    cleanUp();
} /* main */


help( argc, argv )
    int argc;
    char **argv;
{
    printf( "Usage: %s -cdfgihjmprstw? [name.font [size]]\n"
	    "     -c    : color (use gimme.lib palette)\n"
	    "     -d    : double buffer screen (not too pretty w/ Intuition)\n"
	    "     -f    : font (use another font)\n"
	    "     -g    : gadget\n"
	    "     -h    : help -- this info (also -?)\n"
	    "     -i    : input handler (make RMB work like LMB)\n"
	    "     -j    : graph Jan Sven\n"
	    "     -m    : menu\n"
	    "     -p    : postext (position text routine demo)\n"
	    "     -r    : requester\n"
	    "     -s    : subtask\n"
	    "     -t    : timer\n"
	    "     -w    : window\n"
	    "  note: mix&match options to demo features of gimme.lib\n",
	    argv[0]);
    exit( 0 );
} /* help */


openStuff()
{
    struct NewWindow	*nw;
    struct Gadget	*gp;
    struct Image	*ip;
    struct Window	*tempw;
    struct MenuItem	*menuitem;
    ULONG		flag;
    SHORT		x, y;
    register SHORT	i;

    flag = gimmeStdStuff( STDSTUFF, GSS_REVISION );
    if( flag ) {
	printf("openStuff: can't open standard thing for flag 0x0%lx\n", flag);
	return( -1 );
    }
if( FONT ) {
    if( !(tf = gimmeFont(&ta)) ) {      /* note: this updates ta.ta_YSize */
	printf("openStuff: can't open font '%s' size %d\n",
		    ta.ta_Name, ta.ta_YSize);
	return( -1 );
    }
} /* FONT */

if( MENU ) {
    winflags &= ~RMBTRAP;
} /* MENU */
    if( !(Screen = initscreen(&BackWindow)) ) {
	SystemError("can't open screen/window\n");
    }
if( COLOR ) {
    setColors( Screen, NULL, 1 << SBMDEPTH );
} /* COLOR */

if( MENU ) {
    menustrip = gimmeMenu( &gimChainMem, 0, -1, "Options", MENUENABLED );
    menuitem = gimmeMenuItem( &gimChainMem, 0, -1, -1, 'Q',
			"Quit", tf ? &ta : NULL,
			ITEMTEXT | COMMSEQ | ITEMENABLED | HIGHCOMP );
    if( addMenuItem(menustrip, menuitem, 0, 0, 1, GMI_DEFAULT) == MENUNULL ) {
	SystemError("can't setup menu strip\n");
    }
    SetMenuStrip( BackWindow, menustrip );
} /* MENU */

if( WINDOW ) {
    nw = gimmeNewWindow( "howdy", Screen, 310, 100,
			    IDCMP_VSMART, FLAGS_VSMART );
    if( !nw ) {
	SystemError("can't get new window\n");
    }
    nw->Width = 300;
    nw->Height = 100;
    if( !(MyWindow = gimmeWindow(nw, 0, 0, 0)) ) {
	getRidOfNewWindow( nw );
	SystemError("can't open window\n");
    }
    getRidOfNewWindow( nw );
} /* WINDOW */

if( SUBTASK ) {
    /* give it a 5K stack and 1K data area */
    if( !(mysubtask = gimmeSubTask(&gimSubTasks, &gimMainPort, 5000L,
					1000L, NULL)) ) {
	SystemError("can't setup for subtask\n");
    }
    strcpy( mysubtask->tc_UserData, "guess what? I am a subtask!" );
} /* SUBTASK */

if( DBUF ) {
    /* double-buffering isn't the greatest thing with Intuition trying to
     * display things too
     */
    if( makeDBuf(Screen, &secbm) ) {
	printf("can't make second buffer\n");
    }
    swapDBuf( Screen, GIM_MINTERM_COPY );   /* so Intuition draws up front */
    swapDBuf( Screen, GIM_MINTERM_DEST );
} /* DBUF */


    /* always initialize gadg[] array */
    for( i = FIRST_GADG; i < MAX_GADG; ++i ) {
	gadg[i] = NULL;
    } /* for */

if( REQUESTER ) {
    SetBPen( BackWindow->RPort, (ULONG) GIM_RED );
    SetDrMd( BackWindow->RPort, (ULONG) JAM2 );
} /* REQUESTER */

    /* always create these two gadgets */
    gadg[BOOL_GADG-1] = gimmeBoolGadget( BackWindow, BOOL_GADG, 20, 20,
			    150, -1, "end", NULL, tf ? &ta : NULL,
			    GPT_DEFAULT | GPT_FULLWIDTH );
    if( !gadg[BOOL_GADG-1] ) {
	SystemError("can't make start gadget\n");
    }
    gadg[CLEAR_GADG-1] = gimmeBoolGadget( BackWindow, CLEAR_GADG, 20, 40,
			-1, -1, "clear", NULL, tf ? &ta : NULL, GPT_DEFAULT );
    if( !gadg[CLEAR_GADG-1] ) {
	SystemError("can't make clear gadget\n");
    }
if( REQUESTER ) {
    gadg[BOOL_GADG-1]->Activation |= ENDGADGET;
    gadg[BOOL_GADG-1]->GadgetType |= REQGADGET;
} /* REQUESTER */

if( GADGET ) {
    SetAPen( BackWindow->RPort, (ULONG) GIM_YELLOW );
    gadg[BOOL_TOG_GADG-1] = gimmeBoolGadget( BackWindow, BOOL_TOG_GADG, 200, 20,
		-1, -1, "toggle", "boolean", tf ? &ta : NULL, GPT_DEFAULT );
    SetAPen( BackWindow->RPort, (ULONG) GIM_WHITE );

    gadg[BOOL_IMAG_GADG-1] = gimmeBoolImageGadget( BackWindow, BOOL_IMAG_GADG,
			    290, 20, GOS_BITDEPTH, GOS_BITWIDTH, GOS_BITHEIGHT,
			    GPT_DEFAULT, DI_Z, DI_X, DI_Y );
    if( gadg[BOOL_IMAG_GADG-1] ) {
	gadg[BOOL_IMAG_GADG-1]->Flags = GADGIMAGE | GADGHNONE;
	gadg[BOOL_IMAG_GADG-1]->Activation = GADGIMMEDIATE;
	if( gadg[BOOL_IMAG_GADG-1]->GadgetRender ) {
	    copyDataImage( gimDataOneScrollLeft,
			(struct Image *) gadg[BOOL_IMAG_GADG-1]->GadgetRender );
	}
	if( gadg[BOOL_IMAG_GADG-1]->SelectRender ) {
	    copyDataImage( firstImageData,
			(struct Image *) gadg[BOOL_IMAG_GADG-1]->SelectRender );
	}
    }

    gadg[STRING_GADG-1] = gimmeStringGadget( BackWindow, STRING_GADG, 20, 70,
			    150, 20, "string", NULL, tf ? &ta : NULL,
			    GADGIMMEDIATE | RELVERIFY );
    gadg[STRING_INT_GADG-1] = gimmeStringGadget( BackWindow, STRING_INT_GADG,
			20, 110, 150, 20, "12345", "int gadg:", tf ? &ta : NULL,
			GADGIMMEDIATE | RELVERIFY | LONGINT );

    SetDrMd( BackWindow->RPort, (ULONG) JAM1 );
    gadg[PROP_H_GADG-1] = gimmePropGadget( BackWindow, PROP_H_GADG, 250, 50,
		    60, GOS_BITHEIGHT + 4, "horiz prop", tf ? &ta : NULL,
		    GADGIMMEDIATE | RELVERIFY, FREEHORIZ );
    if( ip = gimmeImage(&gadg[PROP_H_GADG-1]->UserData,
			    GOS_BITDEPTH, GOS_BITWIDTH, GOS_BITHEIGHT) ) {
	copyDataImage( gimDataOneScrollLeft, ip );
	gadg[PROP_H_GADG-1]->GadgetRender = (APTR) ip;
	((struct PropInfo *)gadg[PROP_H_GADG-1]->SpecialInfo)->Flags
				&= ~AUTOKNOB;
    }
    SetDrMd( BackWindow->RPort, (ULONG) JAM2 );

    gadg[PROP_V_GADG-1] = gimmePropGadget( BackWindow, PROP_V_GADG, 250, 70,
			    10, 50, "vert prop", tf ? &ta : NULL,
			    GADGIMMEDIATE | RELVERIFY,
			    FREEVERT | PROPBORDERLESS );

    /* note fullscrollbar returns a linked list of 3 gadgets */
    gadg[H_SCROLLBAR-1] = gimmeFullScrollBar( BackWindow, H_SCROLLBAR,
					    FREEHORIZ | KNOBHIT, GSB_DEFAULT,
					    ONESCROLL1+500, ONESCROLL2+500 );

    gadg[V_SCROLLBAR-1] = gimmeFullScrollBar( BackWindow, V_SCROLLBAR,
					    FREEVERT | KNOBHIT, GSB_DEFAULT,
					    ONESCROLL1, ONESCROLL2 );
    ((struct PropInfo *)gadg[V_SCROLLBAR-1]->SpecialInfo)->VertBody = 0x0fff;
} /* GADGET */

    /* link the gadgets */
    if( (gp = gadg[FIRST_GADG]) ) {
	for( i = FIRST_GADG + 1; i < MAX_GADG; ++i ) {
	    if( gadg[i] ) {
		gp->NextGadget = gadg[i];
		for( gp = gadg[i]; gp->NextGadget; gp = gp->NextGadget ) {
if( REQUESTER ) {
		    gp->GadgetType |= REQGADGET;
} /* REQUESTER */
		} /* for */
if( REQUESTER ) {
		gp->GadgetType |= REQGADGET;
} /* REQUESTER */
	    }
	} /* for */
    }

if( REQUESTER ) {
    SetBPen( BackWindow->RPort, (ULONG) GIM_BACKGROUND );
    SetDrMd( BackWindow->RPort, (ULONG) JAM1 );
} /* REQUESTER */


if( POSTEXT ) {
    tempw = MyWindow ? MyWindow : BackWindow;
    x = tempw->Width >> 1;
    y = tempw->Height >> 1;
    /* some weird horizontal text cropped on the borders */
    SetAPen( tempw->RPort, (long) GIM_RED );
    positionText( tempw->RPort, GPT_XLEFT | GPT_YCENTREBASE,
		    "left centbas", 0L, x, 0 );
    SetAPen( tempw->RPort, (long) GIM_BLUE );
    positionText( tempw->RPort, GPT_XCENTRE | GPT_YCENTRE,
		    "centre centre", 0L, x - 40, 0 );
    SetAPen( tempw->RPort, (long) GIM_GREEN );
    positionText( tempw->RPort, GPT_XRIGHT | GPT_YBOTTOM,
		    "right bot", 0L, x + 60, tempw->Height + 4 );
    /* some vertical text */
    SetAPen( tempw->RPort, (long) GIM_YELLOW );
    positionText( tempw->RPort, GPT_YTOP | GPT_YUPWARDS | GPT_XTHICKEN,
		    "dflt top", 0L, x, y );
    SetAPen( tempw->RPort, (long) GIM_CYAN );
    positionText( tempw->RPort, GPT_YCENTRE | GPT_YDOWNWARDS | GPT_XTHICKEN,
		    "dflt centre", 0L, x, y );
    SetAPen( tempw->RPort, (long) GIM_WHITE );
    positionText( tempw->RPort, GPT_YBOTTOM | GPT_YUPWARDS,
		    "dflt bot", 0L, x, y );
    SetAPen( tempw->RPort, (long) GIM_MAGENTA );
    Move( tempw->RPort, (long) x - 20, (long) y );
    Draw( tempw->RPort, (long) x + 20, (long) y );
    Move( tempw->RPort, (long) x, (long) y - 20 );
    Draw( tempw->RPort, (long) x, (long) y + 20 );
    SetAPen( tempw->RPort, (long) GIM_WHITE );
} /* POSTEXT */

if( MYGRAPH ) {
if( !SUBTASK ) {
    newgraph.rp = BackWindow->RPort;
    if( !(mygraph = gimmeGraph(&newgraph, NULL, NULL, NULL)) ) {
	printf("OpenStuff: couldn't open graph\n");
	MYGRAPH = 0;
    }
} /* !SUBTASK */
} /* MYGRAPH */

if( REQUESTER ) {
    request = gimmeRequester( &gimChainMem, 0, 0, -1, -1, GIM_RED,
			gadg[FIRST_GADG], "sample requester", &gimMyFont, 0L );
    if( !request ) {
	SystemError("can't get requester\n");
    }
    Request( request, BackWindow );
} else {
    if( gadg[FIRST_GADG] ) {
	AddGList( BackWindow, gadg[FIRST_GADG], -1L, -1L, NULL );
    }
    RefreshGadgets( gadg[FIRST_GADG], BackWindow, NULL );
} /* else !REQUESTER */

if( INPHAND ) {
    if( !(inputIOreq = addInputHandler(HandlerInterface, NULL, 51, NULL)) ) {
	printf("can't get input handler\n");
    }
} /* INPHAND */

    return( 0 );
} /* openStuff */


cleanUp()
{
    struct Gadget   *gp = NULL;
    ULONG	    flag;

    if( inputIOreq ) removeInputHandler( inputIOreq );
    if( mygraph ) getRidOfGraph( mygraph );
    if( BackWindow ) {
	gp = findMyFirstGadget( BackWindow->FirstGadget, SYS_GADG );
    }
    if( gp ) {
	RemoveGList( BackWindow, gp, -1L );
	getRidOfGadgets( gp );
    } else {
	if( gadg[FIRST_GADG] ) getRidOfGadgets( gadg[FIRST_GADG] );
    }
    if( MyWindow ) getRidOfWindow( MyWindow );
    if( Screen ) {
	if( secbm ) unmakeDBuf( Screen, &secbm, secbm );
	getRidOfScreen( Screen, BackWindow );
    }
    if( tf ) getRidOfFont( tf );
    if( flag = getRidOfStdStuff(GSS_CLOSEALL) ) {
	printf("cleanUp: can't close standard thing for flag 0x%0lx\n", flag);
	getRidOfStdStuff( GSS_KILLALL );
    }
#ifdef MEMTRACE
    freeall();
#endif
} /* cleanUp */


SystemError( string )
    char *string;
{
    if( Output() ) {
	Write( Output(), string, (ULONG)strlen(string) );
    }
    cleanUp();
    exit( 1 );
} /* SystemError */


int processMessage( window, class, code, iaddr )
    struct Window *window;
    ULONG   class;
    USHORT  code;
    APTR    iaddr;
{
    struct MenuItem *MenuItem;

    switch( class ) {
      case CLOSEWINDOW:
	return( -1 );
	break;
      case GADGETDOWN:
	toggleBoolGadget( window, (struct Gadget *) iaddr, request );
	break;
      case GADGETUP:
if( !INPHAND ) {
	if( ((struct Gadget *)iaddr)->GadgetID == CLEAR_GADG ) {
	    clearGadgets( gadg[FIRST_GADG]->NextGadget, window, request, -1 );
	}
} /* !INPHAND */
	break;
      case MENUPICK:
	while( code != MENUNULL ) {
	    MenuItem = ItemAddress( window->MenuStrip, (long) code );
	    if( MenuItem->Command == 'Q' ) {
		return( -1 );
	    }
	    code = MenuItem->NextSelect;
	} /* while */
	break;
      default:
	break;
    } /* switch */
    return( 0 );
} /* processMessage */


runIt( argc, argv, window )
    int argc;
    char **argv;
    struct Window *window;
{
    struct IntuiMessage *imsg;
    ULONG   class;
    USHORT  code;
    APTR    iaddr;
    ULONG   waitmask;
    SHORT   quitflag = 0;
    SHORT   i;

    waitmask = 1L << window->UserPort->mp_SigBit;
    if( MyWindow ) {
	waitmask |= 1L << MyWindow->UserPort->mp_SigBit;
    }
if( SUBTASK ) {
    if( mysubtask ) {
	startSubTask( mysubtask, "DEMO SUBTASK", 0, subtaskRoutine, NULL );
	waitmask |= 1L << gimMainPort->mp_SigBit;
    }
} else {
if( MYGRAPH ) {
    for( i = 0; i < NUM_COORDS1; ++i ) {
	addToGraph( mygraph, graphData[i][0], graphData[i][1] );
    } /* for */
} /* MYGRAPH */
    if( gimTimerPort ) {
	waitmask |= 1L << gimTimerPort->mp_SigBit;
    }
}/* else SUBTASK */
    while( !quitflag && !Chk_Abort() ) {
	Wait( waitmask );
	SetWindowTitles( BackWindow, "", -1L );
	while( imsg = (struct IntuiMessage *) GetMsg(window->UserPort) ) {
	    class = imsg->Class;
	    code = imsg->Code;
	    iaddr = imsg->IAddress;
	    ReplyMsg( imsg );
	    if( processMessage(window, class, code, iaddr) ) {
		quitflag = -1;
	    }
	} /* while */
	if( MyWindow ) {
	    while( imsg = (struct IntuiMessage *) GetMsg(MyWindow->UserPort) ) {
		class = imsg->Class;
		code = imsg->Code;
		iaddr = imsg->IAddress;
		ReplyMsg( imsg );
		if( processMessage(MyWindow, class, code, iaddr) ) {
		    waitmask &= ~(1L << MyWindow->UserPort->mp_SigBit);
		    getRidOfWindow( MyWindow );
		    MyWindow = NULL;
		    break;
		}
	    } /* while */
	}
	if( gimMainPort ) {
	    handleSpecialSubTaskMsg( &gimSubTasks, &gimMainPort );
	}
	if( quitflag && gimSubTasks ) {
	    SetWindowTitles( BackWindow, "hey! kill subtask first", -1L );
	    quitflag = 0;
	}
    } /* while */
} /* runIt */


struct Screen *initscreen( winptr )
    struct Window   **winptr;
{
    struct NewScreen	*ns;
    struct Screen	*screen = NULL;

    ns = gimmeNewScreen( HIRES, CUSTOMSCREEN, SBMDEPTH,
			    "Gimme.lib V1.2 testing", tf ? &ta : &gimMyFont );
    if( ns ) {
	screen = gimmeScreen( ns, winptr, SBMDEPTH, IDCMP_FLAGS, winflags );
	if( screen ) {
	    SWidth = screen->Width;
	    SHeight = screen->Height;
/***
	    ShowTitle( screen, TRUE );
***/
	}
	getRidOfNewScreen( ns );
    }
    return( screen );
} /* initscreen */


/*  example of a handler which makes the right mouse button
 *  behave like the left mouse button
 *  note: it's priority must be >50 (to be ahead of Intuition)
 */
struct InputEvent *myhandler( events, data )
    struct InputEvent	*events;
    APTR		data;
{
    register struct InputEvent	*ev;

    geta4();        /* is this really necessary ??? */
    for( ev = events; ev; ev = ev->ie_NextEvent ) {
	if( ev->ie_Class == IECLASS_RAWMOUSE ) {
	    if( (ev->ie_Code & ~IECODE_UP_PREFIX) == IECODE_RBUTTON ) {
		ev->ie_Code = (ev->ie_Code & ~IECODE_RBUTTON) | IECODE_LBUTTON;
	    }
	}
    } /* for */
    return( events );
} /* myhandler */


#asm
		; events pointer in A0
		; data pointer in A1
		; return events pointer in D0
_HandlerInterface:
    MOVEM.L	D2/D3/A4/A6,-(sp)       ; save some registers
    MOVEM.L	A0/A1,-(sp)             ; set up parms for C
    JSR 	_myhandler
    LEA 	8(sp),sp                ; pop parms
    MOVEM.L	(sp)+,D2/D3/A4/A6       ; restore registers
    RTS
#endasm


subtaskRoutine( data )
    UBYTE   *data;
{
    struct NewWindow	*nw;
    struct IntuiMessage *imsg;
    struct timerequest	*mytr = NULL, *tr;
    struct MsgPort	*myport = NULL;
    ULONG   class;
    USHORT  code;
    APTR    iaddr;
    ULONG   waitmask;
    SHORT   quitflag = 0;
    SHORT   i;
    BYTE    subtimer;

    subtimer = TIMER;
    doPrintf( gimMainPort, NULL, "message from subtask: %s\n", data);
    nw = gimmeNewWindow( "subtask'd window", Screen, 50, 50,
			    IDCMP_VSMART, FLAGS_VSMART );
    if( !nw ) {
	doPrintf(gimMainPort, NULL, "can't get new window\n");
	return;
    }
    nw->Width = 400;
    nw->Height = 150;
    if( !(SubWindow = gimmeWindow(nw, 0, 0, 0)) ) {
	getRidOfNewWindow( nw );
	doPrintf( gimMainPort, NULL, "can't open subtask window\n");
	return;
    }
    getRidOfNewWindow( nw );

/** this appears to be flaky -- but I don't know why!
if( MYGRAPH ) {
    newgraph.rp = SubWindow->RPort;
    if( !(mygraph = gimmeGraph(&newgraph, NULL, NULL, NULL)) ) {
	doPrintf(gimMainPort, NULL, "subtask: couldn't open graph\n");
	MYGRAPH = 0;
    }
}
**/

    waitmask = 1L << SubWindow->UserPort->mp_SigBit;
if( TIMER ) {
    if( gimTimerPort ) {
	/* access Timer to get my own port and signal */
	if( !(mytr = accessTimer(UNIT_VBLANK, &myport)) ) {
	    subtimer = 0;
	} else {		/* asynchronous 10 second delay */
	    timeDelayAsync( 10L, 0L, UNIT_VBLANK, mytr );
	}
	SetWindowTitles( SubWindow, "I'll go away in 10 seconds", -1L );
	waitmask |= 1L << myport->mp_SigBit;
    }
} /* TIMER */

/** this appears to be flaky -- but I don't know why!
if( MYGRAPH ) {
    for( i = 0; i < NUM_COORDS1; ++i ) {
	addToGraph( mygraph, graphData[i][0], graphData[i][1] );
    }
}
****/

    while( !quitflag ) {
	Wait( waitmask );
	while( imsg = (struct IntuiMessage *) GetMsg(SubWindow->UserPort) ) {
	    class = imsg->Class;
	    code = imsg->Code;
	    iaddr = imsg->IAddress;
	    ReplyMsg( imsg );
	    if( processMessage(SubWindow, class, code, iaddr) ) {
		quitflag = -1;
	    }
	} /* while */
	if( subtimer ) {
	    while( tr = (struct timerequest *) GetMsg(myport) ) {
		quitflag = -1;
	    } /* while */
	}
    } /* while */
    getRidOfWindow( SubWindow );
    if( mytr ) {
	releaseTimer( mytr, NULL );     /* will abort it if necessary */
    }
    SubWindow = NULL;
} /* subtaskRoutine */
SHAR_EOF
cat << \SHAR_EOF > GIMMELIB.DOC

GIMMELIB.DOC		gimme.lib		Jan Sven Trabandt
		    V1.2   31-Oct-88		{utgpu,utzoo,lsuc}!oscvax!jan

gimme.lib V1.2 (C)CopyRight 1988, Jan Sven Trabandt. All Rights Reserved.
This software may not be distributed for profit; in other words, it is
freely redistributable except that it may not be incorporated as part of any
commercial software package without my express written consent.

What is this thing??
Gimme.lib is a general purpose library of handy-dandy flexible support routines
that allow dynamic creation of intuition structures such as windows, gadgets
and screens (including double-buffering and dual playfields), quick and easy
use of the timer.device, spawning subtasks, simple IFF ILBM and 8SVX routines,
memory chaining and more...
There are currently over 100 functions.
The source to the library may be instructional in demonstrating how some aspects
of the Amiga are used (especially Intuition structures).

The include files should be located in the gimmelib subdirectory of your normal
include directory.
The functions are prototyped in gimmelib/gimmefuncs.h for quick reference and
correct use of the functions.
Documentation (similar to "man" pages) for each function is catenated together
in the DOCS file, grouped by source file; to find a function in it, search for
the function name catenated with an opening bracket, such as "gimmeBitMap(",
to find either the function's synopsis line or the start of the actual function
[this is useful since the function name "gimmeBitMap" can be referenced in many
places in the DOCS file].

Some general notes regarding gimme.lib:

0 - This library was made using Manx C V3.6a,
    and should work with Lattice with little or no modification (hopefully).
    Using a pre-compiled include file is highly recommended.

1 - Gimme.lib is almost entirely reentrant, with the following known exceptions:
	dbufvquick.c :	makeDBufVQuick(), unmakeDBufVQuick(), swapDBufVQuick()
	    These routines manipulate copper lists for maximum speed
	    using global copper list variables.
	requester.c  :	gimmeAutoRequest()
	    This routine has default text for the yes/no gadgets which can be
	    altered via global variables; if these are not changed, then the
	    routine is re-entrant.
	stdstuff.c   :	gimmeStdStuff(), getRidOfStdStuff()
	    These routines are primarily for a mainline and are not reentrant
	    for multiple subtasks.

2 - Gimme.lib routines do not write to a CLI window or stdout, so they can be
    safely used from subtasks that have no output file associated with them.
    Known exception: gimmePicture() and gimmeSound(), which test Output()
    before doing a Write() in the case of an error.

3 - Gimme.lib routine names follow this naming convention:
	start with a lower-case letter
	each distinct "word" in the name starts with an upper-case letter,
	    except for the first "word"
	underscores (_) are not used
	examples:   gimmeStringGadget, getRidOfScreen
	also, global variables start with "gim" and follow the same conventions
	    as routine names.
    Exception: communic.c, where the routine names begin with c_
	for example: c_getc(), c_open().

4 - Gimme.lib routines which return a short generally return non-zero on error,
    sometimes returning different non-zero values as different error codes.

5 - Gimme.lib routines almost always take SHORTs instead of LONGs, with these
    known notable exceptions:
	flags, which are ULONGs
	size parameters passed to gimmeMessage(), chainAllocMem() and
	    gimmeSubTask
	unit parameter to the time functions, as well as the (micro) second
	    parameters to timeDelay() and timeDelayAsync()
	"num" pararameter in positionText()
    However, if you use 32-bit ints, you shouldn't have to typecast to a short
    as the short would be promoted to an int anyways.

6 - Specialized flags for gimme.lib routines are usually of the form
    GIM_YYY or GXX_YYY where XX denotes a 2-letter shortform for a routine
    name and YYY denotes the particular flag. For example:
	GIM_MINTERM_COPY    - general purpose copy minterm
	GPT_XCENTRE	    - x-centre flag for gimmePositionText(), hence GPT

7 - Most of the gimmeXXX() routines have a corresponding getRidOfXXX() routine
    to undo the effect or deallocate memory resulting from the former routine.
    If no such getRidOfXXX() routine exists, then most likely the effects of
    the gimmeXXX() will be undone by another routine which you may have to call
    yourself -- this is most evident in the case of memory chaining.
    For example, gimmeImage() chains its memory to a given memory-chain, which
    you must free with chainFreeMem() at some point, or if you linked the image
    memory into a gadget, then getRidOfGadget() will free the image memory along
    with the rest of the gadget's memory.

8 - The gimme.lib routines do NOT, in general, check for NULL pointers in
    parameters before using them, unless the docs specifically say that NULL
    can be used as a default. However, gimme.lib can be recompiled using the
    GIMME_WIMPY option which will check with brute-force that pointers are
    non-NULL before using them.
    Important exceptions: memchain.c routines always check because it is so
    important, and menu.c routines check to make user coding easier.

9 - Since several routines are grouped together in modules, your program may
    link in more routines than it needs, so don't count on having the absolute
    smallest code possible when using gimme.lib routines...
    it's the price you pay for quick prototyping capabilities.

10- There are different versions of gimme.lib for different options:
	gimme.lib	- 16-bit int, small code/data
	gimme32.lib	- 32-bit int, small code/data
    NOTE: all the code was written for safe 16-bit use (and hence 32-bit too).
    You should be able to recompile it using large code options as well.

11- NO floating-point operations of any kind are used.
    malloc() and free() are NOT used.
    NO "int"s are used.

12- Many of the routines use my memory-chaining routines [chainAllocMem(),
    chainFreeMem(), etc.]. You may wish to look at them carefully.
    In particular, some routines such as for gadgets and windows use the
    existing structure's UserData field for its own use -- for gadgets,
    it is a memory-chain pointer which includes the gadget's structure itself.



Major Changes (in reverse chronological order)

V1.2	31-Oct-88
-----------------
    1	gadget.c: addGadgets() and removeGadgets() removed due to duplication
		    of existing RKM1.2 functions AddGList() and RemoveGList().
		  clearGadgets(): order of parameters changed to more closely
		    resemble RefreshGadgets(), ie. gadget first, then window.
    2	font.c: gimmeFontQuick() added.
    3	graph.c: new routines for graphing added.
    4	inputhand.c: new routines to add/remove an input handler added.
    5	menu.c, menustuff.c: new routines for menus
    6	copystuff.c: new routines plus some moved from intuistuff.c,
		      to copy intuition-type structure lists.
    7	communic.c: new routines for serial port


V1.1	30-Sep-88
-----------------
    1	font.c: gimmeFont now alters the TextAttr to reflect the actual
		    characteristics of the font found.
    2	gadget.c: gadget routines enhanced and some split to gadgstuff.c
		  getRidOfGadget() renamed to getRidOfGadgets()
		  clearGadget() renamed to clearGadgets()
		  added removeGadgets().
    3	postext.c: changed "num" parm in positionText() to a LONG,
		    vertical text option added.
    4	stdstuff.c: new routines for opening/closing standard libraries
			and devices added.


V1.0	31-Aug-88
-----------------
    1	first reasonable release version

SHAR_EOF
cat << \SHAR_EOF > Makefile
#
#   makefile for GIMME.LIB	    latest: 31-Oct-88	    (Manx version)
#
# NOTE: the default is to make a small code 16-bit int library gimme.lib
#	and test program
#
# NOTE: you must run make once for each library version you want.
#
#   how to make different versions of gimmelib:
#
#	make			- gimme.lib	(small code, 16-bit)
#	make T=32		- gimme32.lib	(small code, 32-bit)
#	make T=l		- gimmel.lib	(large code, 16-bit)
#	make T=l32		- gimmel32.lib	(large code, 32-bit)
#
# NOTE: the four versions above create object files with the following
# extensions, respectively:	.o, .o32, .ol, .ol32
#
# you can specify where the gimmelib include files are (for purposes of
# checking the date) by specifying  INCS=wherever  on the "make" command line
# the default is "gimmelib/"
# ie. in the gimmelib subdirectory of the current directory.
# NOTE: your INCS specification must end with '/' or ':'
#
# NOTE: the desired library must exist in the current directory
# (if it doesn't create an empty file with the appropriate name)
#

# library type (default: "" ie gimme.lib : small code 16-bit int)
T =
# where the include files are (must end with '/' or ':') [to check date]
INCS = gimmelib/


LOBJS = communic.o$T dbuf.o$T dbufquick.o$T dbufvquick.o$T dualpf.o$T \
	font.o$T graph.o$T inputhand.o$T \
	keyboard.o$T menu.o$T menustuff.o$T picture.o$T \
	postext.o$T requester.o$T screen.o$T \
	scrollbar.o$T sound.o$T stdstuff.o$T subtask.o$T \
	subtinit.o$T timerstuff.o$T timer.o$T window.o$T \
	bitmap.o$T bitplane.o$T color.o$T gadget.o$T gadgstuff.o$T message.o$T \
	intuistuff.o$T copystuff.o$T memchain.o$T globals.o$T

# NOTE: order is important because of inter-dependant routines
# note: stdstuff must come before subtask, timer
# note: communic,timerstuff must come before timer
# note: postext must come after graph
# note: color must come after picture
# note: window must come after screen
# note: bitmap must come after dbuf, dbufquick, dualpf, window
# note: bitplane should come after bitmap, picture
# note: message must come after subtinit
# note: gadget must come after scrollbar
# note: gadgstuff must come after gadget
# note: intuistuff and copystuff must come near-last
# note: memchain should come last, just before globals.o

DBGFLAG =
#debug version
#DBGFLAG = -DDEBUG -n

CFLAGS = +Irad:include/incall.pre $(DBGFLAG)

LFLAGS = -Lgimme$T -Lc$T

.c.o:
	cc $(CFLAGS) $*.c -o $@
	lb gimme$T.lib -r $* $*
.c.o32:
	cc $(CFLAGS) +L $*.c -o $@
	lb gimme$T.lib -r $@ $@
.c.ol:
	cc $(CFLAGS) +C $*.c -o $@
	lb gimme$T.lib -r $@ $@
.c.ol32:
	cc $(CFLAGS) +C +L $*.c -o $@
	lb gimme$T.lib -r $@ $@

# all (default) causes modules to be updated in the libraries
all: test

# rebuild causes the libraries to be remade from "scratch"
rebuild: rebuild_library test.o$T rebuild_test


gimme$T.lib: $(LOBJS)
	copy gimme$T.lib rad:lib/gimme$T.lib

test: gimme$T.lib test.o$T
	ln test.o$T -Lgimme$T -Lc$T
test.o: test.c
	cc $(CFLAGS) test.c -o $@
test.o32: test.c
	cc $(CFLAGS) +L test.c -o $@
test.ol: test.c
	cc $(CFLAGS) +C test.c -o $@
test.ol32: test.c
	cc $(CFLAGS) +C +L test.c -o $@


bitplane.o$T:	$(INCS)bitplane.h
color.o$T:	$(INCS)color.h
communic.o$T:	$(INCS)communic.h
copystuff.o$T:	$(INCS)copystuff.h $(INCS)intuistuff.h
dbuf.o$T dbufquick.o$T dbufvquick.o$T:	$(INCS)minterm.h
gadget.o$T:	$(INCS)gadget.h $(INCS)postext.h
gadgstuff.o$T:	$(INCS)gadget.h
globals.o$T:	$(INCS)globals.h $(INCS)requester.h $(INCS)scrollbar.h
graph.o$T:	$(INCS)graph.h $(INCS)postext.h
intuistuff.o$T: $(INCS)intuistuff.h
menustuff.o$T:	$(INCS)menustuff.h
picture.o$T:	$(INCS)picture.h $(INCS)bitplane.h $(INCS)postext.h \
		    $(INCS)minterm.h
postext.o$T:	$(INCS)postext.h
requester.o$T:	$(INCS)requester.h
screen.o$T:	$(INCS)window.h $(INCS)globals.h
scrollbar.o$T:	$(INCS)scrollbar.h
sound.o$T:	$(INCS)sound.h
stdstuff.o$T:	$(INCS)stdstuff.h
window.o$T:	$(INCS)window.h


rebuild_library: $(LOBJS)
	lb rad:lib/gimme$T.lib $(LOBJS)
	copy rad:lib/gimme$T.lib gimme$T.lib

rebuild_test:
	ln test.o$T $(LFLAGS)

SHAR_EOF
cat << \SHAR_EOF > README

README			gimme.lib		Jan Sven Trabandt
		    V1.2   31-Oct-88

gimme.lib V1.2 (C)CopyRight 1988, Jan Sven Trabandt. All Rights Reserved.
This software may not be distributed for profit; in other words, it is
freely redistributable except that it may not be incorporated as part of any
commercial or shareware software package without my express written consent.
No warranties, express or implied, are made about this software.

Welcome.

Gimme.lib is a general purpose library of handy-dandy flexible support routines
that allow dynamic creation of intuition structures such as windows, gadgets
and screens (including double-buffering and dual playfields), quick and easy
use of the timer.device, spawning subtasks, simple IFF ILBM and 8SVX routines,
memory chaining and more...
There are currently over 100 routines.

The source to the library may be instructional in demonstrating how some aspects
of the Amiga are used (especially Intuition structures).

Enjoy.
These routines are released to the public domain, but you cannot incorporate
them into a commercial or shareware product without express written consent
of the primary author (me), and you must include the author's name and
disclaimer in any program using this library.

For more information, sources, bug notices/fixes, comments, remarks and/or
voluntary donations (I'm a "poor student") contact:

	Jan Sven Trabandt
	c/o Ontario Science Centre
	(416) 429-4100 x228 work
	(416) 223-3590      home
	UUCP: {utgpu,utzoo,lsuc}!oscvax!jan


Files you should have received (probably in a zoo archive)
------------------------------

gimme.lib, gimme32.lib	    - linkable libraries (Manx version)
test.c, test		    - test/demo program (type "test" to see options)
Makefile		    - makefile for gimme.lib and test
README			    - this file
TODO			    - planned enhancements
GIMMELIB.DOC		    - brief documentation/outline file
dme.refs		    - for use with Matt Dillon's "dme" (REF command)
				[append it to your usual dme.refs file or
				 use the ADDPATH command]
tags			    - output of "ctags" program on the gimmelib source
				[useable with dme's CTAGS command]
DOCS			    - "man"-page-like description of each routine
				[this is one big file; actually it was created
				 by extracting the routine comments from my
				 source files and stripping them from the source
				 files in source.zoo to keep them separate and
				 to avoid unnecessary duplication]
*.c			    - source files
gimmelib/*.h		    - include files [move to your include directory]


How to use gimme.lib
--------------------
copy gimmelib/#?.h to your normal include file directory, or precompile it into
your precompiled include file (you can use gimmelib/gimmeall.h to include all
the gimmelib include files)

copy gimme.lib or gimme32.lib to your usual lib directory (where you keep c.lib)
or anywhere specified by your CLIB path

use gimmelib routines in your program and...
link with "-Lgimme -Lc" or "-Lgimme32 -Lc32"    (Manx users)


Hope it comes in handy.
Jan Sven.

SHAR_EOF
cat << \SHAR_EOF > TODO

TODO			gimme.lib		Jan Sven Trabandt
		    V1.2   31-Oct-88


Things I plan on doing:

1 - communic.c: add support for parallel device and make it more flexible.
    NOTE: communic.c and its routines are subject to change --
	    DO NOT COUNT ON THEM REMAINING BACKWARDLY COMPATIBLE!

2 - graph.c: make these routines handle graaphing in any quadrant (cleanly).

n - things as I need them

n+1 - bugs/suggestions you send me


BUGS

1 - why is my input-handler flakey??? (see test.c)
2 - why won't graphing from the subtask work?? (see test.c)

SHAR_EOF
cat << \SHAR_EOF > USENET.NOTE
The USENET distribution does not have the .lib files or the 'test'
binary included, in order to cut down on the size of the distribution.

Since you need a Manx compiler to use this stuff, you shouldn't need
the binary - you should be able to compile it!

..Bob
SHAR_EOF
cat << \SHAR_EOF > dme.refs

SOUND			    (} SOUND)           incs:gimmelib/sound.h           (typedef struct _gim_snd)
Voice8Header		    (} Voice8Header)    incs:gimmelib/sound.h           (typedef LONG Fixed)
PICTURE 		    (} PICTURE)         incs:gimmelib/picture.h         (typedef struct _gim_pic)
BitMapHeader		    (} BitMapHeader)    incs:gimmelib/picture.h         (typedef UBYTE Masking)
NEWAXIS 		    (} NEWAXIS)         incs:gimmelib/graph.h           (typedef struct _gim_nax)
AXIS			    (} AXIS)            incs:gimmelib/graph.h           (typedef struct _gim_axis)
NEWGRAPH		    72			incs:gimmelib/graph.h		(typedef struct _gim_newgr)
GRAPH			    (} GRAPH)           incs:gimmelib/graph.h           (#define GGR_DELTAX)
SERPARMS		    (} SERPARMS)        incs:gimmelib/communic.h        (#define C_SER)

GBP_			    999 		incs:gimmelib/bitplane.h	(#define GBP_SEPARATE)
GIM_			    999 		incs:gimmelib/color.h		(#define GIM_BACKGROUND)
GCP_			    (#define GCP_DEFAULT)   incs:gimmelib/copystuff.h   (#define GCP_NOT_ITEXT)
GGR_			    62			incs:gimmelib/graph.h		(#define GGR_DELTA)
GMI_			    (#define GMI_DEFAULT)   incs:gimmelib/menustuff.h   (#define GMI_ADDSUBITEM)
GIM_MINTERM		    999 		incs:gimmelib/minterm.h 	(#define GMI_MINTERM_COPY)
GPT_			    999 		incs:gimmelib/postext.h 	(#define GPT_XLEFT)
GOS_			    999 		incs:gimmelib/scrollbar.h	(#define GOS_TOP)
GSS_			    999 		incs:gimmelib/stdstuff.h	(#ifndef I_AM_STDSTUFF)
IDCMP_			    999 		incs:gimmelib/window.h		(#define IDCMP_)
FLAGS_			    999 		incs:gimmelib/window.h		(#define FLAGS_)
C_ERR_			    (extern short c_error)  incs:gimmelib/communic.h    (#define C_ERR_)

bitplane.h		    999     incs:gimmelib/bitplane.h		()
color.h 		    999     incs:gimmelib/color.h		()
communic.h		    999     incs:gimmelib/communic.h		()
copystuff.h		    999     incs:gimmelib/copystuff.h		()
gadget.h		    999     incs:gimmelib/gadget.h		()
gimNOshortdefs.h	    999     incs:gimmelib/gimNOshortdefs.h	()
gimmeall.h		    999     incs:gimmelib/gimmeall.h		()
gimmefuncs.h		    999     incs:gimmelib/gimmefuncs.h		()
gimshortdefs.h		    999     incs:gimmelib/gimshortdefs.h	()
globals.h		    999     incs:gimmelib/globals.h		()
graph.h 		    999     incs:gimmelib/graph.h		()
intuistuff.h		    999     incs:gimmelib/intuistuff.h		()
macros.h		    999     incs:gimmelib/macros.h		()
menustuff.h		    999     incs:gimmelib/menustuff.h		()
minterm.h		    999     incs:gimmelib/minterm.h		()
picture.h		    999     incs:gimmelib/picture.h		()
postext.h		    999     incs:gimmelib/postext.h		()
requester.h		    999     incs:gimmelib/requester.h		()
scrollbar.h		    999     incs:gimmelib/scrollbar.h		()
sound.h 		    999     incs:gimmelib/sound.h		()
stdstuff.h		    999     incs:gimmelib/stdstuff.h		()
window.h		    999     incs:gimmelib/window.h		()

SHAR_EOF
cat << \SHAR_EOF > tags
gimmeBitMap bitmap.c /^struct BitMap *gimmeBitMap(
getRidOfBitMap bitmap.c /^short getRidOfBitMap(
gimmeBitPlanes bitplane.c /^ULONG gimmeBitPlanes(
getRidOfBitPlanes bitplane.c /^short getRidOfBitPlanes(
getDefaultColors color.c /^USHORT *getDefaultColors(
setColors color.c /^short setColors(
checkColors color.c /^short checkColors(
c_init communic.c /^short c_init(
c_open communic.c /^short c_open(
c_setup communic.c /^short c_setup(
c_getchar communic.c /^static short c_getchar(
c_getc communic.c /^short c_getc(
c_emptyc communic.c /^short c_emptyc(
c_putc communic.c /^short c_putc(
c_gets communic.c /^short c_gets(
c_getline communic.c /^short c_getline(
c_setEOL communic.c /^short c_setEOL(
c_puts communic.c /^short c_puts(
c_close communic.c /^short c_close(
c_done communic.c /^short c_done(
copyDataImage copystuff.c /^short copyDataImage(
copyImageData copystuff.c /^short copyImageData(
copyBorder copystuff.c /^struct Border *copyBorder(
copyImage copystuff.c /^struct Image *copyImage(
copyIntuiText copystuff.c /^struct IntuiText *copyIntuiText(
copyMenuItem copystuff.c /^struct MenuItem *copyMenuItem(
copyMenu copystuff.c /^struct Menu *copyMenu(
makeDBuf dbuf.c /^short makeDBuf(
unmakeDBuf dbuf.c /^short unmakeDBuf(
swapDBuf dbuf.c /^short swapDBuf(
makeDBufQuick dbufquick.c /^short makeDBufQuick(
unmakeDBufQuick dbufquick.c /^short unmakeDBufQuick(
swapDBufQuick dbufquick.c /^short swapDBufQuick(
makeDBufVQuick dbufvquick.c /^short makeDBufVQuick(
unmakeDBufVQuick dbufvquick.c /^short unmakeDBufVQuick(
swapDBufVQuick dbufvquick.c /^short swapDBufVQuick(
makeDualPlayfield dualpf.c /^short makeDualPlayfield(
unmakeDualPlayfield dualpf.c /^short unmakeDualPlayfield(
gimmeFont font.c /^struct TextFont *gimmeFont(
gimmeFontLazy font.c /^struct TextFont *gimmeFontLazy(
getRidOfFont font.c /^short getRidOfFont(
getRidOfGadgets gadget.c /^short getRidOfGadgets(
gimmeBoolGadget gadget.c /^struct Gadget *gimmeBoolGadget(
gimmeBoolImageGadget gadget.c /^struct Gadget *gimmeBoolImageGadget(
gimmePropGadget gadget.c /^struct Gadget *gimmePropGadget(
gimmePropInfo gadget.c /^struct PropInfo *gimmePropInfo(
gimmeStringGadget gadget.c /^struct Gadget *gimmeStringGadget(
gimmeStringInfo gadget.c /^struct StringInfo *gimmeStringInfo(
clearGadgets gadgstuff.c /^short clearGadgets(
toggleBoolGadget gadgstuff.c /^short toggleBoolGadget(
findGadget gadgstuff.c /^struct Gadget *findGadget(
findMyFirstGadget gadgstuff.c /^struct Gadget *findMyFirstGadget(
gimmeGraph graph.c /^GRAPH *gimmeGraph(
getRidOfGraph graph.c /^short getRidOfGraph(
clearGraph graph.c /^VOID clearGraph(
resetGraph graph.c /^VOID resetGraph(
drawGraphAxesOnly graph.c /^VOID drawGraphAxesOnly(
drawGraphAxes graph.c /^SHORT drawGraphAxes(
drawGraphTitle graph.c /^VOID drawGraphTitle(
drawGraphXtitle graph.c /^VOID drawGraphXtitle(
drawGraphYtitle graph.c /^VOID drawGraphYtitle(
coordToOffset graph.c /^static SHORT coordToOffset(
offsetToCoord graph.c /^static SHORT offsetToCoord(
initAxis graph.c /^static VOID initAxis(
graphWriteLabel graph.c /^SHORT graphWriteLabel(
addToGraph graph.c /^VOID addToGraph(
updateCoord graph.c /^static SHORT updateCoord(
doBlock graph.c /^static VOID doBlock(
addInputHandler inputhand.c /^struct IOStdReq *addInputHandler(
removeInputHandler inputhand.c /^short removeInputHandler(
gimmeBorder intuistuff.c /^struct Border *gimmeBorder(
gimmeImage intuistuff.c /^struct Image *gimmeImage(
gimmeIntuiText intuistuff.c /^struct IntuiText *gimmeIntuiText(
deadKeyConvert keyboard.c /^SHORT deadKeyConvert(
chainAllocMem memchain.c /^void *chainAllocMem(
chainFreeMem memchain.c /^VOID chainFreeMem(
linkChainMem memchain.c /^short linkChainMem(
pluckChainMem memchain.c /^short pluckChainMem(
gimmeMenu menu.c /^struct Menu *gimmeMenu(
gimmeMenuItem menu.c /^struct MenuItem *gimmeMenuItem(
addMenuItem menustuff.c /^ULONG addMenuItem(
addMenu menustuff.c /^ULONG addMenu(
removeMenuItem menustuff.c /^struct MenuItem *removeMenuItem(
removeMenu menustuff.c /^struct Menu *removeMenu(
adjustMenuItems menustuff.c /^short adjustMenuItems(
adjustMenuLefts menustuff.c /^short adjustMenuLefts(
gimmeMessage message.c /^struct Message *gimmeMessage(
getRidOfMessage message.c /^short getRidOfMessage(
gimmePicture picture.c /^PICTURE *gimmePicture(
makeBM picture.c /^static ULONG makeBM(
getRidOfPicture picture.c /^short getRidOfPicture(
positionPicture picture.c /^short positionPicture(
usePictureColors picture.c /^short usePictureColors(
getLong picture.c /^static LONG getLong(
getChunk picture.c /^static getChunk(
memget picture.c /^static memget(
getWord picture.c /^static WORD getWord(
getCmpBody picture.c /^static int getCmpBody(
getBody picture.c /^static int getBody(
getLut picture.c /^static int getLut(
positionText postext.c /^SHORT positionText(
gimmeAutoRequest requester.c /^SHORT gimmeAutoRequest(
gimmeRequester requester.c /^struct Requester *gimmeRequester(
gimmeNewScreen screen.c /^struct NewScreen *gimmeNewScreen(
getRidOfNewScreen screen.c /^short getRidOfNewScreen(
gimmeScreen screen.c /^struct Screen *gimmeScreen(
gimmeScreenLazy screen.c /^struct Screen *gimmeScreenLazy(
getRidOfScreen screen.c /^short getRidOfScreen(
lowerScreen screen.c /^short lowerScreen(
raiseScreen screen.c /^short raiseScreen(
gimmeOneScroll scrollbar.c /^struct Gadget *gimmeOneScroll(
gimmeScrollBar scrollbar.c /^struct Gadget *gimmeScrollBar(
gimmeFullScrollBar scrollbar.c /^struct Gadget *gimmeFullScrollBar(
gimmeSound sound.c /^SOUND *gimmeSound(
getRidOfSound sound.c /^short getRidOfSound(
getLong sound.c /^static LONG getLong(
getChunk sound.c /^static getChunk(
memget sound.c /^static memget(
getWord sound.c /^static WORD getWord(
getEGPoint sound.c /^static getEGPoint(
D1Unpack sound.c /^static BYTE D1Unpack(
DUnpack sound.c /^static DUnpack(
gimmeStdStuff stdstuff.c /^ULONG gimmeStdStuff(
getRidOfStdStuff stdstuff.c /^ULONG getRidOfStdStuff(
gimmeSubTask subtask.c /^struct Task *gimmeSubTask(
pushTaskStack subtask.c /^static pushTaskStack(
popTaskStack subtask.c /^static LONG popTaskStack(
undoGimmeSubTask subtask.c /^VOID undoGimmeSubTask(
killSubTask subtask.c /^VOID killSubTask(
getRidOfMyself subtask.c /^static VOID getRidOfMyself(
bridgeSubTask subtask.c /^static VOID bridgeSubTask(
startSubTask subtask.c /^short startSubTask(
initSubTasker subtinit.c /^short initSubTasker(
doneSubTasker subtinit.c /^short doneSubTasker(
doPrintf subtinit.c /^short doPrintf(
handleSpecialSubTaskMsg subtinit.c /^SHORT handleSpecialSubTaskMsg(
accessTimer timer.c /^struct timerequest *accessTimer(
releaseTimer timer.c /^LONG releaseTimer(
gimmeTimeRequest timer.c /^struct timerequest *gimmeTimeRequest(
getRidOfTimeRequest timer.c /^LONG getRidOfTimeRequest(
timeDelay timerstuff.c /^LONG timeDelay(
timeDelayAsync timerstuff.c /^struct timerequest *timeDelayAsync(
waitTimer timerstuff.c /^LONG waitTimer(
killTimeDelay timerstuff.c /^LONG killTimeDelay(
getSysTime timerstuff.c /^short getSysTime(
setSysTime timerstuff.c /^short setSysTime(
gimmeNewWindow window.c /^struct NewWindow *gimmeNewWindow(
getRidOfNewWindow window.c /^short getRidOfNewWindow(
gimmeWindow window.c /^struct Window *gimmeWindow(
getRidOfWindow window.c /^short getRidOfWindow(
SHAR_EOF
#	End of shell archive
exit 0
-- 
Bob Page, U of Lowell CS Dept.  page@swan.ulowell.edu  ulowell!page
Have five nice days.