mirror of
https://github.com/alfishe/amiga-bootcamp.git
synced 2026-06-13 00:26:28 +00:00
docs(amiga): complete AmigaOS 3.1/3.2 developer reference — 172 files across 17 sections
Comprehensive technical documentation covering: - Hardware: OCS/ECS/AGA custom chip registers, Copper & Blitter deep dives - Boot sequence: cold boot through startup-sequence - Binary format: HUNK executable spec, relocation, debug info - Linking & ABI: .fd files, LVO tables, register calling conventions - Exec kernel: tasks, interrupts, memory, signals, semaphores - AmigaDOS: file I/O, FFS/OFS layout, CLI/Shell scripting - Graphics: planar bitmaps, Copper programming, HAM/EHB modes - Intuition: screens, windows, IDCMP, BOOPSI - Devices: trackdisk, SCSI, serial, timer, audio, keyboard - Libraries: utility, expansion, IFFParse, locale, ARexx - Networking: bsdsocket API, SANA-II, TCP/IP stack comparison - Toolchain: GCC, vasm/vlink, SAS/C, NDK, debugging - Reverse engineering: IDA/Ghidra setup, compiler fingerprints, case studies - CPU & MMU: 68040/060 emulation libs, PMMU, cache management - Driver development: SANA-II, Picasso96/RTG, AHI audio All files include breadcrumb navigation. No local paths or proprietary content.
This commit is contained in:
parent
f07a368bf1
commit
21751c0025
172 changed files with 19701 additions and 0 deletions
17
09_intuition/README.md
Normal file
17
09_intuition/README.md
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
[← Home](../README.md)
|
||||
|
||||
# Intuition — GUI Subsystem Overview
|
||||
|
||||
## Section Index
|
||||
|
||||
| File | Description |
|
||||
|---|---|
|
||||
| [intuition_base.md](intuition_base.md) | IntuitionBase structure and global state |
|
||||
| [screens.md](screens.md) | Screen, OpenScreen, CloseScreen, SA_ tags |
|
||||
| [windows.md](windows.md) | Window, OpenWindow, IDCMP messaging |
|
||||
| [gadgets.md](gadgets.md) | Gadget structures, GadTools, BOOPSI |
|
||||
| [menus.md](menus.md) | Menu, MenuItem, MenuStrip construction |
|
||||
| [requesters.md](requesters.md) | EasyRequest, AutoRequest, file requesters |
|
||||
| [idcmp.md](idcmp.md) | IDCMP message classes and IntuiMessage |
|
||||
| [boopsi.md](boopsi.md) | BOOPSI object-oriented gadget system |
|
||||
| [input_events.md](input_events.md) | InputEvent, input.device, commodities |
|
||||
101
09_intuition/boopsi.md
Normal file
101
09_intuition/boopsi.md
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
[← Home](../README.md) · [Intuition](README.md)
|
||||
|
||||
# BOOPSI — Basic Object-Oriented Programming System
|
||||
|
||||
## Overview
|
||||
|
||||
BOOPSI is AmigaOS's class-based object system for Intuition gadgets and images. Objects receive messages via `DoMethod()` and support inheritance and notification.
|
||||
|
||||
---
|
||||
|
||||
## Core Methods
|
||||
|
||||
| Method | Description |
|
||||
|---|---|
|
||||
| `OM_NEW` | Create new object |
|
||||
| `OM_DISPOSE` | Destroy object |
|
||||
| `OM_SET` | Set attributes |
|
||||
| `OM_GET` | Get attributes |
|
||||
| `OM_UPDATE` | Attribute changed notification |
|
||||
| `OM_NOTIFY` | Send notification to targets |
|
||||
| `GM_RENDER` | Render the gadget |
|
||||
| `GM_GOACTIVE` | Gadget activated by user |
|
||||
| `GM_HANDLEINPUT` | Process input while active |
|
||||
| `GM_GOINACTIVE` | Gadget deactivated |
|
||||
|
||||
---
|
||||
|
||||
## Built-in Classes
|
||||
|
||||
| Class | Description |
|
||||
|---|---|
|
||||
| `rootclass` | Base class for all BOOPSI objects |
|
||||
| `gadgetclass` | Base gadget class |
|
||||
| `imageclass` | Base image class |
|
||||
| `strgclass` | String entry gadget |
|
||||
| `buttongclass` | Button gadget |
|
||||
| `propgclass` | Proportional slider |
|
||||
| `groupgclass` | Group container |
|
||||
| `frbuttonclass` | Framed button |
|
||||
| `frameiclass` | Frame image |
|
||||
| `sysiclass` | System images (checkmark, etc.) |
|
||||
| `icclass` | Interconnection (maps attributes) |
|
||||
| `modelclass` | Model for MVC pattern |
|
||||
|
||||
---
|
||||
|
||||
## Creating and Using Objects
|
||||
|
||||
```c
|
||||
Object *button = NewObject(NULL, "frbuttonclass",
|
||||
GA_Left, 20,
|
||||
GA_Top, 40,
|
||||
GA_Width, 100,
|
||||
GA_Height, 20,
|
||||
GA_Text, "Click Me",
|
||||
GA_ID, 42,
|
||||
GA_RelVerify, TRUE,
|
||||
TAG_DONE);
|
||||
|
||||
AddGadget(win, (struct Gadget *)button, -1);
|
||||
RefreshGadgets((struct Gadget *)button, win, NULL);
|
||||
|
||||
/* Set attribute: */
|
||||
SetGadgetAttrs((struct Gadget *)button, win, NULL,
|
||||
GA_Disabled, TRUE,
|
||||
TAG_DONE);
|
||||
|
||||
/* Get attribute: */
|
||||
ULONG value;
|
||||
GetAttr(GA_Disabled, button, &value);
|
||||
|
||||
/* Cleanup: */
|
||||
RemoveGadget(win, (struct Gadget *)button);
|
||||
DisposeObject(button);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Writing a Custom Class
|
||||
|
||||
```c
|
||||
Class *myclass = MakeClass(NULL, "gadgetclass", NULL,
|
||||
sizeof(struct MyData), 0);
|
||||
myclass->cl_Dispatcher.h_Entry = (HOOKFUNC)myDispatcher;
|
||||
|
||||
ULONG myDispatcher(Class *cl, Object *o, Msg msg) {
|
||||
switch (msg->MethodID) {
|
||||
case OM_NEW: return myNew(cl, o, (struct opSet *)msg);
|
||||
case OM_DISPOSE: return myDispose(cl, o, msg);
|
||||
case GM_RENDER: return myRender(cl, o, (struct gpRender *)msg);
|
||||
default: return DoSuperMethodA(cl, o, msg);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- NDK39: `intuition/classusr.h`, `intuition/classes.h`
|
||||
- ADCD 2.1: `NewObject`, `DisposeObject`, `SetAttrs`, `GetAttr`, `DoMethod`
|
||||
107
09_intuition/gadgets.md
Normal file
107
09_intuition/gadgets.md
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
[← Home](../README.md) · [Intuition](README.md)
|
||||
|
||||
# Gadgets — GadTools and BOOPSI
|
||||
|
||||
## Overview
|
||||
|
||||
Intuition gadgets are the UI controls: buttons, string fields, sliders, checkboxes, listviews, etc. OS 2.0+ provides **GadTools** (high-level toolkit) and **BOOPSI** (object-oriented framework).
|
||||
|
||||
---
|
||||
|
||||
## GadTools Gadget Types
|
||||
|
||||
| Kind | Constant | Description |
|
||||
|---|---|---|
|
||||
| Button | `BUTTON_KIND` | Simple push button |
|
||||
| Checkbox | `CHECKBOX_KIND` | Toggle on/off |
|
||||
| Integer | `INTEGER_KIND` | Numeric entry field |
|
||||
| Listview | `LISTVIEW_KIND` | Scrollable list |
|
||||
| MX | `MX_KIND` | Mutually exclusive (radio buttons) |
|
||||
| Number | `NUMBER_KIND` | Read-only number display |
|
||||
| Cycle | `CYCLE_KIND` | Pop-up cycle selector |
|
||||
| Palette | `PALETTE_KIND` | Colour picker |
|
||||
| Scroller | `SCROLLER_KIND` | Scroll bar |
|
||||
| Slider | `SLIDER_KIND` | Value slider |
|
||||
| String | `STRING_KIND` | Text entry field |
|
||||
| Text | `TEXT_KIND` | Read-only text display |
|
||||
|
||||
---
|
||||
|
||||
## Creating a GadTools Layout
|
||||
|
||||
```c
|
||||
struct Screen *scr = LockPubScreen(NULL);
|
||||
APTR vi = GetVisualInfo(scr, TAG_DONE);
|
||||
struct Gadget *glist = NULL;
|
||||
struct NewGadget ng;
|
||||
struct Gadget *gad = CreateContext(&glist);
|
||||
|
||||
ng.ng_LeftEdge = 20;
|
||||
ng.ng_TopEdge = 30;
|
||||
ng.ng_Width = 100;
|
||||
ng.ng_Height = 14;
|
||||
ng.ng_GadgetText = "OK";
|
||||
ng.ng_GadgetID = 1;
|
||||
ng.ng_VisualInfo = vi;
|
||||
ng.ng_Flags = 0;
|
||||
ng.ng_TextAttr = NULL;
|
||||
|
||||
gad = CreateGadget(BUTTON_KIND, gad, &ng, TAG_DONE);
|
||||
|
||||
ng.ng_TopEdge += 20;
|
||||
ng.ng_GadgetText = "Cancel";
|
||||
ng.ng_GadgetID = 2;
|
||||
gad = CreateGadget(BUTTON_KIND, gad, &ng, TAG_DONE);
|
||||
|
||||
/* Open window with gadgets: */
|
||||
struct Window *win = OpenWindowTags(NULL,
|
||||
WA_Gadgets, glist,
|
||||
WA_IDCMP, IDCMP_GADGETUP | IDCMP_CLOSEWINDOW | BUTTONIDCMP,
|
||||
/* ... */
|
||||
TAG_DONE);
|
||||
|
||||
/* Event loop: */
|
||||
/* on IDCMP_GADGETUP: */
|
||||
/* struct Gadget *gad = (struct Gadget *)imsg->IAddress; */
|
||||
/* switch (gad->GadgetID) { case 1: ... case 2: ... } */
|
||||
|
||||
/* Cleanup: */
|
||||
CloseWindow(win);
|
||||
FreeGadgets(glist);
|
||||
FreeVisualInfo(vi);
|
||||
UnlockPubScreen(NULL, scr);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## BOOPSI (Basic Object-Oriented Programming System for Intuition)
|
||||
|
||||
BOOPSI provides class-based gadgets with message dispatch:
|
||||
|
||||
```c
|
||||
/* Create a BOOPSI string gadget: */
|
||||
Object *strObj = NewObject(NULL, "strgclass",
|
||||
GA_Left, 20,
|
||||
GA_Top, 50,
|
||||
GA_Width, 200,
|
||||
GA_Height, 14,
|
||||
GA_ID, 3,
|
||||
STRINGA_Buffer, myBuffer,
|
||||
STRINGA_MaxChars, 64,
|
||||
TAG_DONE);
|
||||
|
||||
/* Add to window: */
|
||||
AddGadget(win, (struct Gadget *)strObj, -1);
|
||||
RefreshGadgets((struct Gadget *)strObj, win, NULL);
|
||||
|
||||
/* Cleanup: */
|
||||
RemoveGadget(win, (struct Gadget *)strObj);
|
||||
DisposeObject(strObj);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- NDK39: `libraries/gadtools.h`, `intuition/classusr.h`
|
||||
- ADCD 2.1: `CreateGadget`, `CreateContext`, `GetVisualInfo`
|
||||
84
09_intuition/idcmp.md
Normal file
84
09_intuition/idcmp.md
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
[← Home](../README.md) · [Intuition](README.md)
|
||||
|
||||
# IDCMP — IntuiMessage Classes
|
||||
|
||||
## Overview
|
||||
|
||||
**IDCMP** (Intuition Direct Communication Message Ports) is the mechanism by which Intuition delivers input events to windows. Each window has a `UserPort` (MsgPort) where `IntuiMessage` structures are queued.
|
||||
|
||||
---
|
||||
|
||||
## struct IntuiMessage
|
||||
|
||||
```c
|
||||
/* intuition/intuition.h — NDK39 */
|
||||
struct IntuiMessage {
|
||||
struct Message ExecMessage;
|
||||
ULONG Class; /* IDCMP_* class */
|
||||
UWORD Code; /* class-specific code */
|
||||
UWORD Qualifier; /* key/mouse qualifiers */
|
||||
APTR IAddress; /* class-specific address (e.g. gadget) */
|
||||
WORD MouseX; /* mouse X relative to window */
|
||||
WORD MouseY; /* mouse Y relative to window */
|
||||
ULONG Seconds; /* timestamp seconds */
|
||||
ULONG Micros; /* timestamp microseconds */
|
||||
struct Window *IDCMPWindow; /* window that received this */
|
||||
struct IntuiMessage *SpecialLink;
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## IDCMP Class Constants
|
||||
|
||||
| Constant | Hex | Description |
|
||||
|---|---|---|
|
||||
| `IDCMP_SIZEVERIFY` | `$0001` | Window is about to be resized |
|
||||
| `IDCMP_NEWSIZE` | `$0002` | Window was resized |
|
||||
| `IDCMP_REFRESHWINDOW` | `$0004` | Window needs refresh |
|
||||
| `IDCMP_MOUSEBUTTONS` | `$0008` | Mouse button pressed/released |
|
||||
| `IDCMP_MOUSEMOVE` | `$0010` | Mouse moved (if REPORTMOUSE) |
|
||||
| `IDCMP_GADGETDOWN` | `$0020` | Gadget pressed |
|
||||
| `IDCMP_GADGETUP` | `$0040` | Gadget released |
|
||||
| `IDCMP_REQSET` | `$0080` | Requester activated |
|
||||
| `IDCMP_MENUPICK` | `$0100` | Menu item selected |
|
||||
| `IDCMP_CLOSEWINDOW` | `$0200` | Close gadget clicked |
|
||||
| `IDCMP_RAWKEY` | `$0400` | Raw keyboard event |
|
||||
| `IDCMP_REQVERIFY` | `$0800` | Requester about to open |
|
||||
| `IDCMP_REQCLEAR` | `$1000` | Requester closed |
|
||||
| `IDCMP_MENUVERIFY` | `$2000` | Menu about to open |
|
||||
| `IDCMP_NEWPREFS` | `$4000` | Preferences changed |
|
||||
| `IDCMP_DISKINSERTED` | `$8000` | Disk inserted |
|
||||
| `IDCMP_DISKREMOVED` | `$10000` | Disk removed |
|
||||
| `IDCMP_ACTIVEWINDOW` | `$40000` | Window activated |
|
||||
| `IDCMP_INACTIVEWINDOW` | `$80000` | Window deactivated |
|
||||
| `IDCMP_DELTAMOVE` | `$100000` | Delta mouse movement |
|
||||
| `IDCMP_VANILLAKEY` | `$200000` | Translated ASCII keypress |
|
||||
| `IDCMP_INTUITICKS` | `$400000` | ~10Hz timer tick |
|
||||
| `IDCMP_IDCMPUPDATE` | `$800000` | BOOPSI gadget update |
|
||||
| `IDCMP_CHANGEWINDOW` | `$2000000` | Window moved/resized |
|
||||
|
||||
---
|
||||
|
||||
## Qualifier Flags
|
||||
|
||||
| Constant | Hex | Description |
|
||||
|---|---|---|
|
||||
| `IEQUALIFIER_LSHIFT` | `$0001` | Left Shift |
|
||||
| `IEQUALIFIER_RSHIFT` | `$0002` | Right Shift |
|
||||
| `IEQUALIFIER_CAPSLOCK` | `$0004` | Caps Lock |
|
||||
| `IEQUALIFIER_CONTROL` | `$0008` | Control |
|
||||
| `IEQUALIFIER_LALT` | `$0010` | Left Alt |
|
||||
| `IEQUALIFIER_RALT` | `$0020` | Right Alt |
|
||||
| `IEQUALIFIER_LCOMMAND` | `$0040` | Left Amiga |
|
||||
| `IEQUALIFIER_RCOMMAND` | `$0080` | Right Amiga |
|
||||
| `IEQUALIFIER_LEFTBUTTON` | `$4000` | LMB |
|
||||
| `IEQUALIFIER_MIDBUTTON` | `$1000` | MMB |
|
||||
| `IEQUALIFIER_RBUTTON` | `$8000` | RMB (not standard) |
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- NDK39: `intuition/intuition.h`, `devices/inputevent.h`
|
||||
- ADCD 2.1: IDCMP reference
|
||||
115
09_intuition/input_events.md
Normal file
115
09_intuition/input_events.md
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
[← Home](../README.md) · [Intuition](README.md)
|
||||
|
||||
# Input Events — InputEvent, input.device, Commodities
|
||||
|
||||
## Overview
|
||||
|
||||
All user input (keyboard, mouse, joystick) flows through `input.device` as `InputEvent` structures. Commodities Exchange provides a high-level API for hotkeys and input filtering.
|
||||
|
||||
---
|
||||
|
||||
## struct InputEvent
|
||||
|
||||
```c
|
||||
/* devices/inputevent.h — NDK39 */
|
||||
struct InputEvent {
|
||||
struct InputEvent *ie_NextEvent;
|
||||
UBYTE ie_Class; /* IECLASS_* */
|
||||
UBYTE ie_SubClass;
|
||||
UWORD ie_Code; /* keycode or button code */
|
||||
UWORD ie_Qualifier; /* IEQUALIFIER_* flags */
|
||||
union {
|
||||
struct { WORD ie_x, ie_y; } ie_xy;
|
||||
APTR ie_addr;
|
||||
struct { UBYTE ie_prev1DownCode, ie_prev1DownQual;
|
||||
UBYTE ie_prev2DownCode, ie_prev2DownQual; } ie_dead;
|
||||
} ie_position;
|
||||
struct timeval ie_TimeStamp;
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Event Classes
|
||||
|
||||
| Class | Constant | Description |
|
||||
|---|---|---|
|
||||
| `IECLASS_RAWKEY` | `$01` | Raw keyboard event |
|
||||
| `IECLASS_RAWMOUSE` | `$02` | Raw mouse button/movement |
|
||||
| `IECLASS_EVENT` | `$03` | Cooked event from Intuition |
|
||||
| `IECLASS_POINTERPOS` | `$04` | Absolute pointer position |
|
||||
| `IECLASS_TIMER` | `$06` | Timer event |
|
||||
| `IECLASS_GADGETDOWN` | `$07` | Gadget pressed |
|
||||
| `IECLASS_GADGETUP` | `$08` | Gadget released |
|
||||
| `IECLASS_DISKINSERTED` | `$09` | Disk inserted |
|
||||
| `IECLASS_DISKREMOVED` | `$0A` | Disk removed |
|
||||
| `IECLASS_NEWPREFS` | `$0C` | Preferences changed |
|
||||
|
||||
---
|
||||
|
||||
## Commodities Exchange
|
||||
|
||||
```c
|
||||
struct Library *CxBase = OpenLibrary("commodities.library", 37);
|
||||
|
||||
/* Create a hotkey filter: */
|
||||
CxObj *broker = CxBroker(&nb, NULL);
|
||||
CxObj *filter = CxFilter("ctrl alt d"); /* hotkey string */
|
||||
CxObj *sender = CxSender(port, CX_HOTKEY_ID); /* send msg to port */
|
||||
AttachCxObj(filter, sender);
|
||||
AttachCxObj(broker, filter);
|
||||
ActivateCxObj(broker, TRUE);
|
||||
|
||||
/* In event loop: */
|
||||
CxMsg *msg;
|
||||
while ((msg = (CxMsg *)GetMsg(port))) {
|
||||
ULONG type = CxMsgType(msg);
|
||||
ULONG id = CxMsgID(msg);
|
||||
ReplyMsg((struct Message *)msg);
|
||||
if (type == CXM_COMMAND && id == CXCMD_KILL) running = FALSE;
|
||||
if (type == CXM_IEVENT && id == CX_HOTKEY_ID) /* hotkey pressed */;
|
||||
}
|
||||
|
||||
DeleteCxObjAll(broker);
|
||||
CloseLibrary(CxBase);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Input Handler Installation
|
||||
|
||||
```c
|
||||
/* Add a custom input handler (runs in input.device context): */
|
||||
struct Interrupt handler;
|
||||
handler.is_Code = (APTR)myInputHandler;
|
||||
handler.is_Data = myData;
|
||||
handler.is_Node.ln_Pri = 51; /* priority (above Intuition=50) */
|
||||
handler.is_Node.ln_Name = "MyHandler";
|
||||
|
||||
struct IOStdReq *inputReq;
|
||||
/* ... open input.device ... */
|
||||
inputReq->io_Command = IND_ADDHANDLER;
|
||||
inputReq->io_Data = &handler;
|
||||
DoIO((struct IORequest *)inputReq);
|
||||
|
||||
/* Handler function: */
|
||||
struct InputEvent * __saveds myInputHandler(
|
||||
struct InputEvent *events __asm("a0"),
|
||||
APTR data __asm("a1"))
|
||||
{
|
||||
struct InputEvent *ev;
|
||||
for (ev = events; ev; ev = ev->ie_NextEvent) {
|
||||
if (ev->ie_Class == IECLASS_RAWKEY && ev->ie_Code == 0x45) {
|
||||
ev->ie_Class = IECLASS_NULL; /* swallow ESC key */
|
||||
}
|
||||
}
|
||||
return events;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- NDK39: `devices/inputevent.h`, `libraries/commodities.h`
|
||||
- ADCD 2.1: `CxBroker`, `CxFilter`, `CxSender`, input.device
|
||||
38
09_intuition/intuition_base.md
Normal file
38
09_intuition/intuition_base.md
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
[← Home](../README.md) · [Intuition](README.md)
|
||||
|
||||
# IntuitionBase — Global GUI State
|
||||
|
||||
## Overview
|
||||
|
||||
`intuition.library` manages screens, windows, menus, gadgets, and the input event pipeline. `IntuitionBase` is the library base containing active display state.
|
||||
|
||||
---
|
||||
|
||||
## struct IntuitionBase (Key Fields)
|
||||
|
||||
```c
|
||||
/* intuition/intuitionbase.h — NDK39 */
|
||||
struct IntuitionBase {
|
||||
struct Library LibNode;
|
||||
struct View ViewLord; /* master View */
|
||||
struct Window *ActiveWindow; /* currently active window */
|
||||
struct Screen *ActiveScreen; /* currently active screen */
|
||||
struct Screen *FirstScreen; /* head of screen list */
|
||||
/* ... private fields ... */
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Opening
|
||||
|
||||
```c
|
||||
struct IntuitionBase *IntuitionBase;
|
||||
IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 39);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- NDK39: `intuition/intuitionbase.h`
|
||||
64
09_intuition/menus.md
Normal file
64
09_intuition/menus.md
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
[← Home](../README.md) · [Intuition](README.md)
|
||||
|
||||
# Menus — MenuStrip Construction
|
||||
|
||||
## Overview
|
||||
|
||||
Intuition menus are structured as: `Menu` → `MenuItem` → `SubItem`. Menus are attached to windows and appear when the user presses the right mouse button.
|
||||
|
||||
---
|
||||
|
||||
## GadTools Menu Creation (OS 2.0+)
|
||||
|
||||
```c
|
||||
struct NewMenu nm[] = {
|
||||
{ NM_TITLE, "Project", NULL, 0, 0, NULL },
|
||||
{ NM_ITEM, "New", "N", 0, 0, NULL },
|
||||
{ NM_ITEM, "Open...", "O", 0, 0, NULL },
|
||||
{ NM_ITEM, NM_BARLABEL, NULL, 0, 0, NULL }, /* separator */
|
||||
{ NM_ITEM, "Quit", "Q", 0, 0, NULL },
|
||||
{ NM_TITLE, "Edit", NULL, 0, 0, NULL },
|
||||
{ NM_ITEM, "Cut", "X", 0, 0, NULL },
|
||||
{ NM_ITEM, "Copy", "C", 0, 0, NULL },
|
||||
{ NM_ITEM, "Paste", "V", 0, 0, NULL },
|
||||
{ NM_END, NULL, NULL, 0, 0, NULL }
|
||||
};
|
||||
|
||||
struct Menu *menu = CreateMenus(nm, TAG_DONE);
|
||||
LayoutMenus(menu, vi, TAG_DONE);
|
||||
SetMenuStrip(win, menu);
|
||||
|
||||
/* In event loop on IDCMP_MENUPICK: */
|
||||
UWORD code = imsg->Code;
|
||||
while (code != MENUNULL) {
|
||||
struct MenuItem *item = ItemAddress(menu, code);
|
||||
UWORD menuNum = MENUNUM(code);
|
||||
UWORD itemNum = ITEMNUM(code);
|
||||
UWORD subNum = SUBNUM(code);
|
||||
/* process selection */
|
||||
code = item->NextSelect;
|
||||
}
|
||||
|
||||
/* Cleanup: */
|
||||
ClearMenuStrip(win);
|
||||
FreeMenus(menu);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Menu Selection Macros
|
||||
|
||||
```c
|
||||
#define MENUNUM(code) ((code) & 0x1F) /* menu number (0–31) */
|
||||
#define ITEMNUM(code) (((code) >> 5) & 0x3F) /* item number (0–63) */
|
||||
#define SUBNUM(code) (((code) >> 11) & 0x1F) /* subitem number */
|
||||
#define FULLMENUNUM(m,i,s) ((m)|((i)<<5)|((s)<<11))
|
||||
#define MENUNULL 0xFFFF /* no selection */
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- NDK39: `libraries/gadtools.h`, `intuition/intuition.h`
|
||||
- ADCD 2.1: `CreateMenus`, `LayoutMenus`, `SetMenuStrip`
|
||||
70
09_intuition/requesters.md
Normal file
70
09_intuition/requesters.md
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
[← Home](../README.md) · [Intuition](README.md)
|
||||
|
||||
# Requesters — EasyRequest, AutoRequest, ASL File Requester
|
||||
|
||||
## Overview
|
||||
|
||||
Requesters are modal dialog boxes. Intuition provides `EasyRequest` for simple dialogs; `asl.library` provides file/font/screen-mode requesters.
|
||||
|
||||
---
|
||||
|
||||
## EasyRequest (OS 2.0+)
|
||||
|
||||
```c
|
||||
struct EasyStruct es = {
|
||||
sizeof(struct EasyStruct),
|
||||
0,
|
||||
"Warning", /* title */
|
||||
"Delete file '%s'?", /* body (printf format) */
|
||||
"Yes|No|Cancel" /* button labels (| separated) */
|
||||
};
|
||||
|
||||
LONG result = EasyRequest(win, &es, NULL, filename);
|
||||
/* Returns: 1=Yes, 0=Cancel, 2=No (rightmost non-zero, leftmost=0) */
|
||||
/* For Yes|No: 1=Yes, 0=No */
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ASL File Requester
|
||||
|
||||
```c
|
||||
struct Library *AslBase = OpenLibrary("asl.library", 39);
|
||||
struct FileRequester *fr = AllocAslRequestTags(ASL_FileRequest,
|
||||
ASLFR_TitleText, "Open File",
|
||||
ASLFR_InitialDrawer, "SYS:",
|
||||
ASLFR_InitialPattern, "#?.txt",
|
||||
ASLFR_DoPatterns, TRUE,
|
||||
TAG_DONE);
|
||||
|
||||
if (AslRequest(fr, NULL)) {
|
||||
Printf("Selected: %s%s\n", fr->fr_Drawer, fr->fr_File);
|
||||
}
|
||||
FreeAslRequest(fr);
|
||||
CloseLibrary(AslBase);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ASL Font Requester
|
||||
|
||||
```c
|
||||
struct FontRequester *fo = AllocAslRequestTags(ASL_FontRequest,
|
||||
ASLFO_TitleText, "Select Font",
|
||||
ASLFO_InitialName, "topaz.font",
|
||||
ASLFO_InitialSize, 8,
|
||||
ASLFO_DoStyle, TRUE,
|
||||
TAG_DONE);
|
||||
|
||||
if (AslRequest(fo, NULL)) {
|
||||
Printf("Font: %s %ld\n", fo->fo_Attr.ta_Name, fo->fo_Attr.ta_YSize);
|
||||
}
|
||||
FreeAslRequest(fo);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- NDK39: `intuition/intuition.h`, `libraries/asl.h`
|
||||
- ADCD 2.1: `EasyRequest`, `AslRequest`
|
||||
92
09_intuition/screens.md
Normal file
92
09_intuition/screens.md
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
[← Home](../README.md) · [Intuition](README.md)
|
||||
|
||||
# Screens — OpenScreen, CloseScreen, SA_ Tags
|
||||
|
||||
## Overview
|
||||
|
||||
An Amiga **Screen** is a complete display context: a `ViewPort` with its own `BitMap`, colour palette, and resolution. Multiple screens can coexist and be dragged up/down to reveal each other.
|
||||
|
||||
---
|
||||
|
||||
## Screen Types
|
||||
|
||||
| Type | Constant | Description |
|
||||
|---|---|---|
|
||||
| Workbench | `WBENCHSCREEN` | The default desktop screen |
|
||||
| Custom | `CUSTOMSCREEN` | Application-owned screen |
|
||||
| Public | `PUBLICSCREEN` | Named screen other apps can open windows on |
|
||||
|
||||
---
|
||||
|
||||
## Opening a Screen (OS 2.0+ TagList)
|
||||
|
||||
```c
|
||||
struct Screen *scr = OpenScreenTags(NULL,
|
||||
SA_Width, 640,
|
||||
SA_Height, 256,
|
||||
SA_Depth, 4, /* 16 colours */
|
||||
SA_DisplayID, HIRES_KEY,
|
||||
SA_Title, "My Screen",
|
||||
SA_ShowTitle, TRUE,
|
||||
SA_Type, CUSTOMSCREEN,
|
||||
SA_Pens, (ULONG)~0, /* use 3D pen defaults */
|
||||
SA_Font, &topaz8,
|
||||
TAG_DONE);
|
||||
```
|
||||
|
||||
### Common SA_ Tags
|
||||
|
||||
| Tag | Description |
|
||||
|---|---|
|
||||
| `SA_Width`, `SA_Height` | Screen dimensions |
|
||||
| `SA_Depth` | Bitplane count (1–8) |
|
||||
| `SA_DisplayID` | ModeID from display database |
|
||||
| `SA_Title` | Title bar text |
|
||||
| `SA_ShowTitle` | Show/hide title bar |
|
||||
| `SA_Type` | `CUSTOMSCREEN`, `PUBLICSCREEN` |
|
||||
| `SA_Behind` | Open behind other screens |
|
||||
| `SA_Quiet` | No title bar at all |
|
||||
| `SA_AutoScroll` | Allow autoscrolling |
|
||||
| `SA_Overscan` | Overscan type (`OSCAN_TEXT`, `OSCAN_STANDARD`, `OSCAN_MAX`) |
|
||||
| `SA_Pens` | DrawInfo pen array (3D look) |
|
||||
| `SA_Interleaved` | Use interleaved bitmap |
|
||||
| `SA_Colors32` | 32-bit colour palette |
|
||||
| `SA_PubName` | Public screen name |
|
||||
|
||||
---
|
||||
|
||||
## Closing
|
||||
|
||||
```c
|
||||
CloseScreen(scr);
|
||||
/* All windows must be closed first! */
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Public Screens
|
||||
|
||||
```c
|
||||
/* Open a public screen: */
|
||||
struct Screen *pub = OpenScreenTags(NULL,
|
||||
SA_Type, PUBLICSCREEN,
|
||||
SA_PubName, "MYAPP",
|
||||
SA_Title, "My Public Screen",
|
||||
TAG_DONE);
|
||||
PubScreenStatus(pub, 0); /* make it available */
|
||||
|
||||
/* From another process, open a window on it: */
|
||||
struct Screen *found = LockPubScreen("MYAPP");
|
||||
struct Window *win = OpenWindowTags(NULL,
|
||||
WA_PubScreen, found,
|
||||
WA_Title, "On MYAPP",
|
||||
TAG_DONE);
|
||||
UnlockPubScreen(NULL, found);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- NDK39: `intuition/screens.h`, `intuition/intuition.h`
|
||||
- ADCD 2.1: `OpenScreenTagList`, `CloseScreen`, `LockPubScreen`
|
||||
97
09_intuition/windows.md
Normal file
97
09_intuition/windows.md
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
[← Home](../README.md) · [Intuition](README.md)
|
||||
|
||||
# Windows — OpenWindow, IDCMP, WA_ Tags
|
||||
|
||||
## Overview
|
||||
|
||||
A **Window** is a rectangular region on a Screen where an application renders and receives input. Windows are managed by Intuition and provide title bars, borders, close/zoom/depth gadgets, sizing, and IDCMP message delivery.
|
||||
|
||||
---
|
||||
|
||||
## Opening a Window (OS 2.0+)
|
||||
|
||||
```c
|
||||
struct Window *win = OpenWindowTags(NULL,
|
||||
WA_Left, 50,
|
||||
WA_Top, 30,
|
||||
WA_Width, 400,
|
||||
WA_Height, 200,
|
||||
WA_Title, "My Window",
|
||||
WA_Flags, WFLG_CLOSEGADGET | WFLG_DRAGBAR | WFLG_DEPTHGADGET |
|
||||
WFLG_SIZEGADGET | WFLG_ACTIVATE | WFLG_GIMMEZEROZERO,
|
||||
WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_MOUSEBUTTONS | IDCMP_VANILLAKEY,
|
||||
WA_CustomScreen, myScreen,
|
||||
TAG_DONE);
|
||||
```
|
||||
|
||||
### Common WA_ Tags
|
||||
|
||||
| Tag | Description |
|
||||
|---|---|
|
||||
| `WA_Left`, `WA_Top` | Position |
|
||||
| `WA_Width`, `WA_Height` | Size |
|
||||
| `WA_MinWidth`, `WA_MaxWidth` | Size limits |
|
||||
| `WA_Title` | Window title string |
|
||||
| `WA_Flags` | `WFLG_*` flags |
|
||||
| `WA_IDCMP` | IDCMP class mask |
|
||||
| `WA_CustomScreen` | Screen to open on |
|
||||
| `WA_PubScreen` | Public screen to open on |
|
||||
| `WA_SuperBitMap` | Use super-bitmap scrolling |
|
||||
| `WA_Gadgets` | First gadget in chain |
|
||||
| `WA_Checkmark` | Custom checkmark image |
|
||||
| `WA_Borderless` | No borders |
|
||||
|
||||
---
|
||||
|
||||
## Window Flags (`WFLG_*`)
|
||||
|
||||
```c
|
||||
#define WFLG_SIZEGADGET (1<<0)
|
||||
#define WFLG_DRAGBAR (1<<1)
|
||||
#define WFLG_DEPTHGADGET (1<<2)
|
||||
#define WFLG_CLOSEGADGET (1<<3)
|
||||
#define WFLG_SIZEBRIGHT (1<<4) /* right-side sizing */
|
||||
#define WFLG_SIZEBBOTTOM (1<<5)
|
||||
#define WFLG_SMART_REFRESH (0) /* refresh type */
|
||||
#define WFLG_SIMPLE_REFRESH (1<<6)
|
||||
#define WFLG_SUPER_BITMAP (1<<7)
|
||||
#define WFLG_BACKDROP (1<<8)
|
||||
#define WFLG_REPORTMOUSE (1<<9)
|
||||
#define WFLG_GIMMEZEROZERO (1<<10) /* inner area starts at 0,0 */
|
||||
#define WFLG_BORDERLESS (1<<11)
|
||||
#define WFLG_ACTIVATE (1<<12)
|
||||
#define WFLG_RMBTRAP (1<<16) /* trap right-button clicks */
|
||||
#define WFLG_NOCAREREFRESH (1<<17)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Event Loop
|
||||
|
||||
```c
|
||||
BOOL running = TRUE;
|
||||
while (running) {
|
||||
WaitPort(win->UserPort);
|
||||
struct IntuiMessage *imsg;
|
||||
while ((imsg = (struct IntuiMessage *)GetMsg(win->UserPort))) {
|
||||
switch (imsg->Class) {
|
||||
case IDCMP_CLOSEWINDOW:
|
||||
running = FALSE;
|
||||
break;
|
||||
case IDCMP_VANILLAKEY:
|
||||
Printf("Key: %lc\n", imsg->Code);
|
||||
break;
|
||||
}
|
||||
ReplyMsg((struct Message *)imsg);
|
||||
}
|
||||
}
|
||||
CloseWindow(win);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- NDK39: `intuition/intuition.h`
|
||||
- ADCD 2.1: `OpenWindowTagList`, `CloseWindow`
|
||||
- `09_intuition/idcmp.md` — IDCMP message classes
|
||||
Loading…
Add table
Add a link
Reference in a new issue