[← Home](../README.md) · [Devices](README.md) # console.device — Text Terminal I/O ## Overview `console.device` provides an ANSI-compatible text terminal within Intuition windows. It handles: - **Input**: translating raw keycodes from `input.device` into ASCII/ANSI characters - **Output**: rendering text, parsing escape sequences for cursor control, color, and formatting - **Clipboard**: cut/copy/paste integration Every CLI/Shell window is backed by a console.device unit. Applications can open their own console units in any Intuition window for text I/O without implementing their own keyboard translation or cursor rendering. ```mermaid flowchart LR KB["Keyboard
(raw keycodes)"] --> INPUT["input.device"] INPUT --> CON["console.device"] CON -->|"Read: ASCII chars"| APP["Application"] APP -->|"Write: text + ESC sequences"| CON CON -->|"Renders text via
RastPort drawing"| WIN["Intuition Window"] style CON fill:#e8f4fd,stroke:#2196f3,color:#333 style WIN fill:#c8e6c9,stroke:#2e7d32,color:#333 ``` --- ## Opening ```c struct MsgPort *conPort = CreateMsgPort(); struct IOStdReq *con = (struct IOStdReq *) CreateIORequest(conPort, sizeof(struct IOStdReq)); /* Attach to an Intuition window: */ con->io_Data = (APTR)window; con->io_Length = sizeof(struct Window); if (OpenDevice("console.device", CONU_STANDARD, (struct IORequest *)con, 0)) { /* error — can't open console */ } ``` ### Unit Types | Unit | Constant | Description | |---|---|---| | 0 | `CONU_STANDARD` | Full-feature console with cursor and scrolling | | 1 | `CONU_CHARMAP` | Character-mapped console (OS 3.0+) — faster for full-screen updates | | 3 | `CONU_SNIPMAP` | Snip-mapped: supports clipboard cut/paste (OS 3.0+) | | -1 | `CONU_LIBRARY` | Library mode — no window, just keymap translation | --- ## Writing Text and Escape Sequences ```c /* Write text to the console window: */ void ConPuts(struct IOStdReq *con, char *str) { con->io_Command = CMD_WRITE; con->io_Data = (APTR)str; con->io_Length = -1; /* -1 = null-terminated */ DoIO((struct IORequest *)con); } /* Usage: */ ConPuts(con, "Hello, Amiga!\n"); ConPuts(con, "\033[1mBold text\033[0m\n"); /* bold on/off */ ConPuts(con, "\033[33mYellow text\033[0m\n"); /* color */ ConPuts(con, "\033[10;20HText at row 10 col 20"); /* absolute position */ ``` --- ## Reading Input ```c /* Read characters (blocking): */ char buffer[256]; con->io_Command = CMD_READ; con->io_Data = (APTR)buffer; con->io_Length = sizeof(buffer); DoIO((struct IORequest *)con); /* con->io_Actual = number of bytes read */ /* Non-blocking read via SendIO + WaitPort: */ con->io_Command = CMD_READ; con->io_Data = (APTR)buffer; con->io_Length = 1; /* read 1 char at a time */ SendIO((struct IORequest *)con); /* Wait for input alongside other events: */ ULONG consoleSig = 1 << conPort->mp_SigBit; ULONG windowSig = 1 << window->UserPort->mp_SigBit; ULONG sigs = Wait(consoleSig | windowSig); if (sigs & consoleSig) { WaitIO((struct IORequest *)con); char ch = buffer[0]; /* process character... */ } ``` --- ## ANSI Escape Sequences Console.device supports a rich subset of ANSI/VT100 escape sequences (CSI = `\033[` = ESC + `[`): ### Cursor Movement | Sequence | Description | Example | |---|---|---| | `\033[nA` | Cursor up n lines | `\033[5A` = up 5 | | `\033[nB` | Cursor down n lines | | | `\033[nC` | Cursor right n columns | | | `\033[nD` | Cursor left n columns | | | `\033[y;xH` | Move to row y, column x (1-based) | `\033[1;1H` = home | | `\033[H` | Home cursor (top-left) | | | `\033[6n` | Report cursor position → replies `\033[y;xR` | | | `\033[s` | Save cursor position | | | `\033[u` | Restore cursor position | | ### Erasing | Sequence | Description | |---|---| | `\033[J` | Clear from cursor to end of screen | | `\033[1J` | Clear from start of screen to cursor | | `\033[2J` | Clear entire screen | | `\033[K` | Clear from cursor to end of line | | `\033[1K` | Clear from start of line to cursor | | `\033[2K` | Clear entire line | ### Text Attributes (SGR) | Sequence | Effect | |---|---| | `\033[0m` | Reset all attributes | | `\033[1m` | **Bold** (high intensity) | | `\033[3m` | *Italic* | | `\033[4m` | Underline | | `\033[7m` | Inverse video (swap fg/bg) | | `\033[22m` | Normal intensity (cancel bold) | | `\033[23m` | Cancel italic | | `\033[24m` | Cancel underline | ### Colors | Sequence | Foreground | Background | |---|---|---| | `\033[30m` / `\033[40m` | Black | Black | | `\033[31m` / `\033[41m` | Red | Red | | `\033[32m` / `\033[42m` | Green | Green | | `\033[33m` / `\033[43m` | Yellow/Brown | Yellow/Brown | | `\033[34m` / `\033[44m` | Blue | Blue | | `\033[35m` / `\033[45m` | Magenta | Magenta | | `\033[36m` / `\033[46m` | Cyan | Cyan | | `\033[37m` / `\033[47m` | White | White | | `\033[39m` / `\033[49m` | Default | Default | > [!NOTE] > Color indices map to the **Intuition pen palette** of the window's screen, not absolute colors. Pen 0 = background, pen 1 = foreground by default. ### Amiga-Specific Extensions | Sequence | Description | |---|---| | `\033[>1h` | Enable auto-scroll | | `\033[>1l` | Disable auto-scroll | | `\033[ p` | Enable cursor | | `\033[0 p` | Disable cursor | | `\033[t` / `\033[b` | Set top/bottom scroll margins | | `\033[20h` | Linefeed mode (LF = CR+LF) | --- ## Raw Key Events In addition to ASCII, console.device reports **special keys** as multi-byte escape sequences: | Key | Sequence Received | |---|---| | Cursor Up | `\033[A` | | Cursor Down | `\033[B` | | Cursor Right | `\033[C` | | Cursor Left | `\033[D` | | Shift+Up | `\033[T` | | Shift+Down | `\033[S` | | F1–F10 | `\033[0~` – `\033[9~` | | Shift+F1–F10 | `\033[10~` – `\033[19~` | | Help | `\033[?~` | --- ## Proper Shutdown ```c /* Must abort any pending read before closing: */ if (!CheckIO((struct IORequest *)con)) { AbortIO((struct IORequest *)con); WaitIO((struct IORequest *)con); } CloseDevice((struct IORequest *)con); DeleteIORequest((struct IORequest *)con); DeleteMsgPort(conPort); ``` --- ## CON: and RAW: Handlers The AmigaDOS file handlers `CON:` and `RAW:` are wrappers around console.device: | Handler | Description | |---|---| | `CON:` | Line-buffered console — input is buffered until Enter is pressed. Supports line editing. | | `RAW:` | Raw console — each keypress is delivered immediately. No line editing. | ```c /* Open a CON: window from DOS: */ BPTR fh = Open("CON:0/0/640/200/My Window/CLOSE", MODE_OLDFILE); FPuts(fh, "Type something: "); char buf[80]; FGets(fh, buf, sizeof(buf)); Close(fh); /* RAW: for unbuffered key-by-key input: */ BPTR raw = Open("RAW:0/0/640/200/Raw Input", MODE_OLDFILE); /* Each Read returns immediately with 1 char */ ``` --- ## References - NDK39: `devices/conunit.h`, `devices/console.h` - ADCD 2.1: console.device autodocs - See also: [keyboard.md](keyboard.md) — raw keycode to console.device pipeline - See also: [input.md](input.md) — input handler chain