[comp.sys.amiga] autoEnquire

hull@hao.UCAR.EDU (Howard Hull) (07/12/87)

This is a program that creates an example of a contraption that I wish to
call an "AutoEnquirer" - it's like a requester except it's not quite as
demanding and goes where you want to put it.  I'd love to see this included
in 1.3 (CA: HINT, HINT).  When you call Intuition's AutoRequest function,
you can specify the size, but not the location of the requester.  The
autoEnquire function lets you specify the location, but not the size.
The autoEnquire contraption is nosey, like its namesake, but it also knows
that it can work better if it doesn't irritate you.  It therefore also has
the property that if the user moves it (in order to see what's under it -
in case that's important to the question at hand) the next time it's
called, it shows up where the user left it last.  To fabricate this beastie,
I snarfed a lot of code; I used giant hunks of John Draper's Menu and
Requester tutorial (from the WELL) and also used Chris Gray's Fractalish
Terrain Generator as a test bed.  Since the Terrain generator would not
compile under Manx, I have it here for you in a 16-bit integer Manxification
by means of Dynamic Allocation.  Also, I want to thank Steve Drew for the
Manx version of the Matt Dillon Shell, which has saved me a lot of disk
swaps, and Dave Wecker for the shar program used to package the stuff below.

To compile, unshar the mess below into an empty directory to get the header,
atv.h, the terrain code atv.c and the autoEnquirer code enq.c and then do
these commands to compile and link (Manx Aztec C 3.04a 512K Amiga 1000):

		cc atv.c
		cc enq.c
		ln atv.c enq.c -lc

Now then, you sharks out there, realize that I am a VERY novice C programmer,
so this code is going evoke comments like "What th... why the HELL did he do
THAT!"  I had to de-subroutinize a couple of things because I could not find
out how to define an array of pointers to dynamically allocated data which
could be transferred to a subroutine without evoking an error from Manx.
something like
		#define XLIMIT 256L
		#define YLIMIT 128L
		...
		short *Cell[256];
		void boogie();
		unsigned short n, m, i, j, x, y;
		...
		void boogie(Cell, p)
		short *Cell[];
		int p;
		{
		unsigned short l,c;
		for (l=0; l<YLIMIT; l++)
		    {
		    for (c=0; c<XLIMIT)
			{
		        Cell[n][m] = (short)(p*Cell[l][c]);
		    }
		}
		}
		...
		main()
		{
		...
		Cell[n][m] = boogie(&Cell[0][0], (Cell[x][y] + Cell[i][j]))
		...
		}
gets tagged with an error concerning the subroutine definition of Cell.
So I want those comments!  (Use EMAIL please.)  That's also why I'm posting
this to just this newsgroup; there's no .uue file because this is a compiler
curiosity only (Gray's Terrain Generator has already been posted as compiled
under Draco, ok?)  In looking this over, I just noticed one thing I should
have fixed - I used :ts=4 for tab stops in the Manx z editor.  Since vi uses
8 spaces for tabs, there'll be trouble there and with many other editors.
For vi you can say ":set tabstop=4" and it should be a little more readable.
I'll be out of town all next week (they usually try to send me out of town
just before I put out a net article, it seems.  I wonder why...) so don't
expect an immediate response.

								Howard Hull
[If yet unproven concepts are outlawed in the range of discussion...
                 ...Then only the deranged will discuss yet unproven concepts]
	{ucbvax!hplabs | decvax!noao | mcvax!seismo | ihnp4!seismo} !hao!hull
	for domain mailers: hull@hao.ucar.edu

