IPC controller interface
Amiberry exposes a line-oriented Unix-domain socket when it is built with
USE_IPC_SOCKET=ON. The interface is available on Linux and macOS. It is used
by controller software such as the
Amiberry MCP server,
which presents stable, action-level MCP tools and HTTP endpoints.
Application integrations should use those MCP or HTTP interfaces. The raw commands described here are controller primitives: they expose window-logical coordinates, complete button bitmasks, runtime identities, revisions, and configuration compare-and-set operations. They are not intended as a direct public automation API.
Transport
The first instance listens on $XDG_RUNTIME_DIR/amiberry.sock, or
/tmp/amiberry.sock when XDG_RUNTIME_DIR is not set. Further instances use
amiberry_1.sock through amiberry_9.sock in the same directory.
Each request and response is one newline-terminated record. Request fields are separated by tabs:
COMMAND<TAB>ARGUMENT<TAB>ARGUMENT<NEWLINE>
A response starts with OK or ERROR; any following tab-separated fields are
command-specific. The HELP command lists all commands supported by the
running build.
Screenshot-driven GUI automation
The safe controller sequence is:
- Capture a coherent screenshot and geometry snapshot with
SCREENSHOT <path> ACTIONABLE. - Observe the current focus, input configuration, monitor, and revisions with
GET_GUI_AUTOMATION_STATE. - If required, use
SET_GUI_AUTOMATION_CONFIGas a guarded compare-and-set. - Convert the selected screenshot pixel into the window-logical coordinate
space described by the capture, then send it with
SEND_MOUSE_ABS_GUARDED. - Use
RELEASE_MOUSE_BUTTONSfor coordinate-free cleanup after any pressed button, including when geometry or revisions have changed.
Controllers must reject stale captures. Do not replay guarded input after a runtime restart, geometry change, monitor change, or input-configuration revision change. Capture a new actionable screenshot instead.
SCREENSHOT <path> ACTIONABLE
Creates a PNG and atomically returns the geometry which made that exact image actionable. Success has this fixed schema-version-1 field set:
OK
schema_version=1
path=<path>
runtime_id=<process identity>
capture_nonce=<capture identity>
geometry_revision=<unsigned revision>
monitor_id=<active input monitor>
display_mode=<mode>
renderer=<renderer>
image_width=<PNG width>
image_height=<PNG height>
source_x=<source rectangle x>
source_y=<source rectangle y>
source_width=<source rectangle width>
source_height=<source rectangle height>
viewport_x=<window-logical viewport x>
viewport_y=<window-logical viewport y>
viewport_width=<window-logical viewport width>
viewport_height=<window-logical viewport height>
window_width=<window-logical width>
window_height=<window-logical height>
The fields are tab-separated on the wire; they are shown one per line above
for readability. image_* and source_* use screenshot pixels.
viewport_* and window_* use Amiberry window-logical coordinates. A
controller maps a point from the saved image through the source rectangle and
viewport exactly once. Raw absolute IPC commands do not accept screenshot
pixels.
Without ACTIONABLE, SCREENSHOT <path> remains the legacy screenshot
operation and returns only the path. It has no runtime, revision, or geometry
guard and must not be used as a relative-coordinate fallback for automation.
Actionable capture is currently supported by the SDL and OpenGL renderers.
The Vulkan renderer rejects SCREENSHOT <path> ACTIONABLE because its
threaded presentation path cannot yet pair captured surface pixels with the
geometry of the same presented frame. Legacy SCREENSHOT <path> remains
available with Vulkan, but it does not make the image safe for coordinate
automation.
GET_GUI_AUTOMATION_STATE
Takes no arguments. A successful schema-version-1 response contains:
runtime_id,geometry_revision,monitor_id, andgeometry_validpending_tablet_modeandeffective_tablet_modepending_mouse_untrapandeffective_mouse_untrappending_effective_divergedandinput_config_revisionfocus_ready,supported_button_mask, and the currentbutton_mask
Tablet modes are off, mousehack, and real. Mouse-untrap modes are off,
middle, magic, and both. A controller must not send guarded input unless
geometry is valid, focus is ready, and the effective input settings are
compatible.
SET_GUI_AUTOMATION_CONFIG
SET_GUI_AUTOMATION_CONFIG <expected_tablet_mode> <expected_mouse_untrap> <expected_input_config_revision> <tablet_mode> <mouse_untrap>
This command compares the expected pending settings and revision with the live
state before changing the pending settings. Success returns reason=none and
the resulting pending/effective values and input_config_revision. A stale or
externally changed state returns ERROR, reason=input_config_conflict, and
the current state. reason=malformed_request reports invalid arguments.
This compare-and-set is for a controller that temporarily owns settings and later restores only the state it still owns. Public MCP and HTTP users should not invoke it directly.
SEND_MOUSE_ABS_GUARDED
SEND_MOUSE_ABS_GUARDED <x> <y> <button_mask> <runtime_id> <geometry_revision> <monitor_id> <input_config_revision>
x and y are window-logical coordinates derived from the actionable
screenshot metadata. button_mask is the complete desired button mask: bit 0 is
left, bit 1 is right, and bit 2 is middle, so valid masks are 0 through 7. It
is a state assignment, not a named click action.
Amiberry applies the coordinate and button mask together only when all guards
still match. Every response includes schema_version=1, applied, reason,
the current runtime_id, geometry_revision, monitor_id,
input_config_revision, and button_mask; success also returns x and y.
Stable rejection reasons are:
geometry_invalidruntime_mismatchgeometry_revision_mismatchmonitor_mismatchinput_config_revision_mismatchsettings_incompatiblefocus_not_readyunsupported_button_maskcoordinate_out_of_boundsinput_rejectedmalformed_request
On rejection, the guarded mutation is not applied. Controllers should use the returned state to decide whether to retry setup or recapture; they must not blindly replay the same mouse operation.
RELEASE_MOUSE_BUTTONS
Takes no arguments and releases left, right, and middle without requiring a
coordinate or a valid capture. It is unconditional and idempotent. Success
returns schema_version=1 and button_mask=0; a non-zero returned mask is an
error and cleanup remains unconfirmed.
This is the recovery primitive after a partial click or drag. Controller-level click and drag implementations may use short internal dwell intervals (the Amiberry MCP controller currently uses 50 ms between press/move/release phases), but that timing and the raw button-mask sequence are private implementation details rather than public API parameters.
Validation status
The geometry mapping and controller primitives have automated coverage in
tests/test_gfx_geometry.sh and tests/test_ipc_gui_automation.sh, including
HiDPI conversion, revision invalidation, stale-guard rejection, button masks,
and unconditional release. Live end-to-end validation with packaged Amiberry
builds on Linux and macOS is a separate release check and is not implied by
those automated tests.