amiga-bootcamp/09_intuition/README.md
Ilia Sharin 27cad8128d docs: expand final 3 Tier 3 articles + update all README indexes
Articles expanded:
- gadgets.md: 403→804 lines — 5 antipatterns, GadTools→BOOPSI migration,
  form cookbook, historical timeline, modern analogies, 6 FAQ
- screens.md: 582→992 lines — decision guide, 5 antipatterns, screen
  flipping/borderless/PAL-NTSC cookbooks, historical comparison, 7 FAQ
- custom_loaders_and_drm.md: 152→500 lines — bootblock structure,
  6 DRM systems, 5 antipatterns, trackloader cookbook, cracking scene
  history, modern analogies, 7 FAQ

README indexes updated in 6 sections to reflect expanded content.
2026-05-12 23:02:22 -04:00

12 KiB
Raw Permalink Blame History

← Home

Intuition — GUI Subsystem Overview

Intuition is the AmigaOS windowing system and user interface manager. It sits between applications and the low-level graphics/input hardware, providing screens, windows, gadgets, menus, and an event-driven message passing system. Unlike modern desktop GUIs, Intuition operates with zero memory protection and cooperative multitasking — every application directly shares hardware resources.

Section Index

File Description
intuition_base.md IntuitionBase — library versioning, global state fields, ViewLord, LockIBase, function overview
screens.md Screens — Copper mechanics, display modes (OCS/ECS/AGA/RTG), dragging, resolution tables, screen type decision guide, 5 antipatterns, screen flipping/borderless/PAL-NTSC cookbooks, modern analogies, 7 FAQ
windows.md Windows — WA_ tags, refresh modes, window types, coordinate system, lifecycle, 5 antipatterns, decision guide, 3 cookbooks, modern analogies, 7 FAQ
gadgets.md Gadgets — GadTools creation, raw struct Gadget, prop/string gadgets, runtime updates, 5 antipatterns, GadTools→BOOPSI migration guide, form cookbook, historical timeline, 6 FAQ
menus.md Menus — GadTools NewMenu, event handling, multi-select, checkmarks, keyboard shortcuts, render chain diagram, 5 antipatterns, lifecycle cookbook, 6 FAQ
requesters.md Requesters — EasyRequest, ASL file/font/screenmode dialogs, non-blocking pattern
idcmp.md IDCMP — event architecture, class reference, shared ports, antipatterns, use-case cookbook
boopsi.md BOOPSI — OOP dispatcher model, ICA interconnection, custom class tutorial, class hierarchy
input_events.md Input Events — handler chain, QoS/priority, Commodities, latency analysis, game input
commodities.md Commodities Exchange — background input filtering, hotkeys, CxObjects, Exchange control
frameworks/ GUI Frameworks: MUI, ReAction, BGUI

System Architecture — Where Intuition Fits

graph TB
    subgraph "User Applications"
        APP1["Application 1"]
        APP2["Application 2"]
        WB["Workbench"]
    end

    subgraph "GUI Layer"
        INT["intuition.library<br/>Screens, Windows, IDCMP"]
        GT["gadtools.library<br/>Standard Gadgets"]
        ASL["asl.library<br/>File/Font Requesters"]
        BOOPSI["BOOPSI Framework<br/>OOP Gadgets"]
    end

    subgraph "Graphics Layer"
        GFX["graphics.library<br/>RastPort, BitMap, Draw"]
        LAY["layers.library<br/>Clipping, Damage Repair"]
        COP["Copper<br/>Display List DMA"]
        BLT["Blitter<br/>Area Fill, Scroll"]
    end

    subgraph "Input Layer"
        INP["input.device<br/>Raw Input Stream"]
        KBD["keyboard.device"]
        GP["gameport.device<br/>Mouse / Joystick"]
        CON["console.device<br/>Text I/O"]
    end

    subgraph "Hardware"
        CUSTOM["Custom Chips<br/>Denise/Lisa · Paula"]
        CIA_["CIA-A / CIA-B<br/>Keyboard, Timers"]
    end

    APP1 & APP2 & WB --> INT
    INT --> GT & ASL & BOOPSI
    INT --> GFX
    GFX --> LAY
    GFX --> COP & BLT
    INT --> INP
    INP --> KBD & GP
    INP --> CON
    KBD --> CIA_
    GP & COP & BLT --> CUSTOM

Data Flow — From Keypress to Application

sequenceDiagram
    participant HW as CIA-A / Keyboard
    participant KBD as keyboard.device
    participant INP as input.device
    participant INT as Intuition
    participant WIN as Active Window
    participant APP as Application

    HW->>KBD: IRQ (key scancode)
    KBD->>INP: InputEvent (IECLASS_RAWKEY)
    INP->>INT: Input handler chain
    Note over INT: Intuition checks:<br/>Menu shortcut?<br/>System key?<br/>Gadget activation?
    INT->>WIN: Route to active window
    WIN->>APP: IDCMP IntuiMessage<br/>(via MsgPort)
    APP->>APP: ReplyMsg() when done