#	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:
#	atv.h
#	atv.c
#	enq.c
# This archive created: Sat Jul 11 17:19:34 1987
echo shar: extracting atv.h
sed 's/^XX//' << \SHAR_EOF > atv.h
XX
XX#include "exec/types.h"
XX#include "intuition/intuition.h"
XX#include "libraries/dos.h"
XX#include "functions.h"
XX
XX#ifdef NULL
XX#undef NULL
XX#define NULL ((void *)0)
XX#endif
XX
XXtypedef unsigned UINT;
XX
XXstruct Screen *OpenScreen();				/* for terrain window */
XXstruct Window *OpenWindow(),*OpenWindow();
XX
XXstruct Screen *Screen;						/* for enquirer window */
XXstruct Window *Window,*RWindow;
XX
SHAR_EOF
if test 378 -ne "`wc -c atv.h`"
then
echo shar: error transmitting atv.h '(should have been 378 characters)'
fi
echo shar: extracting atv.c
sed 's/^XX//' << \SHAR_EOF > atv.c
XX
XX#include "atv.h"
XX
XXextern struct Requester req;			/* custom requester structure */ 
XXextern struct Border out_border;
XXextern struct Gadget ongad;
XXextern struct Gadget offgad;
XX
XXextern short autoEnquire();
XX
XX/*
XX * sc.c - fractalish terrain generator.
XX *
XX *   Date:     March 5, 1987 (original version sometime in 1985)
XX *   Author:   Chris Gray
XX *   Language: C
XX *   System:   Amiga
XX */
XX
XX/*
XX * Badly hacked for Dynamic allocation under 16-bit integer Manx:
XX *
XX *   Date:        July 6, 1987
XX *   Barbarian:   Howard Hull
XX *   Implements:  (some) Dynamic allocation code from Ray Bovet
XX *                (considerable) custom requester code from John Draper's
XX *                 gadget tutorial
XX */
XX
XX/*
XX * Gray: (continued, but edited for current content)
XX *
XX * The nature of the terrain can be changed by playing with the numbers
XX * in 'Range'. If you change SIZE, you must also change the number of
XX * values given for 'Range'.  The created terrain for SIZE = 8 and PGEOM
XX * set to SINGLEW is 256 pixels by 256 pixels, which doesn't fit on a
XX * non-interlaced screen, so only the top 200 pixels are displayed.  The
XX * terrain is a torus, i.e. wraps around both vertically and horizontally.
XX * To see the whole torus in a rectangular format, use SIZE = 7 and set
XX * PGEOM to DOUBLEW.  For other combinations see instructions below.
XX */
XX
XX/*
XX * Feel free to use this algorithm in any games you write, so long as you
XX * give me [Gray] credit for it.
XX * Gray says: (I THINK I invented it, since I've never heard of anything
XX * similar, and other programs I've seen use much slower methods.)
XX */
XX
XX#define SINGLEW 1			/* Use to obtain "square" pixel map            */
XX#define DOUBLEW 2			/* Use to obtain "wide rectangular" pixel map  */
XX#define PGEOM  DOUBLEW		/* Selects picture geometry.  Picture size is  */
XX#define SIZE 7				/* 128 X 128 for 7 at SINGLEW, or 256 X 128 at */
XX#define MAPH (1 << SIZE)	/* 7 in DOUBLEW.  MAPH is map height, or 128   */
XX#define MAPW (MAPH*PGEOM)	/* for 7 SIZE, 256 for 8 SIZE config as torus  */
XX#define CAMOD 4				/* SIZE 7 always 4, SIZE 8 & DOUBLEW must be 8 */
XX#define MAPMH MAPH/CAMOD	/* sets calloc module size; calloc is 16-bit!  */
XX#define CSIZE 2				/* calloc needs to know short type is 2 bytes  */
XX#define SCREEN_WIDTH 320    /* 320X200: 7 & SINGLEW 32K, looks 1/4 size    */
XX#define SCREEN_HEIGHT 200	/* 320X200: 7 & DOUBLEW 65K, 8 & SINGLEW 131K  */
XX							/* 320X400: 8 & SINGLEW 131K, 8 & DOUBLEW 262K */
XX							/* 640X200: 8 & SINGLEW 131K, 8 & DOUBLEW 262K */
XX							/* 640X400: 8 & DOUBLEW 262K looks 1/4 size    */
XX#define SCREEN_DEPTH 5L		/* use 4L max for interlaced screens!          */
XX#define COLOURS (long)(1 << SCREEN_DEPTH)	/* up to 32 colors             */
XX#define WINDOW_WIDTH (long)(MAPW < SCREEN_WIDTH ? MAPW : SCREEN_WIDTH)
XX#define WINDOW_HEIGHT (long)(MAPH < SCREEN_HEIGHT ? MAPH : SCREEN_HEIGHT)
XX#define REQ_LEFT_EDGE 256L	/* Position of enquirer  window when called    */
XX#define REQ_TOP_EDGE 12L	/* up on the terrain display's screen          */
XX#define REQ_WIDTH 64L       /* Width of enquirer window */
XX#define REQ_HEIGHT 72L     /* Length of enquirer window */
XX
XX#define FREEPEN (-1)
XX
XXstatic unsigned short Range[SIZE] = {38, 36, 36, 12, 8, 4, 2};
XX/* static unsigned short Range[SIZE] = {38, 36, 36, 36, 12, 8, 4, 2}; SIZE 8 */
XX
XX/* Color table for non-interlaced screen */
XXstatic unsigned short ColourMap[COLOURS] = {
XX    0x00f, 0x050, 0x070, 0x0a0, 0x0c0, 0x0e0, 0x4f4, 0x8f8,
XX    0xdf0, 0xff0, 0xbd2, 0x9c3, 0x6b5, 0x4a6, 0x297, 0x088,
XX    0x078, 0x177, 0x366, 0x465, 0x663, 0x762, 0x951, 0xa50,
XX    0xa62, 0xa74, 0xa86, 0xa98, 0xaaa, 0xccc, 0xeee, 0xfff
XX};
XX/* AutoEnquire body and button texts */
XXstruct IntuiText negtext =
XX    {COLOURS - 1L, 0L, JAM2, 5L, 2L, NULL, NULL, NULL};
XXstruct IntuiText postext =
XX    {COLOURS - 1L, 0L, JAM2, 5L, 2L, NULL, NULL, NULL};
XXstruct IntuiText text =
XX    {COLOURS - 1L, 0L, JAM2, 12L, 7L, NULL, NULL, NULL};
XX
XXshort wleftedge = -1; /* These are the variables in which we     */
XXshort wtopedge = -1;  /* get the first moved enquirer position.  */
XX
XXstatic unsigned short Seed;
XXstatic short altitude;
XXshort interested;
XX
XXshort *Cell[MAPH];  /* define an array of pointers to modules from calloc */
XXchar *calloc();		/* define the allocator subroutine call */
XX
XX/*
XX * random - return a random number 0 - passed range.
XX */
XX
XXunsigned short random(rang)
XXunsigned short rang;
XX{
XX    if (rang == 0)
XX        return 0;
XX    Seed = Seed * 17137 + 4287;
XX    Seed = (Seed >> 8) ^ (Seed << 8);
XX    return Seed % rang;
XX}
XX
XX/*
XX * set - set a given spot in Cell.
XX */
XX
XXvoid set(size, height)
XXunsigned short size;
XXshort height;
XX{
XX    unsigned short rang;
XX
XX    rang = Range[size];
XX    height = height + random(rang) - (rang + 1) / 2;
XX	altitude = height;
XX}
XX
XXstruct IntuitionBase *IntuitionBase;
XXstruct GfxBase       *GfxBase;
XX
XX/*
XX * main program.
XX */
XX
XXvoid main()
XX{
XX
XX	unsigned short i, j, k, l, m;
XX    unsigned short c, step, nextStep, l1, l2, c1, c2;
XX    short height;
XX
XX    struct DateStamp ds;
XX
XX/* this is the terrain screen.  See RKM for 320X400 & 640X200 configs */
XX    static struct NewScreen newScreen =
XX          {0L, 0L, SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_DEPTH, 0L, 1L,
XX          0x0, CUSTOMSCREEN, NULL, NULL, NULL, NULL};
XX
XX/* this is the terrain display's window structure */
XX    static struct NewWindow newWindow =
XX            {
XX            0L, 0L, WINDOW_WIDTH, WINDOW_HEIGHT,
XX            FREEPEN, FREEPEN,
XX            0x0, BORDERLESS | ACTIVATE | NOCAREREFRESH,
XX            NULL, NULL, NULL, NULL, NULL, 0L, 0L, 0L, 0L,
XX            CUSTOMSCREEN
XX            };
XX
XX/* this is the AutoEnquire window structure */
XX    static struct NewWindow reqWindow =
XX            {
XX            REQ_LEFT_EDGE, REQ_TOP_EDGE, REQ_WIDTH, REQ_HEIGHT,
XX            FREEPEN, FREEPEN,
XX              CLOSEWINDOW            /*  IDCMP flags                      */
XX            | REFRESHWINDOW
XX            | MOUSEBUTTONS
XX            | REQCLEAR 
XX            | GADGETDOWN 
XX            | SELECTDOWN 
XX            | SELECTUP, 
XX                                     /*  Usual flags for gadgets and such */ 
XX              ACTIVATE
XX            | WINDOWDEPTH 
XX            | WINDOWDRAG 
XX            | SMART_REFRESH, 
XX            NULL, NULL, NULL, NULL, NULL, 0L, 0L, 0L, 0L,
XX            CUSTOMSCREEN
XX            };
XX
XX/* 'main' assignments begin here */
XX
XX/* **************************************************************************
XX*																			*
XX*  :::::::::::::::::::::::::::::::::::::::::::::::::::::::::
XX*  ::  When you're up to your OS in allocators, it's hard ::				*
XX*  :: to remember that the task was to empty /dev/swap... ::				*
XX*  :::::::::::::::::::::::::::::::::::::::::::::::::::::::::
XX*																			*
XX*  I ransacked some of Ray Bovet's Atari code to get the dynamic allocator. *
XX*  However, on my own I discovered Horror #1:								*
XX*																			*
XX*  Dynamic allocation for Manx uses either of two Unix compatible routines,	*
XX*  malloc or calloc from the system independent library.  Since calloc		*
XX*  merely multiplies its two input arguments and uses them to call malloc,	*
XX*  with a 16-bit integer compiler the maximum request is 65,535 bytes.		*
XX*  Requests for 65,536 bytes get zero bytes allocated.  In order to obtain	*
XX*  262,144 bytes we would have to ask malloc for eight 32,768 byte modules.	*
XX*																			*
XX*  Just to be decent, this code was issued with #defines at the front that	*
XX*  will ask (as printed) for four modules.  Change the #define for CAMOD to *
XX*  experiment with this.													*
XX*  Good Luck...														H. Hull *
XX*																			*
XX************************************************************************** */
XX
XX/* Dynamic allocation routine for terrain growth arrays */
XX
XX/* casts input arguments to their required types */
XX/* typedef for UINT 'unsigned integer' is at top of page */
XX/* cast the char pointer returned to type 'short *' for our use in Cell */
XX/* calloc returns arg1 items of size arg2, cleared to zeros */
XX
XXk = 0;
XXdo
XX    {
XX	if ((Cell[k] = (short *)calloc((UINT)(MAPMH*MAPW), (UINT)CSIZE)) == NULL)
XX		{
XX		exit(0);  /* Silently exits.  Anybody know a more graceful method? */
XX	}
XX}
XX
XX/* MAPMH is module 'height' in the window; */
XX/* an even number of modules stack together like blind slats on the window */
XX
XX/* Each module produces a pointer to its base that goes into Cell[0] so   */
XX/* we have to then fill the Cell array with window height-based pointers  */
XX/* one pointer for each line across the window.  These serve as pointers  */
XX/* to window-width based line data we want to put in the returned module. */
XX
XXwhile ((k = k + MAPMH) < MAPH);
XX
XXfor (k = 1; k <= CAMOD; k++)
XX	{
XX	l = MAPMH*k;
XX	m = MAPMH*(k-1);
XX	for (j = m+1; j < l; j++)
XX   		{
XX		Cell[j] = Cell[j-1] + MAPW;		/* makes an array of pointers */
XX	}
XX}
XX
XX/* Back to the original programe now... */
XX
XX    IntuitionBase = (struct IntuitionBase *)
XX                            OpenLibrary("intuition.library", 0L);
XX    if (IntuitionBase != NULL)
XX        {
XX        GfxBase = (struct GfxBase *)
XX                          OpenLibrary("graphics.library", 0L);
XX        if (GfxBase != NULL)
XX            {
XX            Screen = OpenScreen(&newScreen);
XX            if (Screen != NULL)
XX                {
XX                LoadRGB4(&Screen->ViewPort, ColourMap, COLOURS);
XX                newWindow.Screen = Screen;
XX                Window = OpenWindow(&newWindow);
XX                if (Window != NULL)
XX                    {
XX                    DateStamp(&ds);
XX                    Seed = (ds.ds_Minute ^ ds.ds_Tick) | 1;
XX
XX/*  Ok.  I give up.  I notice that Cell[y][x] in main() is a place to put */
XX/* a single data point, even though Cell is actually a singly subscripted */
XX/* array of pointers.  We certainly wouldn't want to smash the pointer by */
XX/* attempting an assignment of data to Cell[n].  The compiler would warn  */
XX/* about a short to pointer conversion, anyway.  We could use *Cell[n] to */
XX/* obtain the quantity in the base cell of any particular line of data,   */
XX/* and pointer arithmetic (*Cell[y]+x) might (?) get us the data we want  */
XX/* to access.  But when I try to use Cell[y][x] in a subroutine, I get an */
XX/* excess array subscript error.  No amount of fiddling with subroutine   */
XX/* argument definitions yielded any error free situation.  I can't use a  */
XX/* 'static' definition in main for a dynamically allocated data element,  */
XX/* either, can I?  So this program got hacked to where it looks like a    */
XX/* meat packing plant after a company holiday.  No subroutines addressing */
XX/* Cell are to be found within it.  Indentation is out the window, too.   */
XX
XXdo
XX{
XX
XX/*
XX * grow - grow the basic scenery heights.
XX */
XX
XX    Cell[0][0] = 0;
XX    step = MAPH;
XX    for (i=0; i<SIZE; i++)
XX        {
XX        nextStep = step / 2;
XX        for (l=0; l<MAPH; l+=step)
XX            {
XX            l1 = l + nextStep;
XX            l2 = l + step;
XX            if (l2 == MAPH)
XX                l2 = 0;
XX            for (c=0; c<MAPW; c+=step)
XX                {
XX                c1 = c + nextStep;
XX                c2 = c + step;
XX                if (c2 == MAPW)
XX                    c2 = 0;
XX                set(i, (Cell[l][c] + Cell[l][c2] + 1) / 2);
XX				Cell[l][c1] = altitude;
XX                set(i, (Cell[l][c] + Cell[l2][c] + 1) / 2);
XX				Cell[l1][c] = altitude;
XX                set(i, (Cell[l][c] + Cell[l][c2] +
XX                                 Cell[l2][c] + Cell[l2][c2] + 2) / 4);
XX				Cell[l1][c1] = altitude;
XX                }
XX            }
XX        step = nextStep;
XX        }
XX
XX/*
XX * display - display the resulting scenery.
XX */
XX
XX    for (l=0; l<WINDOW_HEIGHT; l++)
XX        {
XX        for (c=0; c<WINDOW_WIDTH; c++)
XX            {
XX            height = Cell[l][c];
XX            SetAPen(Window->RPort,
XX                    (long)(height<0 ?
XX                        0
XX                    : (height>=COLOURS ?
XX                        COLOURS-1
XX                    : height)));
XX            WritePixel(Window->RPort, (long)c, (long)l);
XX		}
XX	}
XX
XXinterested = FALSE;
XXreqWindow.Screen = Screen;
XXif ((wleftedge >= 0) || (wtopedge >= 0))
XX	{
XX	reqWindow.LeftEdge = wleftedge;  /* if the window has been opened, */
XX	reqWindow.TopEdge = wtopedge;    /* use the updated coordinates    */
XX}
XXRWindow = OpenWindow(&reqWindow);
XXif (RWindow != NULL)
XX	{
XX	(void) InitRequester(&req);  /* Rumor: clears req structure entirely */
XX
XX	/* Init the fields in the Requester structure */ 
XX  
XX	req.LeftEdge  = 4; 
XX	req.TopEdge   = 12; 
XX	req.Width     = 56; 
XX	req.Height    = 59; 
XX	req.ReqGadget = &ongad;         /* First gadget */
XX	req.ReqText   = &text;          /* Text for enquirer */
XX	req.BackFill  = 1;              /* BackGnd color to window */
XX	req.Flags     = 0; 
XX	req.ReqBorder = &out_border;    /* Must have at least one */
XX
XX	/* initialize the enquirer text */
XX
XX	text.IText = (unsigned char *)"DONE";
XX	postext.IText = (unsigned char *)"NEXT";
XX	negtext.IText = (unsigned char *)"QUIT";
XX
XX	if (Request(&req, RWindow) == 1)  /* try to open the enquirer window */
XX		{
XX		interested = (autoEnquire());  /* if we're here it did open, so  */
XX							/* now we can find out what they want to do */
XX
XX/* To aviod some the above cumbersome initialization, the following is a
XX    model for the AutoEnquire function (for v1.3 anybody?) which allows us
XX	to specify WHERE the requester will go rather than HOW BIG it will be:
XX
XX		interested = (AutoEnquire
XX					(
XX					Window,
XX					BodyText,
XX					PositiveText,
XX					NegativeText,
XX					PositiveFlags,
XX					NegativeFlags,
XX					XPosition,
XX					YPosition
XX					)
XX				);
XX   It should also be possible to set things up so that if the user moves
XX    the AutoEnquire window, Intuition can keep track of where he put it
XX    so that it will open up in the same place next time it's called.
XX    Would you like that, Bunky?  Since Intuition maintains the structure,
XX    it could be done with the appropriate flags.					*/
XX
XX		CloseWindow(RWindow);  /* if we're here we got their attention */
XX							  /* and we can close the enquirer window */
XX	}
XX}
XX}
XXwhile (interested == TRUE);
XX
XX/* Ok.  We're back to normal now.  We're also all done with the program. */
XX/* Time to clean up the mess and get out while we're still ahead...      */
XX
XX                    CloseWindow(Window);
XX                }
XX                CloseScreen(Screen);
XX            }
XX            CloseLibrary(GfxBase);
XX        }
XX        CloseLibrary(IntuitionBase);
XX    }
XX}
XX
SHAR_EOF
if test 14327 -ne "`wc -c atv.c`"
then
echo shar: error transmitting atv.c '(should have been 14327 characters)'
fi
echo shar: extracting enq.c
sed 's/^XX//' << \SHAR_EOF > enq.c
XX/* *************************************************************************
XX
XX       The modified code in the appended section was extracted from
XX
XX                     MENUS, REQUESTORS, AND GADGETS 
XX                                  BY 
XX                            John T. Draper 
XX                 A service from the Programmers Network 
XX                       on the WELL in Sausalito. 
XX					 Article 408@well and 409@well
XX					      December 31, 1985
XX 
XX  Permission to post this on other networks is granted provided the 
XXsource of this information is included.   The programmers network is 
XXa non-profit network exchange of programming information.   For more 
XXinformation,  mail your requests to: 
XX 
XXWELL: crunch orsomewellprogrammerwhosequipmenthasnotbeenseized
XXBIX:  crunch orsomewellprogrammerwhosequipmenthasnotbeenseized
XXUSENET: ihnp4!ptsfa!well!crunch orsomewellprogrammerwhosequipmenthasnotbeenseized
XXDELPHI: crunch orsomewellprogrammerwhosequipmenthasnotbeenseized
XX
XX ************************************************************************* */
XX
XX/*
XX * Hacked to make autoEnquirer, a positionable position-tracking requester
XX *
XX *   Date:        July 11, 1987
XX *   Barbarian:   Howard Hull
XX *   Implements:  custom requester code from John Draper's gadget tutorial
XX *                + blood, sweat, tears, & additions to the explative list...
XX */
XX
XX/* **********************************************************
XX *
XX * ::::::::::::::::::::::::::::::::::::::::::::::::::::::::
XX * :: When you're a tiger trainer, it's a bad deal when  ::
XX * :: the tiger gets your attention by putting a paw in  ::
XX * :: your face.  This is not only because tiger paws    ::
XX * :: don't smell very good  - it's also because you'll  ::
XX * :: shortly begin to wonder what the rest of the tiger ::
XX * :: is up to.  With that paw in your face, you can't   ::
XX * :: determine what you need to know to decide on what  ::
XX * :: ought to be done next.  With tigers, it's much the ::
XX * :: same as it is with anything else:  As Will Rogers  ::
XX * :: once said, "It ain't what we know that gets us in  ::
XX * :: trouble.  It's what we know that ain't so..."      ::
XX * ::::::::::::::::::::::::::::::::::::::::::::::::::::::::
XX *
XX *
XX * I wrote this thing up because I got tired of moving the requester
XX * out of the way so I could see what was going on, and that in turn
XX * so that I could then decide what to do with the requester.  As all
XX * of you by now know, and as is evident in the net programs, if you
XX * make an AutoRequest, you get a requester at 0,0 with no programmable
XX * options to reposition it anywhere that you'd rather it be put. (Correct?)
XX *
XX * Given that the Gadget Editor Boys have not yet released their product
XX * (I think they are waiting for John Draper's life to get a little less
XX * complicated) I thought I'd put this out in the mean time.  As I'm very
XX * much a C programming novice, I'm putting this up for some presumably
XX * critical guidance.  Rather than being an example of proper code, I'm
XX * certain it contains a number of spectacular boo boos - maybe including
XX * some assumptions that would make the whole program completely unnecessary.
XX * Just as John said, requesters are a pain in the *ss.  But without a
XX * gadget editor, this is the sort of thing that has to be done...
XX *
XX */
XX
XX#include "atv.h"
XX
XXextern short wleftedge;     /* These are the variables in which we     */
XXextern short wtopedge;      /* put the first received positions.       */
XX
XXextern struct IntuiText negtext; /* Let the user keep the button names in */
XXextern struct IntuiText postext; /*  in his stuff, like for AutoRequest */
XX
XXstruct Requester req;			/* custom requester structure */ 
XX
XX/*
XX * Following is the (empty) Requester stucture template.  It contains a
XX * pointer to the host window through the RWindow structure.  (The empty
XX * Requester structure was defined just above this comment.  It is not
XX * declared, since it gets wiped clean by the InitRequester() call in the
XX * user's program.  That call could be moved into this section if the user
XX * didn't have to follow through by initializing the structure before it
XX * can be used.
XX */
XX
XX/* struct Requester req     You'll notice this is info, and not code,
XX                             as it is commented out
XX{
XXstruct Requester *OlderRequest;
XXshort LeftEdge, TopEdge;   <-- these are relative to RWindow, so we don't
XXshort Width, Height;            need to adjust them when window is moved.
XXshort RelLeft, RelTop;
XXstruct Gadget *ReqGadget;
XXstruct Border *ReqBorder;
XXstruct IntuiText *ReqText;
XXunsigned short Flags;
XXunsigned char BackFill;
XXstruct Layer *ReqLayer;
XXunsigned char ReqPad1[32];
XXstruct BitMap *ImageBMap;
XXstruct Window *RWindow;    <-- this is the link to the window in which the
XXunsigned char ReqPad2[36];      requester background is plastered.
XX}; */
XX
XX/*
XX * Following is the RWindow structure containing the LeftEdge - TopEdge
XX * definition.  We wish to keep track of these two numbers once they are
XX * initialized.  This structure is housed in the user's section.
XX */
XX
XX/* struct Window *RWindow     Again, notice that this is a comment
XX{
XXstruct Window *NextWindow;
XXshort LeftEdge, TopEdge;    <-- NULL when uninitialized, but gets set for us.
XXshort Width, Height;
XXshort MouseY, MouseX;
XXshort MinWidth, MinHeight;
XXunsigned short MaxWidth, MaxHeight;
XXunsigned long Flags;
XXstruct Menu *MenuStrip;
XXunsigned char *Title;
XXstruct Requester *FirstRequest;
XXstruct Requester *DMRequest;
XXshort ReqCount;
XXstruct Screen *WScreen;
XXstruct RastPort *RPort;
XXunsigned char BorderLeft, BorderTop, BorderRight, BorderBottom;
XXstruct RastPort *BorderRPort;
XXstruct Gadget *FirstGadget;
XXstruct Window *Parent, *Descendant;
XXushort *Pointer;
XXshort PtrHeight;
XXshort PtrWidth;
XXshort XOffset, YOffset;
XXunsigned long IDCMPFlags;
XXstruct MsgPort *UserPort, *WindowPort;
XXstruct IntuiMessage *MessageKey;
XXunsigned char DetailPen, BlockPen;
XXstruct Image *CheckMark;
XXunsigned char *ScreenTitle;
XXshort GZZMouseX;
XXshort GZZMouseY;
XXshort GZZWidth;
XXshort GZZHeight;
XXunsigned char *ExtData;
XXchar *UserData;
XXstruct Layer *WLayer;
XXstruct TextFont *IFont;
XX}; */
XX
XXshort autoEnquire();
XX
XX/***************************************************************************
XX*              I M P O R T A N T         C O N S T A N T S
XX***************************************************************************/
XX
XX#define NL 0
XX
XX#define REDP 3
XX#define BLKP 2
XX#define WHTP 1
XX#define BLUP 0
XX
XX/***************************************************************************
XX               CUSTOM REQUEST WITH TEXT, BORDERS, AND GADGETS
XX***************************************************************************/
XX
XX/* Border for buttons */
XXSHORT Pairs[] = {
XX 0, 0,			/* Coordinates relative to button position definition */
XX 43, 0,
XX 43, 12,
XX 0, 12,
XX 0,  0
XX};
XX
XX#define NUM_PAIRS 5		/* 5 pairs make a rectangle, start and stop incl */
XXstruct Border butt_border = {
XX -1,  -1,
XX BLUP, 0, JAM1,
XX NUM_PAIRS,
XX (SHORT *) Pairs,
XX NULL
XX};
XX
XX/* FALSE BUTTON */
XX#define ONE_BUTT 1      /** GadgetID used to identify the action ***/
XXstruct Gadget offgad = {
XX  NULL,
XX  7, 42,                  /* LeftEdge, TopEdge     */
XX  42, 11,                 /* Width,  Height        */
XX  GADGHCOMP,              /* Flag                  */
XX  RELVERIFY | ENDGADGET,  /* Activation            */
XX  BOOLGADGET | REQGADGET, /* GadgetType            */
XX  (APTR)&butt_border,     /* GadgetRender - Border */
XX  NULL,                   /* SelectRender          */
XX  &negtext,               /* "OK" text             */
XX  NL, NL, ONE_BUTT, NL          /* Mut Excl, Spec Info,  */
XX};
XX
XX/* TRUE BUTTON */
XX#define TWO_BUTT 2
XXstruct Gadget ongad = {
XX  &offgad,
XX  7, 22,                  /* LeftEdge, TopEdge     */
XX  42, 11,                 /* Width,  Height        */
XX  GADGHCOMP,              /* Flag                  */
XX  RELVERIFY | GADGIMMEDIATE,   /* Activation       */
XX  BOOLGADGET | REQGADGET, /* GadgetType            */
XX  (APTR)&butt_border,     /* GadgetRender - Border */
XX  NULL,                   /* SelectRender          */
XX  &postext,               /* "OK" text             */
XX  NL, NL, TWO_BUTT, NL    /* Mut Excl, Spec Info,  */
XX};
XX
XX
XX/* Outside Border of Requester */
XXSHORT ReqPairs[] = {
XX 3, 3,		/* Coordinates relative to requester sheet top left corner */
XX 53, 3,
XX 53, 57,
XX 3, 57,
XX 3, 3
XX};
XX
XXstruct Border out_border = {
XX -1, -1,
XX BLKP, 0, JAM1,
XX NUM_PAIRS,
XX (SHORT *) ReqPairs,
XX NULL
XX};
XX
XX/***************************************************************************
XX                   D O   C U S T O M    R E Q U E S T
XX***************************************************************************/
XX
XX/*
XX * Just as Enquiring minds want to know, Enquiring eyes want to see...
XX */
XX
XXautoEnquire()
XX{ 
XX
XX    short looping = TRUE;
XX	short response = FALSE;
XX    struct IntuiMessage *mes;
XX    struct Gadget *gad;           /* Gadget chosen */
XX    unsigned long class; 
XX
XX    while (looping) 
XX        { 
XX        if ((mes = (struct IntuiMessage *)GetMsg(RWindow->UserPort)) == 0L)
XX            { 
XX            (VOID) Wait(1L<<RWindow->UserPort->mp_SigBit); 
XX            continue; 
XX        } 
XX        class = mes->Class; 
XX        gad = (struct Gadget *)mes->IAddress; 
XX        (VOID) ReplyMsg(mes); 
XX        if (class == REQCLEAR)
XX            looping = FALSE; 
XX        if (class == GADGETDOWN)
XX            { 
XX            switch (gad->GadgetID)
XX                { 
XX                case TWO_BUTT:  response = (short)TWO_BUTT-1;
XX                                 EndRequest(&req, RWindow);
XX								 break; 
XX                case ONE_BUTT:  response = (short)ONE_BUTT-1;
XX                                 EndRequest(&req, RWindow);
XX								 break; 
XX
XX				/* As you can see, adding more buttons would be easy */
XX            } 
XX        } 
XX    } 
XX	wleftedge = RWindow->LeftEdge;
XX	wtopedge = RWindow->TopEdge;
XXreturn (response);
XX} 
XX
SHAR_EOF
if test 9780 -ne "`wc -c enq.c`"
then
echo shar: error transmitting enq.c '(should have been 9780 characters)'
fi
#	End of shell archive
exit 0