Files
sibo-playground/docs/reference/06-ui.md

481 lines
24 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Psion SIBO / Workabout MX — User-Interface Programming
**The Window Server and the Console**
Reference notes drawn from the SIBO 'C' SDK *Window Server Reference* (v2.30,
March 1999) and the *PLIB Reference* (console functions). Everything below is
sourced from those two manuals; section/line references are given as
`[wserv]` and `[plib]`. Anything not backed by the manuals is explicitly
flagged as **reverse-engineered** or **uncertain**.
> **Machine-type note.** The manuals cover the HC, MC, S3, S3a and Workabout.
> The **Workabout** is reported by the window server as machine type
> `WS_TYPE_S3C` (i.e. it shares the "Series 3c" identity), and in
> compatibility mode its `version_id` is `WS_TYPE_S3C | WS_VERSION_4`
> `[wserv 7288-7291]`. The manuals do **not** name a "Workabout MX"
> variant; MX-specific behaviour (notably the barcode scan key, below) is
> **not documented** and is marked as reverse-engineered where it appears.
---
## 1. The Window Server model
The window server is a **system process** that provides shared access to the
screen and the keyboard (and a pointing device, where one exists) `[plib
1295-1296]`. Application processes talk to it as **clients** through the
**WLIB** library — a thin C shell over ROM-based code reached by software
interrupts `[plib 1338-1339]`.
### 1.1 Clients, foreground and background
- Of all the clients, exactly **one is the foreground client**; all others are
background clients. The **foreground client is the one that receives
keyboard input** `[wserv 1906-1910]`.
- On the small-screen machines (HC, S3, S3a, Workabout) the windows of
background clients are **not visible at all**; only the foreground client's
windows are shown, in front `[wserv 1918-1921]`.
- On the **MC** (large screen) windows of several clients can be visible at
once, and a client can *attach* to another `[wserv 1330-1333]`.
- The server keeps clients in a **front-to-back task order**: position 0 is the
foreground; position 1 is the frontmost background task, and so on `[wserv
1968-1971]`.
- A client can move itself or another client between foreground and background
with `wClientPosition` `[wserv 1983-1984]`.
### 1.2 The shared screen and keyboard
Drawing goes into a **hierarchical system of overlapping windows**; all drawing
is clipped to visible areas, and the server issues **redraw events** telling a
client which areas need repainting `[plib 1318-1323]`. Keyboard input is routed
to the foreground client, except for keys the server processes itself (task
switch, pause) or keys a client has **captured** with `wCaptureKey` so that it
receives them whether foreground or not `[wserv 1911-1915, 6283-6293]`.
### 1.3 Connecting
A process must connect before using the server, via `wConnect` (or a wrapper
such as `wStartup`) `[wserv 1371-1372]`.
```c
VOID wConnect(WSERV_SPEC *pwserv_spec, VOID *pnws_handle, UINT flags);
```
`[wserv 7182-7183]`
- `flags` combines: `W_CONNECT_AT_BACK` (connect as background; default is
foreground), `W_CONNECT_USER_FLAG`, `W_CONNECT_SYSTEM_MODAL`,
`W_CONNECT_PRIORITY` (enable the server's process-priority handling),
`W_CONNECT_DISABLE_LEAVES` (return negative error numbers instead of calling
`p_leave`) `[wserv 7187-7203]`.
- `pnws_handle` is the handle the server puts into events **not** directed at a
window (e.g. key events) `[wserv 7206-7207]`.
- `pwserv_spec` points to a `WSERV_SPEC` the client must keep for the life of
the connection. `wConnect` fills its `CONNECT_INFO conn` sub-struct with
useful data — screen size (`pixels`), pixel geometry, `set_is_dark`,
`version_id` (machine type + server version), and the default
`system_font_handle` `[wserv 7210-7251]`.
**Connection tests / helpers.** After connecting, the reserved static
`wClientData` is non-zero (zero if not connected) `[wserv 1882-1894]`. The
`WSERV_SPEC` address is also recorded in the reserved static `wserv_channel`,
which general-purpose code can read for screen size etc. `[wserv 7294-7303]`.
**Two startup paths (see also §5 on the console):**
- **PLIB startup module:** call `wStartup`, which connects, creates and
initialises a backed-up window covering the whole screen, and creates a
permanent graphics context on it — ready to draw `[wserv 1496-1519]`. The
created window's ID is in the global `wMainWid` `[wserv 1609]`.
- **CLIB startup module:** the startup automatically opens the console device
`con:`, which on the HC/S3/S3a/Workabout **is itself a window-server
connection** — so the process is already a client. Connecting again with
`wConnect`/`wStartup` panics the process (panic 100) `[wserv 1387-1396,
1757]`. The console channel is in the static `winHandle` `[wserv 1399-1403]`.
### 1.4 Windows (briefly)
- Create with `wCreateWindow` (returns a window ID); the window is dormant and
invisible until **initialised** with `wInitialiseWindowTree`, which activates
the window and all descendants `[wserv 3141-3167]`.
- Destroy a tree with `wCloseWindowTree`; destroying a window more than once is
**not** treated as an error `[wserv 3185-3202]`.
- Windows can be **backed-up** by bitmaps: drawing is mirrored to a backup
bitmap and the server redraws automatically, so the client largely avoids
redraw handling `[wserv 1270-1273, plib 1334-1335]`.
- Redraw/mouse events are directed at a window by the **handle** the client
supplied at `wCreateWindow` (commonly the address of a client structure)
`[wserv 1944-1946]`.
---
## 2. The event system
For each client the server maintains a **queue of events** reporting user input
and other state changes: key presses, foreground/background changes, redraw
events, and (on pointer machines) mouse events `[wserv 1926-1937]`. Key and
mouse events are time-stamped in system ticks (1 tick = 1/32 s) for e.g.
double-click detection `[wserv 1939-1941, 14331-14333]`.
### 2.1 Fetching events
```c
VOID wGetEventWait (WS_EV *event); /* block until an event */
VOID wGetEvent (WS_EV *event); /* async, no wait */
VOID wGetEventSpecial(WS_EV *event, UINT flags); /* async + event filter */
VOID wGetEventUpdate (UINT flags); /* change the filter */
```
`[wserv 14302-14432]`
- **`wGetEventWait`** returns only when an event is available; on an empty queue
it waits indefinitely `[wserv 1949-1951]`.
- **`wGetEvent`** is the asynchronous version, for clients that also service
non-server sources (serial input, timers). It sets `event->type =
E_FILE_PENDING` immediately; when an event arrives the server fills `event`
and signals the client's I/O semaphore. **Only one may be outstanding** — a
second pending `wGetEvent` panics the process `[wserv 14363-14378]`.
- **`wGetEventSpecial`** (window server **version 4** only) is `wGetEvent` plus
a `flags` filter selecting which events to deliver. Only one call to
`wGetEvent`/`wGetEventSpecial` may be outstanding at a time `[wserv
14381-14393]`. Filter flags (OR-able) `[wserv 14396-14416]`:
- `WE_KEY` — key and task-key events
- `WE_REDRAW``WM_REDRAW`
- `WE_STATUS``WM_FOREGROUND`, `WM_BACKGROUND`, `WM_ON`
- `WE_MOUSE` — mouse and rubber-band events
- `WE_OTHERS` — everything else
- `WE_NORMAL` — all of the above (`wGetEventSpecial(..., WE_NORMAL)` ==
`wGetEvent`)
- `WE_ESC` — only meaningful when `WE_KEY` is *not* set: on ESC the keyboard
buffer is discarded and a `WM_ESCAPE` event is delivered.
- **`wGetEventUpdate`** (v4) replaces the filter of an outstanding
`wGetEvent`/`wGetEventSpecial`; a no-op if none is outstanding `[wserv
14419-14432]`.
> **Async discipline.** Fully process one server event before requesting the
> next. Because the server runs at higher priority than clients, an async
> request can complete while you are handling some *other* source. Never
> destroy a window directly in response to a non-server event — instead call
> `wCancelGetEvent`, which delivers a **`WM_CANCELLED`** at the **highest
> priority** (overtaking all queued but not-yet-delivered events), and do the
> destruction when that arrives `[wserv 3227-3252]`.
### 2.2 The event structure
```c
typedef struct {
WORD type; /* positive event type, WM_xxxx */
UWORD handle; /* target window, or the wConnect handle */
UWORD time; /* low word of tick count (key/mouse) */
WS_EVENT_UNION p; /* type-dependent payload */
} WS_EV;
typedef union {
UWORD uword;
UBYTE *dpoint;
P_RECT rect; /* WM_REDRAW rectangle */
WMSG_KEY key; /* WM_KEY */
WMSG_MOUSE mouse; /* WM_MOUSE / rubber band */
WMSG_RUBBER rubber;
WMSG_CAPS caps; /* WM_KEYBOARD_STATE_CHANGE */
} WS_EVENT_UNION;
```
`[wserv 14311-14350]`
- `handle`: for window-directed events (`WM_REDRAW`, `WM_MOUSE`) it is the
handle given to `wCreateWindow`; for non-window events (`WM_KEY`,
`WM_FOREGROUND`) it is the handle given to `wConnect` `[wserv 14326-14329]`.
The key payload:
```c
typedef struct {
UWORD keycode; /* code of the key pressed */
UBYTE modifiers; /* shift/ctrl/psion/caps/num-lock */
UBYTE count; /* auto-repeat accumulation */
} WMSG_KEY;
```
`[wserv 14456-14465]`
- `modifiers` bit flags: `W_SHIFT_MODIFIER` (0x02), `W_CTRL_MODIFIER` (0x04),
`W_PSION_MODIFIER` (0x08), `W_CAPS_MODIFIER` (0x10),
`W_NUM_LOCK_MODIFIER` (0x20, MC only) `[wserv 14481-14499]`.
- `count` is 1 for a single press; it exceeds 1 only when the client cannot
keep up with auto-repeat. The manual's advice is to **ignore the repeat
count** `[wserv 14466-14476, 6263-6280]`.
- `keycode`: printable SIBO characters (code page 850-like) fall in
`0x20``0xFF` excluding `0x7F`. The **PSION** shift typically adds `0x200`
(`W_SPECIAL_KEY`). "Special" keys carry codes `< 0x20`, `0x7F`, or `> 0xFF`
`[wserv 14501-14541]`. Named special codes include `W_KEY_TAB` (0x09),
`W_KEY_DELETE_LEFT` (0x08), `W_KEY_DELETE_RIGHT` (0x7F), `W_KEY_RETURN`
(0x0D), `W_KEY_ESCAPE` (0x1B), `W_KEY_UP/DOWN/RIGHT/LEFT` (0x1000x103),
`W_KEY_PAGE_UP/DOWN` (0x104/0x105), `W_KEY_HOME/END` (0x106/0x107),
`W_KEY_TASK` (0x108), `W_KEY_MENU` (0x122), `W_KEY_HELP` (0x123),
`W_KEY_ON` (0x2002), `W_KEY_OFF` (0x2003), etc. `[wserv 14547-14852]`.
### 2.3 Event types
Common event types (`WS_EV event;` assumed) `[wserv 14441-15048]`:
| Event | Meaning | Payload |
|-------|---------|---------|
| **`WM_KEY`** | A key was pressed. The full description is in `event.p.key` (keycode, modifiers, count). Delivered to the foreground client (or a capturer). `[wserv 14449-14476, 6249-6250]` | `p.key` |
| **`WM_REDRAW`** | Sent when the client's queue is empty and one or more windows has an update region. `event.p.rect` is a rectangular block of pixels needing redraw. Lowest priority except for `WM_USER_MSG`. `[wserv 14855-14865]` | `p.rect` |
| **`WM_BACKGROUND`** | The foreground client has just gone to background. Usually nothing to do, but suspend real-time/animated activity until foreground returns. Only `type` set. `[wserv 14868-14878]` | — |
| **`WM_FOREGROUND`** | A background client has just become foreground. Only `type` set. `[wserv 14881-14887]` | — |
| **`WM_CANCELLED`** | Sent in response to `wCancelGetEvent`; delivered at highest priority. Only `type` set. `[wserv 14890-14897, 3250-3252]` | — |
| **`WM_USER_MSG`** | Sent in response to `wUserMsg`. **Lowest priority of all** — useful as an "the server has nothing more to send" marker. Only `type` set. `[wserv 14909-14916]` | — |
| **`WM_ON`** | Machine switched on (server v3.5+). Delivered to the foreground client if it called `wInformOn`; in v4, to any client (fore or back) that called `wInformOnAll(TRUE)`. Prompts a display refresh. Only `type` set. `[wserv 14919-14937]` | — |
| **`WM_COMMAND`** | Another client sent a command via `wSendCommand` (server v3.5). Prompts the receiver to call `wGetCommand` for the data (up to 127 bytes). Only `type` set. `[wserv 14940-14947, 1128-1129]` | — |
| **`WM_TASK_KEY`** | Sent to the **application-key handler** (the shell) when an application key is pressed with no process of that application present, or a PSION-shifted application key is pressed. S3/S3a/Workabout only. The app-key index (015) is in `event.p.key.keycode`. `[wserv 14963-14975]` | `p.key.keycode` |
| **`WM_ESCAPE`** | (v4) Delivered when ESC is pressed *and* the client selected events with `wGetEventSpecial` including `WE_ESC`/`WM_ESCAPE` but **excluding** key events; the keyboard buffer is discarded. `[wserv 14999-15015]` | — |
| **`WM_TASK_UPDATE`** | Sent to the shell (when foreground) whenever *any* process terminates. S3/S3a/Workabout and HC v3.5+. Only `type` set. `[wserv 14950-14960]` | — |
| **`WM_DATE_CHANGED`** | (v4) Date changed (reset, or past midnight). Sent to a foreground S3a/Workabout app not in S3 compatibility mode; background apps get it on next foreground; delivered at next power-on if off. `[wserv 14978-14993]` | — |
| **`WM_KEYBOARD_STATE_CHANGE`** | Sent only to the shell when numlock/capslock changes; new state in `event.p.caps.modifiers`. (MC generates it for the caps-lock key.) `[wserv 15065-15069, 14734-14735]` | `p.caps` |
**Mouse / pointer events** (only on machines with a pointing device, e.g. the
MC) `[wserv 15076-15187]`:
| Event | Meaning |
|-------|---------|
| **`WM_MOUSE`** | State change on the digitiser. `event.p.mouse` is a `WMSG_MOUSE { UBYTE event; UBYTE state; P_POINT pos; }`. `event.p.mouse.event` is `WM_MOUSE_MOVE` (filtered out by default), `WM_MOUSE_PRESS`, or `WM_MOUSE_RELEASE`; `state` carries `W_MOUSE_DOWN`, `W_MOUSE_OUTSIDE`, and the shift modifiers. `[wserv 15083-15129]` |
| **`WM_RUBBER_BAND_INIT`** | Special `WM_MOUSE` variant sent when a press occurs in a window flagged `W_WIN_RUBBER_BAND_CAPTURE`. `[wserv 15146-15154]` |
| **`WM_RUBBER`** | Sent on completion of a rubber-band interaction. `[wserv 15160-15166]` |
| **`WM_ACTIVE`** | Sent to a window that set `W_WIN_INACTIVE` when a `WM_MOUSE_PRESS` lands on it or a descendant (in place of the `WM_MOUSE`); the client typically re-activates the tree by clearing `W_WIN_INACTIVE`. Only `type` set. `[wserv 15169-15186]` |
Large-screen (MC) events also include `WM_DEICONISE`, `WM_ATTACHED`,
`WM_DETACHED` for the multi-task attach/iconise model `[wserv 15017-15062]`.
### 2.4 Event priority
Event delivery is **prioritised**, not strictly FIFO:
- `WM_CANCELLED` is delivered at the **highest** priority, overtaking anything
queued but not yet delivered `[wserv 3250-3252]`.
- `WM_REDRAW` is **lower** than user input and foreground/background events;
the only type lower than `WM_REDRAW` is `WM_USER_MSG` `[wserv 14865,
3126-3127]`.
- `WM_USER_MSG` has the **lowest** priority of all `[wserv 14912-14913]`.
- Between windows there is a further **two-level redraw priority**: windows are
low by default; `W_WIN_PRIORITY` (on `wCreateWindow`/`wSetWindow`) promotes a
window's redraws ahead of the rest `[wserv 3130-3131]`.
### 2.5 The barcode scan key — **reverse-engineered (Workabout MX)**
> **Not in the manuals.** The *Window Server Reference* documents no barcode /
> scanner / laser trigger key, and defines no keycode near 368. On barcode-
> equipped Workabout / Workabout MX hardware the **scan (trigger) key is
> observed to arrive as an ordinary `WM_KEY` event with keycode 368**
> (`0x170`). This is **reverse-engineered field knowledge, not documented
> behaviour** — treat the exact value and delivery path as version/hardware
> dependent and confirm on the target unit. Because it surfaces as a normal
> key event, it can be handled in the ordinary `WM_KEY` path (and, like other
> keys, potentially captured with `wCaptureKey`).
---
## 3. Drawing and text output primitives
All drawing targets a **drawable** selected by the **current graphics context
(GC)** `[wserv 5504, 5526]`.
### 3.1 Graphics contexts
- Create a **permanent** GC on a window/bitmap with `gCreateGC` /
`gCreateGC0` (the latter with default values) `[wserv 304-305, 1438]`. Select
the current GC with `gSetGC` / `gSetGC0` `[wserv 311-312, 2993]`.
- **Temporary** GCs are used during redraws (see below) and are freed
automatically by `wEndRedraw` `[wserv 3037-3050]`.
- `wStartup` conveniently makes a permanent GC on its full-screen window
`[wserv 1502-1505]`.
### 3.2 Graphics primitives
- Lines / shapes / borders / fills: `gDrawLine`, `gBorderRect`, `gBorder`,
`gBorder2Rect`/`gBorder2` (shadowed, v4), `gFillPattern`, `gInvObloid`
`[wserv 315-326, 1296, 919-957]`.
- Bitmaps: `gCopyBit` (copy a bitmap to a window) and the bitmap-file family
(`gInitBit`, `gGetBit`, `gLoadBit`, `gPeekBit`, `gSaveBit`) `[wserv 354,
829-1021]`.
- The server also draws buttons (`wDrawButton`, `wDrawButton2`), sprites
(`wCreateSprite`/`wSetSprite`) and scaled objects (`gDrawObject`) `[wserv
926-969, 1168, 1203]`.
### 3.3 Text output
Text is drawn through the current GC (font ID, style, transfer mode) `[wserv
5526-5536]`:
- `gPrintText` — draw text from a pixel position `[wserv 5508, 1439]`
- `gPrintClipText` — clipped to a given width `[wserv 5510]`
- `gPrintBoxText` — left/right/centred in a box; commonly used for
**flicker-free** redraw `[wserv 5512-5513, 2961]`
- `gXPrintText` — with embellishment `[wserv 5515]`
- `gShadowText` — shadowed (v4) `[wserv 5517]`
Font styles combine `G_STY_NORMAL`, `G_STY_BOLD`, `G_STY_UNDERLINE`,
`G_STY_INVERSE`, `G_STY_DOUBLE`, `G_STY_MONO`, `G_STY_ITALIC` `[wserv
5539-5557]`. Layout helpers: `gTextWidth`, `gTextCount`, `wGetWidthTable`
`[wserv 5492-5497]`.
### 3.4 Redraw handling
On a `WM_REDRAW`, the normal response is to **validate** the update region and
draw it `[wserv 10248-10256]`. Bracket the drawing with a `wBeginRedraw`
variant and `wEndRedraw`; `wBeginRedraw` both signals "this is a redraw" and
**validates** the given rectangle `[wserv 3005-3007]`. There are six
`wBeginRedraw*` variants covering partial vs whole window and
independent/temporary GC combinations `[wserv 3020-3050]`. Related: validate
without redrawing (`wValidateRect`, `wValidateWin`) and force redraws by
invalidating (`wInvalidateRect`, `wInvalidateWin`) `[wserv 270-274, 2901]`.
Backed-up windows largely avoid this cycle because the server repaints from the
backup bitmap `[wserv 1270-1273]`.
Minimal MC (non-backed-up) redraw loop `[wserv 1589-1608]`:
```c
wStartup();
do {
wGetEventWait(&event);
if (event.type == WM_REDRAW) {
wBeginRedrawWin(wMainWid);
gPrintText(10, 20, "Hello world!", 12);
wEndRedraw();
}
} while (event.type != WM_KEY);
```
---
## 4. Error handling (server calls)
By default a failing server function calls `p_leave` with the negative error
number; `wDisableLeaves(TRUE)` (or `W_CONNECT_DISABLE_LEAVES` at connect time)
makes it **return** the error instead `[wserv 1629-1641]`. Many drawing calls
are **blind** (queued client-side, no acknowledgement); on failure the server
discards further blind ops until a non-blind call reports the error. Force the
issue with `wCheckPoint` (flush + signal) or `wFlush` (flush only); after an
error, `wCleanUp` releases dangling resources `[wserv 1653-1703]`. Client-side
buffering means a panic can lag the offending call — insert `wFlush`/
`wCheckPoint` when hunting one down `[wserv 1791-1793]`.
---
## 5. The console layer — `CON:` and the PLIB console functions
The console is the **lightweight text-UI path**. PLIB contains only *primitive*
console functions — typed-line input (with simple backspace editing) and
mono-spaced line output — while the `con:` device driver adds row/column
positioning and mono-spaced character printing `[plib 1299-1301]`. They are
explicitly "for quick-and-dirty applications... not suitable for constructing
quality user interfaces" `[plib 8580-8581]`.
### 5.1 Relationship to the window server
Both the PLIB console functions and `con:` **ultimately call the window
server** for input and drawing — but expose only a fraction of its capability
`[plib 1310-1315]`. How `con:` is implemented differs by machine `[wserv
1319-1323]`:
- **HC / S3 / S3a / Workabout:** `con:` is implemented by **connecting
directly to the window server** — opening `con:` makes the process a window-
server client. Opening it also creates and initialises a **backed-up**
console window (no redraw handling needed) `[wserv 1319-1320, 1387-1407]`.
The console window's ID can be fetched with the `P_FINQ` I/O function
(`CONSOLE_INFO.window_handle`), letting a CLIB program create its own GC on
that window and draw with WLIB `[wserv 1410-1453]`.
- **MC:** `con:` is implemented by a **separate `SYS$CONS` display process**
that keeps a character map and redraws its own window (with title/menu bars).
Here it is `SYS$CONS`, not the application, that is the window-server client;
the application cannot use the console window, and `P_FINQ` is **not**
supported. On the MC the recommendation is the **PLIB startup module +
`wStartup`** `[wserv 1305-1322, 1539-1615]`.
The two startup modules therefore differ: the **CLIB** startup auto-opens
`con:` (backing `printf`, `gets`, `cprintf`, `cgets`) `[wserv 1387-1389]`; the
**PLIB** startup does not, and you call `wStartup` yourself `[wserv 1496-1497]`.
Auto-opening can be suppressed in CLIB by defining `p_xwind` `[wserv
1457-1490]`.
### 5.2 The PLIB console functions
Output (open `con:` automatically on first use) `[plib 8584-8595, 8700-8737]`:
```c
VOID p_putch(UINT c); /* write one character */
VOID p_puts (TEXT *str); /* write string + newline */
VOID p_printf(TEXT *fstr, ...); /* formatted line + newline */
VOID p_print (TEXT *fstr, ...); /* formatted, no trailing newline */
```
- `p_printf` uses an internal buffer of `P_MAXSYSIO` (258) bytes; output is
limited to `P_MAXSYSIO - 2` (256) bytes per call. Format is that of `p_atob`
`[plib 8720-8726]`.
- `p_print` moves no line; embed `\r` (start of line) and `\n` (down a line)
yourself `[plib 8732-8737]`.
Input `[plib 8597-8599, 8740-8770]`:
```c
INT p_getch(VOID); /* wait for a key, return its code */
INT p_gets (TEXT *str); /* read a line (backspace edit) */
INT p_getl (TEXT *pmt, TEXT *str, INT len); /* prompt, then read a line */
```
- `p_getch` waits for a key and returns its character code (no echo) `[plib
8740-8743]`.
- `p_gets` reads up to `P_MAXSYSIO-1` characters, Enter-terminated, and NUL-
terminates at `str` (needs `P_MAXSYSIO` bytes there); returns the length
`[plib 8746-8756]`.
- `p_getl` writes the prompt `pmt`, then reads up to `len` characters
(Enter-terminated, needs `len+1` bytes); returns the length `[plib
8759-8770]`.
Canonical smallest program `[plib 1020-1021]`:
```c
p_printf("Hello world");
p_getch();
```
### 5.3 Console configuration statics
Set these **before the first console call** `[plib 8612-8694]`:
- `winHandle` (`GLREF_D VOID *`) holds the open console channel; open a file or
`TTY:` into it first to **redirect** `p_putch` / `p_print` / `p_printf`. Do
**not** use `p_getch` / `p_gets` / `p_getl` when redirected `[plib
8615-8628]`.
- `_DefScreenRect` (`P_RECT`, top-left `(0,0)`, bottom-right = columns × rows)
changes the console window size `[plib 8629-8665]`.
- `_DefScreenMode` (`INT`) selects the mode: `0` native (default, currently
single-pixel non-compatibility on all SIBO machines), `1` compatibility, `2`
non-compatibility with grey, `3` compatibility with grey. Irrelevant values
are ignored `[plib 8668-8694]`.
---
## 6. Higher UI libraries (pointer only)
For full applications — menus, dialogs, forms — SIBO provides **higher-level UI
libraries layered on the window server** (commonly referred to as **HWIM**,
**FORM** and **OLIB**). **These are separate libraries and are not documented
in the *Window Server Reference* or *PLIB Reference*** covered here; the two
manuals mention menus and dialog boxes only as *windows the server draws/clips*
(e.g. `[wserv 2395, 10646-10647]`), not as an API. Use those libraries' own
references for real application UIs; the material above is the **foundation**
they sit on. *(Library names are noted as a pointer only and are not sourced
from these two manuals.)*
---
### Source key
- `[wserv N]` — *Window Server Reference* v2.30, line N of the supplied text.
- `[plib N]` — *PLIB Reference* (console functions), line N of the supplied
text.
- Items marked **reverse-engineered** / **uncertain** are **not** in either
manual (notably the code-368 barcode scan key and the higher UI library
names).