Screen / Window / Gadget Hierarchy

graph TB
    subgraph "Display Hardware"
        VP["ViewPort<br/>(Copper-driven display)"]
    end

    subgraph "Screen Layer"
        SCR["Screen<br/>sc_ViewPort, sc_RastPort<br/>sc_BitMap, sc_Flags"]
    end

    subgraph "Window Layer"
        W1["Window A<br/>IDCMP flags, RastPort"]
        W2["Window B<br/>IDCMP flags, RastPort"]
    end

    subgraph "Gadget Layer"
        G1["System Gadgets<br/>Close, Depth, Size, Drag"]
        G2["GadTools Gadgets<br/>Button, Slider, ListView"]
        G3["BOOPSI Objects<br/>Custom gadgets via OOP"]
    end

    subgraph "Menu Layer"
        M1["MenuStrip<br/>Menu → MenuItem → SubItem"]
    end

    VP --> SCR
    SCR --> W1 & W2
    W1 --> G1 & G2 & G3
    W1 --> M1
    W2 --> G1

Ownership Rules

Object Owned By Lifetime
Screen Creator task (or Workbench) Until CloseScreen() — all windows must close first
Window Creator task Until CloseWindow() — must drain IDCMP port first
Gadget Window Attached via AddGList(), removed before window close
Menu Window Attached via SetMenuStrip(), cleared via ClearMenuStrip()
RastPort Window/Screen Borrowed reference — never free directly

IDCMP — The Event System

Intuition Direct Communication Message Port is the core event mechanism. Each window has a UserPort (MsgPort) that receives IntuiMessage structs:

graph LR
    subgraph "Input Sources"
        MOUSE["Mouse Move/Click"]
        KEY["Keyboard"]
        TIMER["Timer Tick"]
        RESIZE["Window Resize"]
    end

    subgraph "Intuition Dispatch"
        INT["Intuition<br/>Event Router"]
    end

    subgraph "Window IDCMP Port"
        PORT["Window.UserPort<br/>(MsgPort)"]
        MSG1["IntuiMessage<br/>Class: MOUSEBUTTONS"]
        MSG2["IntuiMessage<br/>Class: VANILLAKEY"]
        MSG3["IntuiMessage<br/>Class: NEWSIZE"]
    end

    subgraph "Application"
        WAIT["Wait(sigmask)"]
        LOOP["GetMsg() loop"]
        REPLY["ReplyMsg()"]
    end

    MOUSE & KEY & TIMER & RESIZE --> INT
    INT --> PORT
    PORT --> MSG1 & MSG2 & MSG3
    WAIT --> LOOP
    LOOP --> REPLY

Critical IDCMP Classes

Class Hex Meaning
CLOSEWINDOW $0200 User clicked close gadget
MOUSEBUTTONS $0008 Mouse button press/release
MOUSEMOVE $0010 Mouse moved (requires REPORTMOUSE)
GADGETUP $0040 Gadget released (RELVERIFY)
GADGETDOWN $0020 Gadget pressed
MENUPICK $0100 Menu item selected
VANILLAKEY $00200000 Cooked keystroke (ASCII)
RAWKEY $0400 Raw keyboard scancode
NEWSIZE $0002 Window resized
REFRESHWINDOW $0004 Damage — app must redraw
INTUITICKS $00400000 ~10Hz timer for UI updates

Library Interactions — Who Calls Whom

graph LR
    subgraph "Application Code"
        APP["Your Program"]
    end

    subgraph "intuition.library"
        OS["OpenScreen()"]
        OW["OpenWindow()"]
        GT_["GadTools Layout"]
        SM["SetMenuStrip()"]
        IDCMP["IDCMP Dispatch"]
    end

    subgraph "graphics.library"
        RP["RastPort Operations<br/>Move, Draw, Text, RectFill"]
        BM["BitMap Allocation"]
        VIEW["MakeVPort / LoadView"]
    end

    subgraph "layers.library"
        LY["Layer Clipping<br/>CreateUpfrontLayer"]
        DMG["Damage List<br/>BeginRefresh / EndRefresh"]
    end

    subgraph "exec.library"
        MP["MsgPort<br/>CreateMsgPort"]
        SIG["Signals<br/>AllocSignal, Wait"]
        MEM["Memory<br/>AllocMem, FreeMem"]
    end

    APP --> OS & OW & GT_ & SM
    APP --> RP
    APP --> MP & SIG

    OW --> LY
    OS --> VIEW & BM
    IDCMP --> MP & SIG
    RP --> LY
    LY --> DMG
    VIEW --> |"Copper list"| COP["Copper DMA"]

