home *** CD-ROM | disk | FTP | other *** search
- /* Copyright 1988 by I2(EYE) Systems. JASK.C - Version 1.0
- *
- * This file contains all of the routines for this program.
- *
- *
- * JASK - Drop-in Intuitive Ask Replacement
- *
- * This software may be freely distributed provided that this notice
- * is retained. It may be hacked or used as is in any product as long
- * as you credit me for it.
- *
- * If you find this program useful for enhancing your script file
- * capabilites or as example source code, please send $5.00 to:
- *
- * I2(EYE) Systems
- * 6620 Hunter Road
- * Elkridge, MD 21227
- * Attn: J. Barshinger
- *
- * USENET or ARPANET: barsh@stsci
- *
- * Note: if you send $10.00, I'll send you the latest enhancements.
- * Planned enhancements include a re-entrant version so
- * that it can be made resident and a mouse-move capability
- * that will automatically move the pointer to the default
- * gadget.
- *
- * JASK - Intuitive Ask Replacement
- * --------------------------------
- *
- * JASK is a replacement for the ASK command distributed in the Amiga 1.3
- * enhancer package. It will allow the user to click on a gadget to specify
- * a positive or negative response rather than type it in at the keyboard.
- * You can move the "requester" to the bottom of the screen or to the front
- * or back of other screens if you don't want to answer it at the moment.
- *
- * JASK Parameters
- * ---------------
- *
- * -r This parameter specifies the "requester" text. This is
- * the question you want to ask.
- *
- * This is the only REQUIRED parameter. (40 character max.)
- *
- * EXAMPLE: "-rYour MOMMA is ?" = Your MOMMA is ? in the
- * requester box.
- * (put quotes around the string to put spaces in the text)
- *
- * -p This specifies the text for the positive (left) gadget.
- * When this gadget is selected, WARN (5) will be returned.
- * (put quotes around the string to put spaces in the text)
- * DEFAULT: YES (12 character max.)
- * EXAMPLE: -pUGLY = UGLY in the left gadget.
- *
- * -n This specifies the text for the negative (right) gadget.
- * When this gadget is selected, 0 will be returned (success).
- * (put quotes around the string to put spaces in the text)
- * DEFAULT: NO (12 character max.)
- * EXAMPLE: -nPHAT = PHAT in the right gadget.
- *
- * -t This will specify a timeout period in seconds. When the
- * timeout period expires, the default answer will be returned.
- * DEFAULT: wait forever
- * EXAMPLE: -t10 = wait 10 seconds.
- *
- * -d This parameter specifies which gadget is the default (safe)
- * answer. It does two things:
- * a) determines if the positive or negative answer is
- * to be default.
- * b) makes a more extravagant border for the specified
- * gadget.
- * n specifies the negative answer, p specifies the positive
- * answer.
- * DEFAULT: if this is not specified, both gadgets will look
- * the same, but the negative gadget will be returned.
- * EXAMPLE: -dp = Fancy gadget rendered on positive and positive
- * is the default answer.
- *
- * -q This specifies whether you want the "requester" quick or if
- * you want the "requester" to scroll up.
- * DEFAULT: the "requester" scrolls up to it final position.
- * EXAMPLE: -q = turn off the scrolling effects.
- *
- */
-
- #include "exec/types.h"
- #include "intuition/intuition.h"
-
- /* define ScreenFont1 to be the default Amiga font in Italic Mode */
-
- struct TextAttr ScreenFont1 = { "topaz.font", TOPAZ_EIGHTY,
- FSF_ITALIC, FPF_ROMFONT };
-
- /* define ScreenFont2 to be the default Amiga font */
-
- struct TextAttr ScreenFont2 = { "topaz.font", TOPAZ_EIGHTY,
- FS_NORMAL, FPF_ROMFONT };
-
- #define POS_GAD TRUE /* User value for the positive gadget */
- #define NEG_GAD FALSE /* User value for the negative gadget */
-
- /* Initialize the requester, positive gadget, and negative gadget text */
-
- char RText[] = " ";
- char PText[] = " ";
- char NText[] = " ";
-
- struct IntuiText ReqText = { /* Structure defining the Requester Text */
- 3, 2, /* front pen, back pen colors */
- JAM2, /* front pen used for text, back for background */
- 0, 0, /* LeftEdge, TopEdge offsets */
- &ScreenFont1, /* Text font to use */
- RText, /* Text to print */
- NULL }; /* Pointer to next Text structure */
-
- struct IntuiText ReqText1 = { /* Structure defining the PosGad Text */
- 1, 2, /* front pen, back pen colors */
- JAM1, /* front pen used for text, back for background */
- 2, 5, /* LeftEdge, TopEdge offsets */
- &ScreenFont2, /* Text font to use */
- PText, /* Text to print */
- NULL }; /* Pointer to next Text structure */
-
- struct IntuiText ReqText2 = { /* Structure defining the NegGad Text */
- 1, 2, /* front pen, back pen colors */
- JAM1, /* front pen used for text, back for background */
- 2, 5, /* LeftEdge, TopEdge offsets */
- &ScreenFont2, /* Text font to use */
- NText, /* Text to print */
- NULL }; /* Pointer to next Text structure */
-
- /* this data represents points offset from the actual gadget
- (xy coordinates). This puts the pen down at the first point and
- draws to the next point until done. This is used to draw the boxes
- around the Gadgets */
-
- short DefGadBorderPts[] = {
- -1, -6, /* Starting point */
- -7, -1, /* points to draw lines to... */
- -7, 20,
- -1, 25, /* This data defines the fancy gadget border */
- 100, 25, /* that you turn on with the -d parameter */
- 106, 20,
- 106, -1,
- 100, -6,
- -1, -6,
- -1, 25,
- -1, 20,
- 100, 20,
- 100, 25,
- 100, -6,
- 100, -1,
- -1, -1 };
-
- /* This data defines the inside box around the plain gadget border */
-
- short aGadBorderPts[] = {
- -1, -1, /* Starting point */
- 100, -1, /* points to draw the line to... */
- 100, 20,
- -1, 20,
- -1, -1 }; /* interior gadget box outline */
-
- /* This data defines the outside boc around the plain gadget border */
-
- short bGadBorderPts[] = {
- -4, -3, /* Starting point */
- 103, -3, /* points to draw the line to... */
- 103, 22,
- -4, 22,
- -4, -3 }; /* exterior gadget box outline */
-
- /* This structure points to the data defining the outside gadget border */
-
- struct Border NormGadBorder = {
- 0, 0, /* LeftEdge, TopEdge offsets from the gadget */
- 2, 3, JAM1, /* FrontPen, BackPen, Draw using the frontpen */
- 5, /* Number of xy coordinates in this border */
- bGadBorderPts, /* pointer to the border xy coordinates */
- NULL }; /* pointer to the next border to draw */
-
- /* This structure defines the positive gadget border(s) */
-
- struct Border GadBorder1 = {
- 0, 0, /* LeftEdge, TopEdge offsets from the gadget */
- 2, 3, JAM1, /* FrontPen, BackPen, Draw using the frontpen */
- 5, /* Number of xy coordinates in this border */
- aGadBorderPts, /* pointer to the border xy coordinates */
- &NormGadBorder };/* pointer to the outside gadget border */
-
- /* This structure defines the negative gadget border(s) */
-
- struct Border GadBorder2 = {
- 0, 0, /* LeftEdge, TopEdge offsets from the gadget */
- 2, 3, JAM1, /* FrontPen, BackPen, Draw using the frontpen */
- 5, /* Number of xy coordinates in this border */
- aGadBorderPts, /* pointer to the border xy coordinates */
- &NormGadBorder };/* pointer to the outside gadget border */
-
- /* Structure defining the Negative Gadget */
-
- struct Gadget ReqGad2 = {
- NULL, /* pointer to next gadget */
- 500, 10, /* LeftEdge, TopEdge offsets within window */
- 100, 20, /* Width, Height of the gadget */
- GADGHCOMP, /* Complement the gadget color when pressed */
- RELVERIFY, /* Pointer must be in gadget when released */
- BOOLGADGET, /* This is a boolean gadget */
- (APTR)(&GadBorder2), /* pointer to the gadget's borders */
- NULL, /* pointer to image when gadget is selected */
- &ReqText2, /* pointer to gadget's text */
- NULL, NULL, /* Mutual exclude, special info flags */
- NEG_GAD, /* User data defining gadget id */
- NULL }; /* Pointer to user data */
-
- /* Structure defining the Positive Gadget */
-
- struct Gadget ReqGad1 = {
- &ReqGad2, /* pointer to next gadget */
- 40, 10, /* LeftEdge, TopEdge offsets within window */
- 100, 20, /* Width, Height of the gadget */
- GADGHCOMP, /* Complement the gadget color when pressed */
- RELVERIFY, /* Pointer must be in gadget when released */
- BOOLGADGET, /* This is a boolean gadget */
- (APTR)(&GadBorder1), /* pointer to the gadget's borders */
- NULL, /* pointer to image when gadget is selected */
- &ReqText1, /* pointer to gadget's text */
- NULL, NULL, /* Mutual exclude, special info flags */
- POS_GAD, /* User data defining gadget id */
- NULL }; /* Pointer to user data */
-
- /* Structure defining the Screen */
-
- struct NewScreen ReqScreen = {
- 0, 210, /* LeftEdge, TopEdge */
- 640, 53, /* Width, Height */
- 2, /* Depth - number of bit-planes */
- 2, 3, /* DetailPen, BlockPen */
- HIRES, /* ViewModes - 640X200 */
- CUSTOMSCREEN, /* Screen Type */
- &ScreenFont2, /* Default Font */
- "JRBII's Ask Requester V1.0", /* Default Title */
- NULL, /* Gadgets, currently ignored */
- NULL }; /* Custom Bit Map */
-
- /* Structure defining the Window */
-
- struct NewWindow ReqWindow = {
- 0, 10, /* LeftEdge, TopEdge offset within screen */
- 640, 43, /* Width, Height */
- -1, -1, /* DetailPen, BlockPen, -1 means same as screen */
- GADGETUP, /* IDCMP Flags, send message on Gadget selected */
- ACTIVATE, /* Window Flags - Activate the window */
- &ReqGad1, /* Pointer to FirstGadget in window */
- NULL, /* CheckMark */
- NULL, /* Window title */
- NULL, /* Pointer to Screen */
- NULL, /* Pointer to BitMap */
- 0, 0, /* Minimum width, Minimum height */
- 0, 0, /* Maximum width, Maximum height */
- CUSTOMSCREEN }; /* Screen Type for this Window */
-
- struct Window *ReqWin = NULL; /* pointer to a Window structure */
- struct Screen *ReqScr = NULL; /* pointer to a Screen structure */
-
- struct Window *OpenWindow(); /* define the OpenWindow routine */
- struct Screen *OpenScreen(); /* define the OpenScreen routine */
-
- LONG IntuitionBase = NULL; /* Address of Intuition library */
- /* IT MUST BE A GLOBAL SYMBOL */
-
- LONG result; /* result returned to the script file */
- int timeout; /* number of seconds before timeout */
- struct IntuiMessage *msg; /* Message pointer for msg received */
- /* from the IDCMP. */
-
-
- /* This routine cleans up and returns "result" to AmigaDos. It is */
- /* called for normal termination of the program, in addition to any */
- /* error conditions encountered. */
-
- void Done()
- {
-
- /* if there is a message leftover, return it to Intuition */
-
- if (msg != 0) ReplyMsg(msg);
-
- /* if the Window exists, close it */
-
- if (ReqWin != NULL) CloseWindow(ReqWin);
-
- /* if the Screen is open, close it */
-
- if (ReqScr != NULL) CloseScreen(ReqScr);
-
- /* if the Intuition library is open, close it */
-
- if (IntuitionBase != NULL) CloseLibrary(IntuitionBase);
-
- /* return result to AmigaDos */
-
- exit(result);
-
- } /* end Done() */
-
-
- /* This routine parses the command line parameters and sets up the */
- /* requested special effects */
- /* Parsing and error checking has been kept to a minimum here to */
- /* keep the executable code size as small as possible */
-
- void Parse_Args(argc, argv)
- int argc; /* count of parameters passed */
- char *argv[]; /* pointer to the parameters */
- {
- char i, k, x, y, error, rfound, pfound, nfound, *arg;
-
- error = 0; /* error counter */
- rfound = FALSE; /* -r parameter found?, it's a required parm */
- pfound = FALSE; /* -p parameter found? */
- nfound = FALSE; /* -n parameter found? */
-
- for (i=1; i<argc; i++) /* go through all the parameters */
- {
- arg = argv[i]; /* get pointer to the current parameter */
-
- if (arg[0] != '-') error++; /* make sure there's a dash */
-
- /* determine which parameter this is */
-
- switch (tolower(arg[1])) /* convert the char to lower */
- {
-
- case 'q': /* quick parameter */
- ReqScreen.TopEdge = 146; /* put the screen in */
- /* its final location */
- break;
-
- case 'r': /* requester text parmeter */
- if (!rfound)
- {
- rfound = TRUE; /* set -r parm found flag */
-
- /* if parm text is greater than its max size */
- /* truncate it to max size, save the size in k*/
- if ((k = strlen(&arg[2])) > 40)
- k = 40;
-
- /* calculate the number of spaces needed to */
- /* center the text in the requester */
- x = (40 - k) / 2;
-
- /* copy the text into the requester text array */
- for (y = 2; y < k+2; x++, y++)
- RText[x] = arg[y];
- };
-
- break;
-
- case 'p': /* Positive Gadget text parm */
- if (!pfound)
- {
- pfound = TRUE; /* set -p parm found flag */
-
- /* if input text is greater than its max size */
- /* truncate it to max size, save the size in k*/
- if ((k = strlen(&arg[2])) > 12)
- k = 12;
-
- /* calculate the number of spaces needed to */
- /* center the text in the Gadget */
- x = (12 - k) / 2;
-
- /* copy the text into the PosGad text array */
- for (y = 2; y < k+2; x++, y++)
- PText[x] = arg[y];
- };
-
- break;
-
- case 'n': /* Negative Gadget text parm */
- if (!nfound)
- {
- nfound = TRUE; /* set -n parm found flag */
-
- /* if input text is greater than its max size */
- /* truncate it to max size, save the size in k */
- if ((k = strlen(&arg[2])) > 12)
- k = 12;
-
- /* calculate the number of spaces needed to */
- /* center the text in the Gadget */
- x = (12 - k) / 2;
-
- /* copy the text into the NegGad text array */
- for (y = 2; y < k+2; x++, y++)
- NText[x] = arg[y];
- };
-
- break;
-
- case 't': /* Timeout parameter */
-
- /* convert the string to an integer value */
- stcd_i(&arg[2],&timeout);
-
- timeout *= 10; /* our clock ticks 10 times per */
- /* second, so multiply the */
- /* timeout by 10 to get seconds */
-
- /* Cause the IDCMP to get a timer message */
- /* 10 times per second in addition to receiving */
- /* gadget selection messages */
- ReqWindow.IDCMPFlags = GADGETUP|INTUITICKS;
- break;
-
- case 'd': /* Default specifier parm */
- if (tolower(arg[2]) == 'n')
- { /* Negative Gadget Specified */
- /* Setup the gadget border to use the */
- /* fancy border */
- GadBorder2.Count = 16; /* 16 xy points */
- GadBorder2.XY = DefGadBorderPts;
- GadBorder2.NextBorder = NULL;
- result = 0; /* default result is Neg */
- }
- else if (tolower(arg[2]) == 'p')
- { /* Pos Gadget specified */
- /* Setup the gadget border to use the */
- /* fancy border */
- GadBorder1.Count = 16; /* 16 xy points */
- GadBorder1.XY = DefGadBorderPts;
- GadBorder1.NextBorder = NULL;
- result = 5; /* default result is Pos */
- }
- else error++; /* anything except 0 or 1 is err */
- break;
-
- default: /* Any other parameters specifiers are wrong */
- error++;
- break;
-
- }; /* end switch */
-
- }; /* end for */
-
- if (!pfound) /* if pos text not specified, just say YES */
- {
- PText[4] = 'Y';
- PText[5] = 'E';
- PText[6] = 'S';
- };
-
- if (!nfound) /* if neg text not specified, just say NO */
- {
- NText[5] = 'N';
- NText[6] = 'O';
- };
-
- if (error || (!rfound)) /* if an error occurred... */
- {
- /* print the usage message */
- puts("USAGE: jask -r [-q] [-p] [-n] [-t] [-d]");
- exit(10); /* and exit back to AmigaDos */
- };
-
- } /* end Parse_Args() */
-
-
- void main(argc, argv)
- int argc;
- char *argv[];
- {
- struct Gadget *Gad; /* pointer to the Gadget message */
- short GadID; /* Gadget ID for the message */
- int time; /* number of ticks since program start */
- char i;
-
- time = 0; /* initialize time to 0 */
- result = 0; /* default result is 0, if not specified */
-
- Parse_Args(argc, argv); /* Parse the command line parameters */
-
- /* Open the intuition library, on error exit... */
-
- if ((IntuitionBase = OpenLibrary("intuition.library",0)) == NULL)
- {
- puts("Error opening the intuition library");
- exit(10);
- };
-
- /* Open the Screen, on error call done to also close the */
- /* intuition library */
-
- if ((ReqScr = OpenScreen(&ReqScreen)) == NULL)
- {
- puts("Can't open ReqScreen\n");
- result = 10;
- Done();
- };
-
- ReqWindow.Screen = ReqScr; /* Put the screen address in */
- /* window structure, so the */
- /* window knows where to go */
-
- /* Open the window, on error call done to close the screen and */
- /* the intuition library */
-
- if ((ReqWin = OpenWindow(&ReqWindow)) == NULL)
- {
- puts("Can't open ReqWindow\n");
- result = 10;
- Done();
- };
-
- /* Print the requester text into the window at x=160, y=15 */
-
- PrintIText(ReqWin->RPort,&ReqText,160,15);
-
- /* Scroll the screen up to its final position, unless the -q */
- /* option was specified, which automatically puts it in its */
- /* final position */
-
- for (i=0; ((i<64) && (ReqScreen.TopEdge > 200)) ; i++)
- MoveScreen(ReqScr, 0, -1);
-
- while(TRUE) /* loop forever, exit on GADGETUP or timeout */
- {
-
- /* Wait for an intuition message from the window's port */
-
- WaitPort( ReqWin->UserPort );
-
- /* Message received, so get a pointer to it */
-
- msg = (struct IntuiMessage *) GetMsg(ReqWin->UserPort);
-
- /* We could recieve more that one message, so loop */
- /* until all have been processed */
-
- while (msg != 0)
- {
-
- /* switch on the type of message received */
-
- switch (msg->Class)
- {
- case GADGETUP: /* A Gadget was selected */
-
- /* Get the address of the Gadget */
-
- Gad = (struct Gadget *)(msg->IAddress);
-
- /* Determine which gadget was selected */
-
- GadID = Gad->GadgetID;
-
- /* if GadID is TRUE, the pos gadget was */
- /* selected, else the neg was selected */
- /* set the result appropriately */
-
- if (GadID)
- result = 5;
- else
- result = 0;
-
- /* We're done, close whatever we opened */
- /* and return the result to AmigaDos */
-
- Done();
- break;
-
- case INTUITICKS: /* A timer msg was received */
-
- /* if the tick count is greater than */
- /* timeout, we're done, so close what- */
- /* ever we opened and send the default */
- /* result to AmigaDos */
-
- if (time++ > timeout) Done();
- break;
- } /* switch (msg->class)... */
-
- ReplyMsg(msg); /* Done with the msg, so send it */
- /* back to intuition */
-
- /* Get the next message, if any */
-
- msg = (struct IntuiMessage *)
- GetMsg(ReqWin->UserPort);
-
- } /* end while (msg != 0)... */
-
- } /* end while (TRUE)... */
-
- } /* end main() */
-
- /* End of file - JASK.C */
-