amiga-bootcamp/11_libraries/rexxsyslib.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

4.4 KiB

← Home · Libraries

rexxsyslib.library — ARexx Scripting Interface

Overview

ARexx is the Amiga's built-in macro/scripting language (based on IBM's REXX). Any application can host an ARexx port to receive commands from scripts and other applications — this is the Amiga's primary inter-application communication mechanism for user-facing scripting.

flowchart LR
    SCRIPT["ARexx Script<br/>(text file)"] -->|"Sends command<br/>to named port"| PORT["Application<br/>ARexx Port<br/>(e.g., 'MYAPP')"]
    PORT -->|"Parses command<br/>returns result"| SCRIPT

    APP2["Other Application"] -->|"FindPort + PutMsg"| PORT

    style PORT fill:#e8f4fd,stroke:#2196f3,color:#333

Adding an ARexx Port to Your Application

#include <rexx/storage.h>
#include <rexx/rxslib.h>

struct MsgPort *arexxPort = CreateMsgPort();
arexxPort->mp_Node.ln_Name = "MYAPP";  /* public port name */
arexxPort->mp_Node.ln_Pri  = 0;
AddPort(arexxPort);  /* make it publicly findable */

/* In your main event loop, combine with IDCMP: */
ULONG arexxSig = 1 << arexxPort->mp_SigBit;
ULONG idcmpSig = 1 << window->UserPort->mp_SigBit;

ULONG sigs = Wait(arexxSig | idcmpSig);

if (sigs & arexxSig)
{
    struct RexxMsg *rmsg;
    while ((rmsg = (struct RexxMsg *)GetMsg(arexxPort)))
    {
        STRPTR cmd = ARG0(rmsg);  /* the command string */

        /* Parse and execute: */
        if (stricmp(cmd, "QUIT") == 0)
        {
            rmsg->rm_Result1 = 0;  /* RC = 0 (success) */
            rmsg->rm_Result2 = 0;
            running = FALSE;
        }
        else if (strnicmp(cmd, "OPEN ", 5) == 0)
        {
            char *filename = cmd + 5;
            LONG rc = OpenFile(filename);
            rmsg->rm_Result1 = rc ? 0 : 10;  /* 0=ok, 10=error */
            rmsg->rm_Result2 = 0;
        }
        else if (stricmp(cmd, "VERSION") == 0)
        {
            rmsg->rm_Result1 = 0;
            /* Return a string result: */
            if (rmsg->rm_Action & RXFF_RESULT)
                rmsg->rm_Result2 = (LONG)CreateArgstring("1.0", 3);
        }
        else
        {
            rmsg->rm_Result1 = 5;  /* RC_WARN — unknown command */
            rmsg->rm_Result2 = 0;
        }

        ReplyMsg((struct Message *)rmsg);
    }
}

/* Cleanup: */
RemPort(arexxPort);
/* Drain remaining messages: */
struct RexxMsg *rmsg;
while ((rmsg = (struct RexxMsg *)GetMsg(arexxPort)))
{
    rmsg->rm_Result1 = 20;  /* RC_FATAL */
    ReplyMsg((struct Message *)rmsg);
}
DeleteMsgPort(arexxPort);

Sending ARexx Commands

struct Library *RexxSysBase = OpenLibrary("rexxsyslib.library", 0);

struct MsgPort *replyPort = CreateMsgPort();
struct RexxMsg *rmsg = CreateRexxMsg(replyPort, NULL, "MYAPP");
rmsg->rm_Args[0] = (STRPTR)CreateArgstring("OPEN test.txt", 13);
rmsg->rm_Action  = RXCOMM | RXFF_RESULT;

/* Find the target application's port: */
Forbid();
struct MsgPort *target = FindPort("TARGETAPP");
if (target)
{
    PutMsg(target, &rmsg->rm_Node);
    Permit();
    WaitPort(replyPort);
    GetMsg(replyPort);

    Printf("Return code: %ld\n", rmsg->rm_Result1);
    if (rmsg->rm_Result1 == 0 && rmsg->rm_Result2)
    {
        Printf("Result: %s\n", (char *)rmsg->rm_Result2);
        DeleteArgstring((STRPTR)rmsg->rm_Result2);
    }
}
else
{
    Permit();
    Printf("Target port not found\n");
}

DeleteArgstring(rmsg->rm_Args[0]);
DeleteRexxMsg(rmsg);
DeleteMsgPort(replyPort);

ARexx Script Example

/* MyScript.rexx — control MYAPP from ARexx */
ADDRESS 'MYAPP'

OPEN 'work:data/image.iff'
IF RC > 0 THEN DO
    SAY 'Failed to open file, RC=' RC
    EXIT 10
END

VERSION
SAY 'App version:' RESULT
QUIT

Return Codes

Value Constant Meaning
0 RC_OK Success
5 RC_WARN Warning (command not understood, etc.)
10 RC_ERROR Error (command failed)
20 RC_FATAL Fatal error (port shutting down)

Common ARexx-Aware Applications

Application Port Name Example Commands
Workbench WORKBENCH OPEN, CLOSE, WINDOW
MultiView MULTIVIEW.n OPEN, PRINT, QUIT
IBrowse IBROWSE GOTOURL, RELOAD
CygnusEd rexx_ced OPEN, SAVE, MARK, CUT
TextPad TEXTPAD LOAD, SAVE, FIND

References

  • NDK39: rexx/storage.h, rexx/rxslib.h
  • ADCD 2.1: rexxsyslib.library autodocs
  • See also: process_management.md — process/task message ports