Intuition Windows — Section 3.1 Walkthrough

This article synthesises Section 3.1 ("Windows") of Amiga C for Advanced Programmers by Bleek, Jennrich, Schulz (Abacus / Data Becker, ~1991). Section 3.1 is the longest single section in the chapter (~40 pages, PDF pages 94–132) and covers the Intuition window model: the NewWindow structure, OpenWindow flags, IDCMP event classes, refresh events, gadget attachment, and the standard event loop pattern.

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


Why windows are the most important UI primitive (page 94)

The book opens the section with a strong claim:

"Windows are the most important input/output medium. We wanted to present a detailed description of a complete application you could program in C, then continue to improve upon it throughout this book. We decided on creating a text editor for C programs. Therefore this section supplies you with information about programming fundamental I/O, and selecting what to use from the many options."

The rest of the chapter (and most of Chapter 4) builds the editor example on top of the window primitive. So this section is the most rigorous.


The NewWindow structure (page 95–96)

NewWindow is the declarative descriptor. The book's version (legacy AmigaOS 1.x style):

struct NewWindow {
    SHORT LeftEdge, TopEdge;       /* position */
    SHORT Width, Height;           /* size */
    UBYTE DetailPen, BlockPen;     /* pens */
    ULONG IDCMPFlags;              /* events you want */
    ULONG Flags;                   /* window behaviours */
    struct Gadget *FirstGadget;    /* gadget chain */
    struct Image *CheckMark;       /* custom menu checkmark (or NULL) */
    UBYTE *Title;                  /* title text */
    struct Screen *Screen;         /* custom screen (for CUSTOMSCREEN) */
    struct BitMap *BitMap;         /* for WFLG_SUPER_BITMAP */
    SHORT MinWidth, MinHeight;     /* sizing limits */
    USHORT MaxWidth, MaxHeight;
    USHORT Type;                   /* WBENCHSCREEN or CUSTOMSCREEN */
};

The fields map directly to today's OpenWindowTagList() tags. Each field:

Geometry: LeftEdge, TopEdge, Width, Height

  • LeftEdge, TopEdge — top-left corner, in screen pixels.
  • Width, Height — outer dimensions, including the title bar and borders (unless WFLG_GIMMEZEROZERO is used, the drawing area starts inside the borders). Standard screen widths: 320 (LORES), 640 (HIRES).

Pens: DetailPen, BlockPen

Like screens, windows use the pen model. DetailPen is for text; BlockPen is for backgrounds. Pen indices are 0-7.

IDCMPFlags: which events?

