Transformed 8 stub articles (720 lines total) into full bootcamp-grade references (5,100+ lines) with architecture diagrams, complete code examples, struct field references, pitfalls, and best practices. IDCMP (idcmp.md — 1,060 lines): - IntuiMessage field reference with types, sizes, value ranges - Use-case cookbook: double-click, rubber-band, multi-signal, BOOPSI - When to use IDCMP vs alternatives (decision flowchart) - 5 named antipatterns with WRONG/RIGHT code - Memory safety checklist and defensive event loop template - Cross-platform comparison table (Win32, X11, Cocoa, Qt) Input Events (input_events.md — 850 lines): - Event class routing and QoS analysis (priority-as-QoS hierarchy) - Intuition consumption table (what survives the handler chain) - lowlevel.library bypass for CD32/game input - Latency analysis with pipeline timing budget (68000 vs 68040) - Input strategy comparison (IDCMP vs handler vs direct hardware) - Game input patterns: direct HW polling, CIA keyboard, hybrid handler - Signal pattern for proper handler→application communication Windows (windows.md — 370 lines): - Window anatomy diagram, WA_ tag reference tables - Refresh modes comparison (Simple/Smart/SuperBitMap) - Window types: standard, backdrop, borderless, GimmeZeroZero - Coordinate system, border offsets, struct Window fields - Modification API (move, resize, title, busy pointer) Gadgets (gadgets.md — 403 lines): - Three-generation evolution (raw/GadTools/BOOPSI) - Complete GadTools lifecycle with setup, creation, events, cleanup - Runtime state updates (GadTools vs raw Intuition) - Raw struct Gadget: GFLG_*, GACT_*, GTYP_* flag tables - Proportional and string gadget internals BOOPSI (boopsi.md — 505 lines): - Class hierarchy Mermaid diagram - Method dispatch sequence diagram - ICA interconnection architecture (icclass, modelclass, ICTARGET_IDCMP) - Full custom gadget class tutorial (4 steps with complete code) - Built-in class reference table - C++/Qt analog comparison table Menus (menus.md — 378 lines): - Menu hierarchy diagram (Menu → Item → Sub-Item) - GadTools NewMenu workflow with field reference - Event handling with multi-select chain walking - Checkmark/mutual exclusion, sub-menus, dynamic modification - Keyboard shortcut system (single-char and NM_COMMANDSTRING) Requesters (requesters.md — 370 lines): - EasyRequest return value logic table - ASL file requester with multi-select and full tag reference - ASL font and screenmode requesters - Non-blocking BuildEasyRequest/SysReqHandler pattern - Requester state persistence IntuitionBase (intuition_base.md — 267 lines): - Library version table (OS 1.2 through 3.2.x) - Struct field reference with safety annotations - ViewLord architecture diagram - LockIBase vs Forbid/Permit guidance - Complete library function overview (5 categories) README index updated with enriched article descriptions.
11 KiB
Requesters
What Is a Requester?
A requester is a modal dialog — a focused interaction that temporarily blocks user access to its parent window until the user responds. Amiga requesters come in several flavors:
| Type | API | Use Case |
|---|---|---|
| EasyRequest | EasyRequest() / EasyRequestArgs() |
Simple message dialogs (alerts, confirmations) |
| AutoRequest | AutoRequest() |
Legacy OS 1.x two-button dialog |
| ASL File | asl.library — ASL_FileRequest |
File open/save dialogs |
| ASL Font | asl.library — ASL_FontRequest |
Font picker |
| ASL ScreenMode | asl.library — ASL_ScreenModeRequest |
Display mode picker |
| Custom | Request() / BOOPSI |
Application-defined forms |
EasyRequest (OS 2.0+)
The standard way to show message dialogs — supports printf-style formatting and arbitrary button layouts:
Basic Usage
struct EasyStruct es = {
sizeof(struct EasyStruct),
0, /* Flags (reserved) */
"Warning", /* Window title */
"Delete file '%s'?\n"
"This action cannot be undone.", /* Body text (printf format) */
"Delete|Cancel" /* Button labels (| separated) */
};
LONG result = EasyRequest(win, &es, NULL, filename);
Return Value Logic
The return value mapping is not intuitive — it follows a specific pattern:
| Buttons | Click | Return Value |
|---|---|---|
"OK" |
OK | 1 |
"Yes|No" |
Yes | 1 |
"Yes|No" |
No | 0 |
"Save|Don't Save|Cancel" |
Save | 1 |
"Save|Don't Save|Cancel" |
Don't Save | 2 |
"Save|Don't Save|Cancel" |
Cancel | 0 |
Rule: The rightmost button always returns 0 (typically "Cancel"). All other buttons return 1, 2, 3... from left to right.
Printf-Style Formatting
The body text supports %s, %ld, %lx, etc. Additional arguments are passed after the IDCMP_Ptr parameter:
struct EasyStruct es = {
sizeof(struct EasyStruct), 0,
"Disk Error",
"Error %ld occurred while\n"
"reading '%s' from %s:",
"Retry|Abort"
};
/* Pass format arguments as varargs */
LONG result = EasyRequest(win, &es, NULL,
errorCode, /* %ld */
fileName, /* %s */
deviceName /* %s */
);
Non-Blocking Variant
/* For situations where you can't block (e.g., input handler): */
struct Window *reqWin = BuildEasyRequest(win, &es, IDCMP_DISKINSERTED, args);
/* Poll for response (returns -1 while still open): */
LONG response;
while ((response = SysReqHandler(reqWin, NULL, FALSE)) == -1)
{
/* Do other work or Wait() */
Wait(1L << reqWin->UserPort->mp_SigBit);
}
FreeSysRequest(reqWin);
ASL File Requester
The standard file open/save dialog provided by asl.library:
Opening a File
#include <libraries/asl.h>
#include <proto/asl.h>
struct Library *AslBase = OpenLibrary("asl.library", 39);
struct FileRequester *fr = AllocAslRequestTags(ASL_FileRequest,
ASLFR_TitleText, "Open File",
ASLFR_InitialDrawer, "SYS:Docs",
ASLFR_InitialFile, "",
ASLFR_InitialPattern, "#?.(txt|doc|guide)",
ASLFR_DoPatterns, TRUE, /* Show pattern gadget */
ASLFR_DoMultiSelect, FALSE, /* Single file selection */
ASLFR_RejectIcons, TRUE, /* Hide .info files */
TAG_DONE);
if (AslRequest(fr, NULL))
{
/* User clicked "OK" */
char fullPath[512];
strcpy(fullPath, fr->fr_Drawer);
AddPart(fullPath, fr->fr_File, sizeof(fullPath));
Printf("Selected: %s\n", fullPath);
}
else
{
/* User clicked "Cancel" */
}
FreeAslRequest(fr);
CloseLibrary(AslBase);
Save Dialog
struct FileRequester *fr = AllocAslRequestTags(ASL_FileRequest,
ASLFR_TitleText, "Save As...",
ASLFR_InitialDrawer, currentDrawer,
ASLFR_InitialFile, currentFile,
ASLFR_DoSaveMode, TRUE, /* "Save" button instead of "Open" */
ASLFR_DoPatterns, TRUE,
TAG_DONE);
Multi-Select
struct FileRequester *fr = AllocAslRequestTags(ASL_FileRequest,
ASLFR_TitleText, "Select Files",
ASLFR_DoMultiSelect, TRUE,
TAG_DONE);
if (AslRequest(fr, NULL))
{
if (fr->fr_NumArgs > 0)
{
/* Multi-select: iterate the WBArg array */
for (LONG i = 0; i < fr->fr_NumArgs; i++)
{
Printf("File: %s\n", fr->fr_ArgList[i].wa_Name);
}
}
else
{
/* Single file selected (even in multi-select mode) */
Printf("File: %s%s\n", fr->fr_Drawer, fr->fr_File);
}
}
Common ASL File Tags
| Tag | Type | Description |
|---|---|---|
ASLFR_TitleText |
STRPTR |
Requester window title |
ASLFR_InitialDrawer |
STRPTR |
Starting directory |
ASLFR_InitialFile |
STRPTR |
Pre-selected filename |
ASLFR_InitialPattern |
STRPTR |
AmigaOS pattern filter (e.g., #?.txt) |
ASLFR_DoPatterns |
BOOL |
Show pattern matching gadget |
ASLFR_DoSaveMode |
BOOL |
Show "Save" button instead of "Open" |
ASLFR_DoMultiSelect |
BOOL |
Allow multiple file selection |
ASLFR_RejectIcons |
BOOL |
Hide .info icon files |
ASLFR_DrawersOnly |
BOOL |
Only show directories (folder picker) |
ASLFR_InitialLeftEdge/TopEdge |
WORD |
Requester position |
ASLFR_InitialWidth/Height |
WORD |
Requester size |
ASLFR_Window |
struct Window * |
Parent window (for positioning) |
ASLFR_Screen |
struct Screen * |
Screen to open on |
ASLFR_FilterFunc |
struct Hook * |
Custom filtering function |
ASL Font Requester
struct FontRequester *fo = AllocAslRequestTags(ASL_FontRequest,
ASLFO_TitleText, "Select Font",
ASLFO_InitialName, "topaz.font",
ASLFO_InitialSize, 8,
ASLFO_DoFrontPen, TRUE, /* Show color picker */
ASLFO_DoStyle, TRUE, /* Show Bold/Italic/Underline */
ASLFO_DoDrawMode, TRUE, /* Show JAM1/JAM2 selector */
ASLFO_MinHeight, 6, /* Minimum font size */
ASLFO_MaxHeight, 72, /* Maximum font size */
TAG_DONE);
if (AslRequest(fo, NULL))
{
Printf("Font: %s %ld\n", fo->fo_Attr.ta_Name, fo->fo_Attr.ta_YSize);
Printf("Style: %ld, FrontPen: %ld\n", fo->fo_Attr.ta_Style, fo->fo_FrontPen);
/* Open the selected font */
struct TextFont *font = OpenDiskFont(&fo->fo_Attr);
if (font)
{
SetFont(win->RPort, font);
/* ... */
CloseFont(font);
}
}
FreeAslRequest(fo);
ASL ScreenMode Requester
For applications that let users choose their display mode:
struct ScreenModeRequester *smr = AllocAslRequestTags(ASL_ScreenModeRequest,
ASLSM_TitleText, "Select Screen Mode",
ASLSM_InitialDisplayID, HIRES_KEY,
ASLSM_InitialDisplayDepth, 4,
ASLSM_DoWidth, TRUE, /* Allow width selection */
ASLSM_DoHeight, TRUE, /* Allow height selection */
ASLSM_DoDepth, TRUE, /* Allow depth selection */
ASLSM_DoOverscanType, TRUE, /* Allow overscan selection */
ASLSM_MinWidth, 320,
ASLSM_MinHeight, 200,
ASLSM_MinDepth, 1,
ASLSM_MaxDepth, 8,
TAG_DONE);
if (AslRequest(smr, NULL))
{
Printf("Mode: 0x%08lx, %ldx%ldx%ld\n",
smr->sm_DisplayID,
smr->sm_DisplayWidth,
smr->sm_DisplayHeight,
smr->sm_DisplayDepth);
/* Open screen with selected mode */
struct Screen *scr = OpenScreenTags(NULL,
SA_DisplayID, smr->sm_DisplayID,
SA_Width, smr->sm_DisplayWidth,
SA_Height, smr->sm_DisplayHeight,
SA_Depth, smr->sm_DisplayDepth,
SA_Overscan, smr->sm_OverscanType,
SA_AutoScroll, TRUE,
TAG_DONE);
}
FreeAslRequest(smr);
Custom Window Requesters
For application-specific forms, use Request() with a custom layout:
/* Create a requester with gadgets */
struct Requester req;
InitRequester(&req);
req.LeftEdge = 20;
req.TopEdge = 20;
req.Width = 300;
req.Height = 100;
req.ReqGadget = myGadgetList; /* Your gadgets */
req.ReqText = myIntuiText; /* Labels */
req.BackFill = 0; /* Background pen */
req.Flags = 0;
req.ReqBorder = myBorder; /* Border decoration */
/* Activate the requester (blocks the parent window) */
if (Request(&req, win))
{
/* Requester is active — handle IDCMP_GADGETUP events */
/* When done: */
EndRequest(&req, win);
}
Most modern applications use
EasyRequest()for simple dialogs or build custom windows instead ofRequest(). TheRequest()API is mainly relevant for legacy code.
Remembering Requester State
ASL requesters remember their last position and selections if you reuse the same requester structure:
/* Allocate once at program start */
struct FileRequester *fr = AllocAslRequestTags(ASL_FileRequest,
ASLFR_TitleText, "Open", TAG_DONE);
/* First use — shows default directory */
AslRequest(fr, NULL);
/* Second use — automatically shows the directory from last use */
AslRequest(fr, NULL);
/* Free at program exit */
FreeAslRequest(fr);
You can override this with explicit tags on each call:
AslRequest(fr, (struct TagItem *)(APTR[]){
{ ASLFR_InitialDrawer, (ULONG)"RAM:" },
{ TAG_DONE, 0 }
});
Pitfalls
1. EasyRequest Return Value Confusion
The rightmost button always returns 0, not the button count. For "Yes|No", "No" returns 0 — which many developers mistake for FALSE when it's actually the "No" response.
2. ASL Without a Window Reference
If you don't pass ASLFR_Window, the requester opens at a default position, potentially on a different screen or off-screen.
3. Not Checking AslRequest Return
AslRequest() returns FALSE if the user cancels. Always check — accessing fr->fr_File after cancellation returns the previous (stale) selection.
4. Forgetting FreeAslRequest
ASL requesters allocate internal memory for file lists and paths. Failing to call FreeAslRequest() leaks memory.
5. Blocking While Requester Is Open
EasyRequest and AslRequest are synchronous — your event loop is stopped while the requester is open. If you need to handle background events, use the non-blocking BuildEasyRequest()/SysReqHandler() pattern.
Best Practices
- Use
EasyRequest()for all message dialogs — notAutoRequest()(OS 1.x legacy) - Place "Cancel" as the rightmost button — it always returns 0, matching the Amiga convention
- Pass the parent window to requesters — for proper screen placement and depth arrangement
- Reuse ASL requesters — users expect the dialog to remember their last directory
- Use
ASLFR_DoPatterns, TRUE— power users rely on pattern matching - Use
ASLFR_RejectIcons, TRUE—.infofiles clutter the file list - Use
BuildEasyRequest()when you need to handle events during a dialog - Always check return values — a canceled requester should not proceed with the operation