mirror of
https://github.com/alfishe/amiga-bootcamp.git
synced 2026-06-12 16:16:28 +00:00
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.
194 lines
5.3 KiB
Markdown
194 lines
5.3 KiB
Markdown
[← Home](../README.md) · [Libraries](README.md)
|
|
|
|
# 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).
|
|
|
|
```mermaid
|
|
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:
|
|
|
|
```c
|
|
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
|
|
|
|
```c
|
|
/* 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:
|
|
|
|
```c
|
|
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:
|
|
|
|
```c
|
|
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:
|
|
|
|
```c
|
|
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.md) — icon.library for reading .info files and ToolTypes
|