IDCMPFlags is a bitmask of event classes. Common flags (book's table on page ~98):

Flag Event
IDCMP_CLOSEWINDOW 2.0+ User clicked the close gadget
IDCMP_REFRESHWINDOW 2.0+ Window contents need redraw
IDCMP_MOUSEBUTTONS 2.0+ Mouse button click/release
IDCMP_MOUSEMOVE 2.0+ Mouse moved over the window
IDCMP_GADGETUP 2.0+ A classic gadget was released
IDCMP_GADGETDOWN 2.0+ A classic gadget was pressed
IDCMP_MENUPICK 2.0+ User selected a menu item
IDCMP_RAWKEY 2.0+ Raw key press/release
IDCMP_VANILLAKEY 2.0+ Key translated to ASCII through the keymap
IDCMP_ACTIVEWINDOW / IDCMP_INACTIVEWINDOW Window focus change
IDCMP_INTUITICKS 2.0+ Periodic tick (for animation)
IDCMP_IDCMPUPDATE 2.0+ Attribute updates from BOOPSI gadgets (ICA_TARGET = ICTARGET_IDCMP)

The book's editor only uses a subset: IDCMP_CLOSEWINDOW | IDCMP_MENUPICK | IDCMP_MOUSEBUTTONS | IDCMP_RAWKEY | IDCMP_REFRESHWINDOW. This is the minimum-viable set.

Modern editors extend with IDCMP_VANILLAKEY for printable keys and IDCMP_NEWSIZE for resize-aware redraw.

Flags: window behaviour

Flags is the most varied field. Book covers extensively (page ~99 onwards). The major flags:

Flag Effect
WFLG_CLOSEGADGET 2.0+ Add a close gadget to title bar
WFLG_SIZEGADGET 2.0+ Add a size gadget (resize)
WFLG_DEPTHGADGET 2.0+ Add a depth gadget
WFLG_DRAGBAR 2.0+ Add a draggable title bar
WFLG_ACTIVATE 2.0+ Make the window active (input focus) on open
WFLG_GIMMEZEROZERO 2.0+ Reserve inner origin (0,0) instead of (leftedge+border, topedge+titlebar)
WFLG_BORDERLESS 2.0+ No border
WFLG_BACKDROP 2.0+ Make window a backdrop (stays behind other windows)
WFLG_SUPER_BITMAP 2.0+ Allocates a superbitmap refresh region
WFLG_SIMPLE_REFRESH 2.0+ Application is responsible for redraw
WFLG_SMART_REFRESH 2.0+ Intuition saves obscured areas off-screen and restores them itself
WFLG_NOCAREREFRESH 2.0+ No IDCMP_REFRESHWINDOW messages; Intuition handles the refresh bookkeeping

Smart vs simple refresh is critical: simple refresh means the application must redraw every damaged area itself; smart refresh costs memory (Intuition keeps backing store for hidden parts) but the app only redraws after sizing. See intuition/intuition-layer-locking.md for the locking rules.


OpenWindow — the call

struct Window *win = OpenWindow(&nw);
if (!win) {
    /* failure: OpenWindow() just returns NULL (IoErr() does not apply) */
}

The book's editor helper:

if (!(win = (struct Window *)OpenWindow(&nw))) {
    printf("Window can't be opened!\n");
    Close_All();
    exit(FALSE);
}

The book emphasises that OpenWindow() can fail for many reasons (no memory, screen mode not available, screen Lock()ed, etc.) and that the failure path needs to be just as robust as the success path.


The event loop

The book's "hello-world"-equivalent event loop (the pattern is identical for all the example programs):

BOOL done = FALSE;
while (!done) {
    WaitPort(win->UserPort);   /* block until an event arrives */
    while ((msg = GetMsg(win->UserPort))) {
        switch (msg->Class) {
            case IDCMP_CLOSEWINDOW:
                done = TRUE;
                break;
            case IDCMP_REFRESHWINDOW:
                BeginRefresh(win);
                /* ... redraw content ... */
                EndRefresh(win, TRUE);
                break;
            /* ... other events ... */
        }
        ReplyMsg(msg);
    }
}

This is the canonical Intuition event loop. Later code typically adds:

  • Wait() on a combined signal mask instead of WaitPort() (to service several ports)
  • win->UserData to attach application state to the window

But the overall structure is unchanged: wait, get, dispatch, reply.


Refresh events in detail (page ~110)

The book devotes several pages to refresh, because it's the most error-prone part of Intuition programming.

  • IDCMP_REFRESHWINDOW arrives when: window is opened, exposed after being hidden, sized, or moved
  • The application's response is BeginRefresh(win) + draw + EndRefresh(win, complete=TRUE)
  • Within BeginRefresh/EndRefresh, the application can use the window's RastPort for drawing
  • Outside these calls, drawing primitives may not clip correctly

The book gives a worked example for text-refresh (page ~115): the editor redraws the visible text line range in response to a refresh event.


Window ports and message ports

OpenWindow allocates a MsgPort for events; access via win->UserPort. This is your port, not Intuition's — you must ReplyMsg() every message to free the port slot.

The book covers:

  • WaitPort() vs Wait() — both are exec.library functions; WaitPort() waits on a single port, Wait() on any set of signals (multi-source waiting)
  • GetMsg() returns one message; loop until NULL
  • ReplyMsg() frees the message structure (which is allocated by intuition.library)

Drag, size, depth, close gadgets

These are system gadgets that Intuition maintains. The book explains:

  • The system gadgets are part of the window's FirstGadget chain
  • They send IDCMP events when activated
  • WFLG_*GADGET flags enable each one
  • Custom system gadgets (e.g. zoom, iconify) came later via the WA_Zoom (V36) and WA_IconifyGadget (V47) tags

The book doesn't cover the modern BOOPSI system gadget replacement (window.class).


Window locking (book's caveats)

The book mentions briefly (page ~120) the gotchas of window locking but doesn't go deep. The serious modern coverage is in intuition/intuition-layer-locking.md, which the book can't anticipate:

  • Layer locks must be balanced
  • ObtainGIRPort() is implicit — heavy users may want to avoid it

What's NOT in section 3.1

  • Tag-based window creation (OpenWindowTagList) — comes later. The book predates OS 2.0 tag APIs.
  • BOOPSI window classes (window.class) — modern AmigaOS uses these.
  • Zoom and iconify gadgets — WA_Zoom (V36), WA_IconifyGadget (V47).
  • Borderless windows with image rendering (WA_Backdrop) is touched briefly; full coverage is in NDK 3.x.
  • Modal windows — the book covers requesters (3.5) instead.
  • Backdrop windows (WFLG_BACKDROP) — covered briefly but not deeply.

Sources

The window model in section 3.1 is essentially identical to the modern AmigaOS intuition.library API; the migration path from NewWindow/OpenWindow to OpenWindowTagList is mechanical, and the event loop pattern carries forward without change.