amiga-bootcamp/11_libraries/workbench.md
Ilia Sharin f61c26b542 Expand documentation suite: 30+ articles enriched with diagrams, code examples, and hardware details
Graphics: text_fonts (bitmap layout, styles), sprites (DMA, multiplexing), gfx_base (chipset detection), rastport (draw modes, clipping), ham_ehb (mermaid fixes), display_modes (HAM palettes)

Devices: scsi (per-model interfaces, Gayle limits, CD-ROM, native vs vendor drivers), console (ANSI sequences, CON:/RAW:), parallel (CIA registers, pinout), timer (resource exhaustion), gameport (quadrature, XOR state)

Libraries: workbench (WBStartup, AppWindow/Icon/MenuItem), rexxsyslib (ARexx port hosting, command parsing), diskfont (font directory, colour fonts), keymap (rawkey codes, dead keys), locale (catalogue system, date formatting), layers (ClipRect, refresh types), utility (TagItem chains), icon (DiskObject, ToolTypes), iffparse (IFF structure, ByteRun1), expansion (Zorro AutoConfig)

Networking: tcp_ip_stacks (major rewrite - Amiga vs Unix architecture, SANA-II pipeline, PPP/SLIP dial-up, Ethernet cards, MiSTer), bsdsocket (pure API ref), sana2 (buffer hooks, driver requirements), protocols (all code examples). Deduplicated overlap between the three files.

Toolchain: debugging (Enforcer patterns, SnoopDOS, GDB remote, kprintf checklist), sasc (pragma encoding, __saveds idioms), stormc (NEW - StormC IDE, C++, PowerPC)

References: error_codes (DOS, Exec, trackdisk, Intuition error tables)
Driver development: rtg_driver (Native driver analysis, P96 tuning)

All 22 README indexes updated. Root README synced with stormc.md entry.
2026-04-23 21:37:26 -04:00

5.3 KiB

← Home · Libraries

workbench.library — Workbench Integration

Overview

workbench.library provides APIs for interacting with the Workbench desktop environment: receiving startup arguments, registering AppWindows (drag-and-drop targets), AppIcons (desktop icons), and AppMenuItems (Workbench Tools menu entries).

flowchart TD
    subgraph "Workbench"
        WB["Workbench Desktop"]
        WB --> AW["AppWindow<br/>(file drop target)"]
        WB --> AI["AppIcon<br/>(custom desktop icon)"]
        WB --> AM["AppMenuItem<br/>(Tools menu entry)"]
    end

    subgraph "Application"
        PORT["MsgPort"] --> LOOP["Event Loop"]
        LOOP --> HANDLE["Handle AppMessage"]
    end

    AW -->|"User drops file"| PORT
    AI -->|"User clicks icon"| PORT
    AM -->|"User selects menu"| PORT

    style AW fill:#c8e6c9,stroke:#2e7d32,color:#333
    style AI fill:#fff9c4,stroke:#f9a825,color:#333
    style AM fill:#e8f4fd,stroke:#2196f3,color:#333

WBStartup Message

When launched from Workbench (double-click an icon), the program receives a WBStartup message instead of CLI arguments:

struct WBStartup {
    struct Message sm_Message;
    struct MsgPort *sm_Process;   /* process that sent us */
    BPTR   sm_Segment;            /* our loaded segment list */
    LONG   sm_NumArgs;            /* number of arguments (1 = just the tool) */
    char  *sm_ToolWindow;         /* tool window spec (CON: string) */
    struct WBArg *sm_ArgList;     /* array of arguments */
};

struct WBArg {
    BPTR   wa_Lock;    /* directory lock (BPTR) */
    BYTE  *wa_Name;    /* filename (relative to wa_Lock) */
};

Handling WBStartup

/* In main(): */
struct WBStartup *wbmsg = NULL;