Screen Types and Display Pipeline

graph TB
    subgraph "Screens (front to back)"
        S1["Screen 1: Custom (640×256 4-color)<br/>sc_ViewPort → Copper List 1"]
        S2["Screen 2: Workbench (640×256 8-color)<br/>sc_ViewPort → Copper List 2"]
        S3["Screen 3: Game (320×256 32-color)<br/>sc_ViewPort → Copper List 3"]
    end

    subgraph "Copper"
        COP["Copper DMA<br/>Interleaves ViewPorts<br/>Sets palette per screen"]
    end

    subgraph "Denise/Lisa"
        OUT["Video Output<br/>Composited scanlines"]
    end

    S1 & S2 & S3 --> COP
    COP --> OUT

The Copper hardware makes Amiga's multi-screen system possible — each screen gets its own palette, resolution, and scroll position, all managed by a single Copper list that switches parameters mid-frame at the correct scanline.


GadTools vs BOOPSI — Gadget Frameworks

Aspect GadTools (OS 2.0+) BOOPSI (OS 2.0+)
Philosophy Wrapper functions around Intuition gadgets True OOP with classes, methods, inheritance
Creation CreateGadget(kind, prev, newgad, tags) NewObject(class, NULL, tags)
Layout Manual X/Y positioning with font scaling Manual or custom layout classes
Event model IDCMP GADGETUP + GT_GetIMsg() OM_NOTIFY → target chain
Extensibility Fixed set: BUTTON, STRING, SLIDER, etc. Unlimited custom classes
Typical use Preferences panels, simple tools MUI internals, complex UIs
Complexity Low — 5 functions to learn High — requires understanding class dispatch

Refresh Modes — How Windows Repaint

Mode Flag Description Trade-off
Simple Refresh WFLG_SIMPLE_REFRESH App must redraw on REFRESHWINDOW IDCMP Minimum memory, maximum app work
Smart Refresh WFLG_SMART_REFRESH Layers saves/restores obscured regions Uses RAM for damage bitmaps, less app work
Super Bitmap WFLG_SUPER_BITMAP Full off-screen bitmap, auto-restored Highest RAM use, zero redraw work
Backdrop WFLG_BACKDROP Window behind all others, fills screen Used by Workbench
graph LR
    subgraph "Simple Refresh"
        A1["Window obscured"] --> A2["REFRESHWINDOW IDCMP"]
        A2 --> A3["App: BeginRefresh()"]
        A3 --> A4["App: Redraw damaged areas"]
        A4 --> A5["App: EndRefresh()"]
    end

Common Patterns

Minimal Window Event Loop

struct Window *win = OpenWindowTags(NULL,
    WA_Title,  "My Window",
    WA_Width,  320, WA_Height, 200,
    WA_IDCMP,  IDCMP_CLOSEWINDOW | IDCMP_VANILLAKEY,
    WA_Flags,  WFLG_CLOSEGADGET | WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_ACTIVATE,
    TAG_DONE);

BOOL running = TRUE;
while (running) {
    Wait(1L << win->UserPort->mp_SigBit);
    struct IntuiMessage *msg;
    while ((msg = GT_GetIMsg(win->UserPort))) {
        switch (msg->Class) {
            case IDCMP_CLOSEWINDOW:
                running = FALSE;
                break;
            case IDCMP_VANILLAKEY:
                /* msg->Code = ASCII key */
                break;
        }
        GT_ReplyIMsg(msg);
    }
}
CloseWindow(win);

Shared IDCMP Port (Multiple Windows)

/* Create one port, share across windows */
struct MsgPort *sharedPort = CreateMsgPort();

win1 = OpenWindowTags(NULL, ..., WA_IDCMP, 0, TAG_DONE);
win1->UserPort = sharedPort;
ModifyIDCMP(win1, IDCMP_CLOSEWINDOW);

win2 = OpenWindowTags(NULL, ..., WA_IDCMP, 0, TAG_DONE);
win2->UserPort = sharedPort;
ModifyIDCMP(win2, IDCMP_CLOSEWINDOW);

/* Single Wait() handles both windows */
/* Check msg->IDCMPWindow to identify source */

References

  • RKRM: Libraries Manual — Intuition chapter
  • RKRM: Libraries Manual — GadTools chapter
  • RKRM: Libraries Manual — BOOPSI chapter
  • NDK39: intuition/intuition.h, intuition/screens.h, intuition/gadgetclass.h
  • ADCD 2.1: Intuition Autodocs — OpenWindow, OpenScreen, ModifyIDCMP