Intuition Requesters — Section 3.5

This article synthesises Section 3.5 ("Requesters") of Amiga C for Advanced Programmers by Bleek, Jennrich, Schulz (Abacus / Data Becker, ~1991). It covers the Intuition requester model: what a requester is, when to use one, the simple high-level API (EasyRequest, AutoRequest), and the custom-requester pattern using windows.

Editorial note: page numbers in this article refer to the PDF page index in the raw OCR source.


What a requester is (page 239)

A requester is a modal box containing one or more gadgets, used to prompt the user for input — typically when the program needs a decision before continuing execution.

"A requester appears to request this information. A requester is a box containing at least one gadget to aid user response. Text can be added to the gadgets to clarify the problem or question."

Two flavours:

  1. System requesters — issued by the OS itself (e.g. "Please insert volume DH0:"). The user cannot switch apps until the requester is dismissed. Generated by DisplayAlert().
  2. Application requesters — your code creates them on demand. They block input to your application's window until dismissed, but other apps remain usable.

The book focuses on application requesters.


The high-level API: EasyRequest and AutoRequest

For most "OK / Cancel" or "Yes / No" dialogs, the high-level API is sufficient.

EasyRequest (page ~242)

#include <intuition/intuition.h>

LONG result = EasyRequest(
    window,                            /* parent window (or NULL) */
    &easyStruct,                       /* the requester descriptor */
    NULL,                              /* IDCMP flags for the requester */
    NULL                               /* format-string args (if any) */
);

easyStruct is an EasyStruct:

struct EasyStruct {
    ULONG es_StructSize;               /* sizeof(struct EasyStruct) */
    ULONG es_Flags;                     /* 0 */
    UBYTE *es_Title;                   /* title bar text */
    UBYTE *es_TextFormat;              /* body text (printf-style format) */
    UBYTE *es_GadgetFormat;            /* gadget labels, separated by ~ */
};

For example, an OK/Cancel dialog:

struct EasyStruct es = {
    sizeof(struct EasyStruct),
    0,
    (UBYTE *)"Confirm",
    (UBYTE *)"Do you want to continue?",
    (UBYTE *)"Yes|No"
};

LONG answer = EasyRequest(win, &es, NULL, NULL);
/* answer: 0 = OK/Yes, 1 = Cancel/No, or gadget index */

The function blocks until the user clicks one of the gadgets. The return value is the 0-based index of the chosen gadget.

AutoRequest (page ~245)

AutoRequest is the simpler variant — it takes raw IntuiText arguments instead of an EasyStruct:

#include <intuition/intuition.h>

struct IntuiText body = {
    0, 1, JAM1, 0, 0, (STRPTR)"Really quit?", NULL
};
struct IntuiText negative = {
    0, 1, JAM1, 0, 0, (STRPTR)"Cancel", NULL
};
struct IntuiText positive = {
    0, 1, JAM1, 0, 0, (STRPTR)"OK", NULL
};

LONG answer = AutoRequest(win, &body, &negative, &positive, 0, 0, 300, 80);
/* answer: TRUE = positive gadget clicked, FALSE = negative */

AutoRequest is the pre-2.0 API; EasyRequest is the OS 2.0+ replacement. Both are covered.

For the full autodoc coverage, see library-reference/intuition-library.md for EasyRequestArgs() (the modern, format-string-safe variant) and SysReqHandler() (V39+ system-request integration).


Custom requesters (page ~250)

When EasyRequest isn't enough — multi-gadget requesters, custom layouts, validators — you build your own. A custom requester is just a window with the right flags:

struct NewWindow req = {
    /* position: centred over parent */
    /* size: small */
    NULL, NULL,                         /* leftedge/topedge (centred by intuition) */
    240, 60,                            /* width, height */
    0, 1,                               /* DetailPen, BlockPen */
    IDCMP_GADGETUP | IDCMP_REFRESHWINDOW,  /* IDCMP */
    WFLG_DRAGBAR | WFLG_REQACTIVE | WFLG_NOCAREREFRESH,
    NULL,                               /* gadgets */
    NULL,                               /* title */
    win->WScreen,                       /* screen */
    NULL                                /* type */
};

struct Window *rw = OpenWindow(&req);
if (rw) {
    /* add gadgets via AddGadget */
    /* run event loop, terminate when user clicks gadget */
    CloseWindow(rw);
}

The key flags for a requester-style window:

  • WFLG_REQACTIVE — the requester is "active" (input goes to it until dismissed)
  • WFLG_NOCAREREFRESH — disable automatic refresh; your application redraws in IDCMP_REFRESHWINDOW
  • IDCMP_REQSET / IDCMP_REQCLEAR events tell you when the requester gains/loses active state

The book works through a custom-requester example for the editor's "Save before quit?" dialog (page 250 onwards).


System requesters and alerts (3.5 → 3.6)

The book treats system requesters as a separate sub-section (which we cover as 3.6). The high-level call is DisplayAlert():

#include <intuition/intuition.h>

LONG result = DisplayAlert(
    AN_Unknown | AG_OpenLib,            /* alert number, with flags */
    "Could not open intuition.library!",
    NULL                                /* no args */
);

The alert constants live in <intuition/alerts.h> and are detailed in debugging/alerts-and-gurus.md. For the autodoc of DisplayAlert, see library-reference/intuition-library.md.


Lifecycle of a custom requester

The book emphasises the proper lifecycle (page ~255):

  1. Open the window with WFLG_REQACTIVE and the right IDCMP flags
  2. Add gadgets with AddGadget()
  3. Run the event loop until the user dismisses (via a button gadget, IDCMP_CLOSEWINDOW, or a Cancel key)
  4. Remove gadgets with RemoveGadget()
  5. Close the window with CloseWindow()

Common bugs:

  • Forgetting to set WFLG_REQACTIVE (then the requester doesn't grab input)
  • Forgetting to reply to IDCMP_REQSET / IDCMP_REQCLEAR messages
  • Not handling IDCMP_CLOSEWINDOW (user can't dismiss without a Cancel gadget)

Requester ergonomics (book's guidelines)

The book gives practical advice (page ~260):

  • Don't ask the user for things you could remember. If your own code just made a change, save it automatically and don't ask.
  • Do use a requester when the action is destructive (delete, overwrite, exit-without-save).
  • Default-focus the safe option (e.g. Cancel), not the destructive one. The book uses EasyRequest with gadgets listed as "Yes|No" — Note that the order matters: the first gadget gets the keyboard shortcut.
  • Don't nest requesters. A requester that pops up another requester confuses the user.
  • TimeoutAutoRequest takes a timeout (300, 80 = seconds, microseconds). For modal prompts where the user might walk away, use a timeout.

What's NOT in section 3.5

  • SysReqHandler() (V39+) — integrate your program into the system-request handling. The book predates this.
  • AslRequest() and friends — the high-level ASL requesters (file, font, screen mode). See library-reference/asl-library.md.
  • PopupMenu() / PopUpMenu() (V39+) — the modern way to put a context menu over any window. The book doesn't cover this.
  • Async requesters — the book doesn't consider requesters that don't block the caller.

Modern migration

If writing new code today:

Use this Instead of this Why
EasyRequestArgs() (V39+) EasyRequest() Format-string safety
AslRequest() Custom-requester file picker Save a day of work
Layout group + pop-asl Manual pop-up requester Sane geometry
Requester.class (BOOPSI) Manual requester window Easier custom rendering

But the fundamentals (the lifecycle, the EasyStruct descriptor, the IDCMP_REQSET/REQCLEAR event handling) all carry forward.


Sources