if (argc == 0)
{
    /* Launched from Workbench — get the startup message: */
    struct Process *me = (struct Process *)FindTask(NULL);
    WaitPort(&me->pr_MsgPort);
    wbmsg = (struct WBStartup *)GetMsg(&me->pr_MsgPort);

    /* ArgList[0] = the tool itself (our icon) */
    /* ArgList[1..n] = files the user shift-clicked or dropped on us */

    /* CD to the tool's directory for file access: */
    BPTR oldDir = CurrentDir(wbmsg->sm_ArgList[0].wa_Lock);

    /* Process dropped files: */
    for (int i = 1; i < wbmsg->sm_NumArgs; i++)
    {
        BPTR dir = wbmsg->sm_ArgList[i].wa_Lock;
        char *name = wbmsg->sm_ArgList[i].wa_Name;
        BPTR old = CurrentDir(dir);
        /* ... open and process file 'name' ... */
        CurrentDir(old);
    }

    /* Read our ToolTypes: */
    struct DiskObject *dobj = GetDiskObject(wbmsg->sm_ArgList[0].wa_Name);
    if (dobj)
    {
        char *pubscreen = FindToolType(dobj->do_ToolTypes, "PUBSCREEN");
        FreeDiskObject(dobj);
    }

    CurrentDir(oldDir);
}

/* ... main program logic ... */

/* MUST reply before exiting: */
if (wbmsg)
{
    Forbid();
    ReplyMsg((struct Message *)wbmsg);
}

Caution

You must reply the WBStartup message before exiting, and you must call Forbid() before ReplyMsg(). If you reply without Forbid, Workbench may unload your code segment before your process finishes exiting → crash.


AppWindow — File Drop Target

Register a window to receive files when the user drags icons to it:

struct MsgPort *appPort = CreateMsgPort();

/* Register the window: */
struct AppWindow *appWin = AddAppWindow(
    1,            /* ID (your choice — returned in AppMessage) */
    0,            /* user data */
    window,       /* the Intuition Window */
    appPort,      /* port for AppMessages */
    NULL);        /* tags (NULL = defaults) */

/* In event loop: */
struct AppMessage *amsg;
while ((amsg = (struct AppMessage *)GetMsg(appPort)))
{
    for (int i = 0; i < amsg->am_NumArgs; i++)
    {
        BPTR old = CurrentDir(amsg->am_ArgList[i].wa_Lock);
        Printf("Dropped: %s\n", amsg->am_ArgList[i].wa_Name);
        /* ... open and process file ... */
        CurrentDir(old);
    }
    ReplyMsg((struct Message *)amsg);
}

/* Cleanup: */
RemoveAppWindow(appWin);
DeleteMsgPort(appPort);

AppIcon — Desktop Icon

Place a custom icon on the Workbench desktop:

struct DiskObject *icon = GetDiskObject("PROGDIR:myapp");

struct AppIcon *appIcon = AddAppIcon(
    1,            /* ID */
    0,            /* user data */
    "My App",     /* label under the icon */
    appPort,      /* port for messages */
    NULL,         /* lock (NULL = Workbench root) */
    icon,         /* the icon imagery */
    NULL);        /* tags */

/* When user double-clicks or drops files on the AppIcon: */
/* → AppMessage received on appPort (same as AppWindow) */

RemoveAppIcon(appIcon);
FreeDiskObject(icon);

AppMenuItem — Tools Menu Entry

Add an entry to the Workbench "Tools" menu:

struct AppMenuItem *appMenu = AddAppMenuItem(
    1,            /* ID */
    0,            /* user data */
    "My Tool",    /* menu text */
    appPort,      /* port for messages */
    NULL);        /* tags */

/* When user selects the menu item: */
/* → AppMessage received, am_NumArgs=0 (no file args) */

RemoveAppMenuItem(appMenu);

References

  • NDK39: workbench/workbench.h, workbench/startup.h
  • ADCD 2.1: workbench.library autodocs
  • See also: icon.md — icon.library for reading .info files and ToolTypes