<!-- Source: https://medius.k4tech.net/bindings/c/types -->
# Types & errors

_Every C struct, enum, and status code, by table_

The `Medius*` types and `MEDIUS_*` enumerators from [`medius.h`](/bindings/c.md). The calls that produce and consume them are on [API index](/bindings/c/api.md); streams on [Streams](/bindings/c/streams.md). What each value means lives with the canonical type docs in the [Rust Library](/library.md) and [Native API](/native.md) sections.

> **Note**
>
> **How C models the enums.** Each enum has a fixed-width backing: [`MediusStatus`](/bindings/c/types.md#errors) is `int32_t`; every other enum is `uint8_t`. On [C23](https://en.cppreference.com/w/c/language/enum) and [C++](https://en.cppreference.com/w/cpp/language/enum) the tag carries that underlying type directly (`enum MediusButton : uint8_t`); on [C99](https://en.cppreference.com/w/c/language/history) the tag is [`typedef`](https://en.cppreference.com/w/c/language/typedef)'d to the integer and you pass the prefixed enumerators (`MEDIUS_BUTTON_LEFT`). Structs are plain PODs: pass by value, read fields directly. Nothing is heap-allocated, so there's nothing to free per value; only the opaque handles have a [`*_free`](/bindings/c/api.md).

## Sizing constants

_Fixed-cap arrays sized to the wire limits_

The event, lock, and log PODs embed fixed-cap arrays sized to the protocol's own limits, with a count field saying how many slots are live. `char` arrays are NUL-terminated.

| Macro | Value | Caps |
| --- | --- | --- |
| `MEDIUS_MAX_USAGES` | `256` | [`MediusUsageEvent.usages`](/bindings/c/types.md#usage-event), [`MediusClipStatus.held`](/bindings/c/types.md#clip-status) |
| `MEDIUS_MAX_LOCKS` | `256` | [`MediusLocks.entries`](/bindings/c/types.md#locks) |
| `MEDIUS_MAX_PATH` | `512` | [`MediusPortInfo.path`](/bindings/c/types.md#portinfo) |
| `MEDIUS_MAX_LOG_TEXT` | `512` | [`MediusLogLine.text`](/bindings/c/types.md#log-line) |
| `MEDIUS_MAX_PRODUCT` | `128` | [`MediusDeviceInfo.product`](/bindings/c/types.md#device-info) |
| `MEDIUS_MAX_SERIAL` | `128` | [`MediusPortInfo.serial`](/bindings/c/types.md#portinfo) |
| `MEDIUS_MAX_NAME` | `33` | [`MediusVersion.name`](/bindings/c/types.md#version) |
| `MEDIUS_CLIP_TRIG_MAX` | `8` | [`MediusClipSettings.triggers`](/bindings/c/types.md#clip-settings) |

## Enums

_uint8_t-backed selectors (MediusStatus is int32_t)_

Each value is a wire byte; the canonical meaning lives on [Enums](/library/types/enums.md). The `*Kind` enums (and [`MediusClass`](/bindings/c/types.md#input-kind)) tag which arm of a built value ([`MediusUsage`](/bindings/c/types.md#input), [`MediusMotion`](/bindings/c/types.md#motion), [`MediusCatchEvent`](/bindings/c/types.md#catch-event)) is populated.

## MediusDeviceKind

_The cloned device's primary kind_

```text
enum MediusDeviceKind : uint8_t
```

The `kind` field of a [`MediusDeviceInfo`](/bindings/c/types.md#device-info), from the cloned device's Boot-interface protocol. Also what [`medius_device_find_mouse_box`](/bindings/c/api.md#discovery) / `_find_keyboard_box` select on. See [DeviceKind](/library/types/enums.md#device-kind).

| Enumerator | Value | Meaning |
| --- | --- | --- |
| `MEDIUS_DEVICE_KIND_UNKNOWN` | `0` | Neither a Boot keyboard nor mouse. |
| `MEDIUS_DEVICE_KIND_KEYBOARD` | `1` | The device is a keyboard. |
| `MEDIUS_DEVICE_KIND_MOUSE` | `2` | The device is a mouse. |

## MediusButton

_A mouse button id_

```text
enum MediusButton : uint8_t   /* values match the firmware button id */
```

The button an [inject](/library/inject.md) call drives. Ids on [Usage IDs](/native/commands/usage.md#buttons).

| Enumerator | Value | Meaning |
| --- | --- | --- |
| `MEDIUS_BUTTON_LEFT` | `0` | Left button. |
| `MEDIUS_BUTTON_RIGHT` | `1` | Right button. |
| `MEDIUS_BUTTON_MIDDLE` | `2` | Middle button. |
| `MEDIUS_BUTTON_SIDE1` | `3` | First thumb button. |
| `MEDIUS_BUTTON_SIDE2` | `4` | Second thumb button. |

## MediusAction

_The press / release tri-state_

```text
enum MediusAction : uint8_t
```

The override action shared by [inject](/library/inject.md) calls, whether a button, key, or media usage. See the [injection model](/native/injection.md).

| Enumerator | Value | Meaning |
| --- | --- | --- |
| `MEDIUS_ACTION_SOFT_RELEASE` | `0` | Drop the [box](/native/hardware.md)'s override, press or force; a physical hold stays down. |
| `MEDIUS_ACTION_PRESS` | `1` | Force the input down. |
| `MEDIUS_ACTION_FORCE_RELEASE` | `2` | Force the input up, masking a physical hold. |

## MediusClass

_Which arm of a MediusUsage is set_

```text
enum MediusClass : uint8_t
```

The `kind` tag of a [`MediusUsage`](/bindings/c/types.md#input) you build with [`medius_usage_button/_key/_media`](/bindings/c/api.md#builders).

| Enumerator | Value | Meaning |
| --- | --- | --- |
| `MEDIUS_CLASS_BUTTON` | `0` | `id` is a mouse button id. |
| `MEDIUS_CLASS_KEY` | `1` | `id` is a HID keyboard usage. |
| `MEDIUS_CLASS_MEDIA` | `2` | `id` is a 16-bit Consumer usage. |

## MediusMotionKind

_Which arm of a MediusMotion is set_

```text
enum MediusMotionKind : uint8_t
```

Tags the [`MediusMotion`](/bindings/c/types.md#motion) you build with [`medius_motion_cursor/_wheel`](/bindings/c/api.md#builders). See [Move](/library/move.md).

| Enumerator | Value | Meaning |
| --- | --- | --- |
| `MEDIUS_MOTION_KIND_CURSOR` | `0` | `dx`/`dy` apply. |
| `MEDIUS_MOTION_KIND_WHEEL` | `1` | `wheel` applies. |

## MediusLockTargetKind

_Which input a MediusLockTarget addresses_

```text
enum MediusLockTargetKind : uint8_t
```

The `kind` of a [`MediusLockTarget`](/bindings/c/types.md#lock-target). See [Lock](/library/lock.md).

| Enumerator | Value | Meaning |
| --- | --- | --- |
| `MEDIUS_LOCK_TARGET_KIND_X` | `0` | Horizontal movement. |
| `MEDIUS_LOCK_TARGET_KIND_Y` | `1` | Vertical movement. |
| `MEDIUS_LOCK_TARGET_KIND_WHEEL` | `2` | Scroll wheel. |
| `MEDIUS_LOCK_TARGET_KIND_USAGE` | `3` | A momentary usage (the struct's `usage` field selects which). |

## MediusLockDirection

_Which edge a lock applies to_

```text
enum MediusLockDirection : uint8_t
```

For an axis or wheel it's a sign; for a usage it's an edge. See [LOCK](/native/commands/lock.md).

| Enumerator | Value | Meaning |
| --- | --- | --- |
| `MEDIUS_LOCK_DIRECTION_BOTH` | `0` | Both signs, or press and release. |
| `MEDIUS_LOCK_DIRECTION_POSITIVE` | `1` | Axis positive (`+`), or a usage press. |
| `MEDIUS_LOCK_DIRECTION_NEGATIVE` | `2` | Axis negative (`-`), or a usage release. |

## MediusEdge

_Which edge of a trigger usage fires a clip binding_

```text
enum MediusEdge : uint8_t
```

The edge of a [`MediusClipTrigger`](/bindings/c/types.md#clip-trigger)'s `on` usage that runs its action. Same wire values as [`MediusLockDirection`](/bindings/c/types.md#lock-direction). See [Clip](/library/clip.md).

| Enumerator | Value | Meaning |
| --- | --- | --- |
| `MEDIUS_EDGE_BOTH` | `0` | Both press and release. |
| `MEDIUS_EDGE_PRESS` | `1` | The press edge only. |
| `MEDIUS_EDGE_RELEASE` | `2` | The release edge only. |

## MediusClipAction

_The engine action a clip trigger drives_

```text
enum MediusClipAction : uint8_t
```

What a bound [`MediusClipTrigger`](/bindings/c/types.md#clip-trigger) does to the clip on its edge; the same verbs as the [`medius_clip_start/_stop/...`](/bindings/c/api.md#clip) calls. See [Clip](/library/clip.md).

| Enumerator | Value | Meaning |
| --- | --- | --- |
| `MEDIUS_CLIP_ACTION_START` | `0` | Rewind and play (resume from a pause). |
| `MEDIUS_CLIP_ACTION_STOP` | `1` | Stop and release held input and the auto-lock. |
| `MEDIUS_CLIP_ACTION_PAUSE` | `2` | Halt mid-clip, retaining the cursor and held input. |
| `MEDIUS_CLIP_ACTION_RESUME` | `3` | Continue from the paused cursor. |
| `MEDIUS_CLIP_ACTION_RESTART` | `4` | Force a rewind and play, even mid-playback. |
| `MEDIUS_CLIP_ACTION_TOGGLE` | `5` | Play if idle/paused, stop if playing. |

## MediusBlanket

_A whole-group lock selector_

```text
enum MediusBlanket : uint8_t
```

A whole input group: which one [`medius_device_lock_all/_unlock_all`](/bindings/c/api.md#lock) block in one call, and the scope [`medius_clip_set_autolock`](/bindings/c/api.md#clip) auto-locks while a clip plays. See [Lock](/library/lock.md).

The values are ABI-local ordinals (matching the crate's [`Blanket`](/library/types/enums.md#blanket) order), not the `CLIP_LOCK_*` wire bits.

| Enumerator | Value | Meaning |
| --- | --- | --- |
| `MEDIUS_BLANKET_AIM` | `0` | The X and Y cursor axes. |
| `MEDIUS_BLANKET_WHEEL` | `1` | The wheel. |
| `MEDIUS_BLANKET_BUTTONS` | `2` | Every mouse button. |
| `MEDIUS_BLANKET_KEYS` | `3` | Every keyboard key and modifier. |
| `MEDIUS_BLANKET_MEDIA` | `4` | Every media (Consumer) usage. |

## MediusLedTarget

_Which chip's status LED to drive_

```text
enum MediusLedTarget : uint8_t
```

See [LED](/native/commands/led.md).

| Enumerator | Value | Meaning |
| --- | --- | --- |
| `MEDIUS_LED_TARGET_DEVICE` | `0` | The device chip's own LED. |
| `MEDIUS_LED_TARGET_HOST` | `1` | The host chip's LED, relayed over the inter-chip link. |
| `MEDIUS_LED_TARGET_BOTH` | `2` | Both LEDs at once. |

## MediusLedMode

_What to drive the LED to_

```text
enum MediusLedMode : uint8_t
```

See [LED](/library/led.md). `Solid` / `Blink` use the command's `level`.

| Enumerator | Value | Meaning |
| --- | --- | --- |
| `MEDIUS_LED_MODE_AUTO` | `0` | Restore the chip's own status display. |
| `MEDIUS_LED_MODE_OFF` | `1` | LED dark. |
| `MEDIUS_LED_MODE_SOLID` | `2` | Lit steadily at `level`. |
| `MEDIUS_LED_MODE_BLINK` | `3` | Blinks at `level`. |

## MediusRebootTarget

_Which chip to restart, and how_

```text
enum MediusRebootTarget : uint8_t
```

See [Admin](/native/commands/admin.md).

| Enumerator | Value | Meaning |
| --- | --- | --- |
| `MEDIUS_REBOOT_TARGET_DEVICE_DOWNLOAD` | `0` | Device chip into ROM download mode (flash over the serial link). |
| `MEDIUS_REBOOT_TARGET_HOST_DOWNLOAD` | `1` | Host chip into ROM download mode (flash over its own USB). |
| `MEDIUS_REBOOT_TARGET_DEVICE_RUN` | `2` | Restart the device chip and run its firmware. |
| `MEDIUS_REBOOT_TARGET_HOST_RUN` | `3` | Restart the host chip and run its firmware. |

## MediusEmitMode

_What paces injected motion_

```text
enum MediusEmitMode : uint8_t
```

See [Options](/library/options.md).

| Enumerator | Value | Meaning |
| --- | --- | --- |
| `MEDIUS_EMIT_MODE_LEARNED` | `0` | Pace to the mouse's learnt native report rate (the default). |
| `MEDIUS_EMIT_MODE_INTERVAL` | `1` | Pace to the cloned mouse's declared poll rate (its bInterval). |
| `MEDIUS_EMIT_MODE_FIXED` | `2` | Pace to a fixed rate in Hz (snapped to 1000/n, capped 1 kHz). |

## MediusCatchEventKind

_Which arm of a MediusCatchEvent is set_

```text
enum MediusCatchEventKind : uint8_t
```

Tells you which member of the [`MediusCatchEvent`](/bindings/c/types.md#catch-event) union to read. See [Catch](/library/catch.md).

| Enumerator | Value | Read |
| --- | --- | --- |
| `MEDIUS_CATCH_EVENT_KIND_MOTION` | `0` | `data.motion` |
| `MEDIUS_CATCH_EVENT_KIND_USAGES` | `1` | `data.usages` |

## MediusLogLevel

_Severity tag on a log line_

```text
enum MediusLogLevel : uint8_t
```

The severity of a [`MediusLogLine`](/bindings/c/types.md#log-line). See [Logs & counters](/library/diagnostics.md).

| Enumerator | Value | Meaning |
| --- | --- | --- |
| `MEDIUS_LOG_LEVEL_ERROR` | `0` | A failure the box couldn't recover from. |
| `MEDIUS_LOG_LEVEL_WARN` | `1` | Something off that the box handled. |
| `MEDIUS_LOG_LEVEL_INFO` | `2` | Normal operational notices. |
| `MEDIUS_LOG_LEVEL_DEBUG` | `3` | Detail for diagnosing a problem. |
| `MEDIUS_LOG_LEVEL_VERBOSE` | `4` | The finest-grained trace output. |

## MediusCatchMask

_Which physical reports raise an event_

```text
typedef uint8_t MediusCatchMask;   /* OR the MEDIUS_CATCH_MASK_* bits */
```

The subscription you hand to [`medius_device_catch_events`](/bindings/c/api.md#streams). See [Catch](/library/catch.md).

| Macro | Bit | Triggers on |
| --- | --- | --- |
| `MEDIUS_CATCH_MASK_MOTION` | `0x01` | The mouse moved (dx/dy). |
| `MEDIUS_CATCH_MASK_WHEEL` | `0x02` | The wheel turned. |
| `MEDIUS_CATCH_MASK_BUTTONS` | `0x04` | A button changed. |
| `MEDIUS_CATCH_MASK_KEYS` | `0x08` | A keyboard key changed. |
| `MEDIUS_CATCH_MASK_MEDIA` | `0x10` | A media key changed. |
| `MEDIUS_CATCH_MASK_ALL` | `0x1F` | Every class. |

## MediusKey

_A HID keyboard/keypad usage_

```text
typedef uint8_t MediusKey;   /* modifiers are 0xE0 to 0xE7 */
```

A raw [HID keyboard usage](https://www.usb.org/document-library/hid-usage-tables-14) passed to the [key](/library/inject.md) calls. Pass any usage byte, or one of the `MEDIUS_KEY_*` macros. The full set of usages is on [Usage IDs](/native/commands/usage.md#keycodes).

| Macro group | Example | Usage |
| --- | --- | --- |
| Letters | `MEDIUS_KEY_A` .. `MEDIUS_KEY_Z` | `4` to `29` |
| Digits | `MEDIUS_KEY_1` .. `MEDIUS_KEY_0` | `30` to `39` |
| Function | `MEDIUS_KEY_F1` .. `MEDIUS_KEY_F12` | `58` to `69` |
| Editing / nav | `MEDIUS_KEY_ENTER`, `_ESCAPE`, `_TAB`, `_SPACE`, `_INSERT`, `_HOME`, `_DELETE`, arrows | various |
| Modifiers | `MEDIUS_KEY_LEFT_CTRL` .. `MEDIUS_KEY_RIGHT_GUI` | `224` to `231` (`0xE0` to `0xE7`) |

## MediusMediaKey

_A 16-bit HID Consumer usage_

```text
typedef uint16_t MediusMediaKey;
```

A raw Consumer usage passed to the [media](/library/inject.md) calls. Pass any 16-bit usage, or a `MEDIUS_MEDIA_*` macro. The full set is on [Usage IDs](/native/commands/usage.md#consumer).

| Macro | Usage | Macro | Usage |
| --- | --- | --- | --- |
| `MEDIUS_MEDIA_PLAY_PAUSE` | `205` | `MEDIUS_MEDIA_MUTE` | `226` |
| `MEDIUS_MEDIA_NEXT_TRACK` | `181` | `MEDIUS_MEDIA_VOLUME_UP` | `233` |
| `MEDIUS_MEDIA_PREV_TRACK` | `182` | `MEDIUS_MEDIA_VOLUME_DOWN` | `234` |
| `MEDIUS_MEDIA_STOP` | `183` | `MEDIUS_MEDIA_PLAY` | `176` |
| `MEDIUS_MEDIA_PAUSE` | `177` |  |  |

## MediusFrameType

_A wire frame TYPE byte (mock only)_

```text
enum MediusFrameType : uint8_t   /* always defined; read only by the mock recorder */
```

The TYPE byte of a wire [frame](/native/frame.md), used with the mock recorder ([`medius_mock_saw`](/bindings/c/api.md#mock) / [`medius_mock_recorded_frame`](/bindings/c/api.md#mock)). See the [mock feature](/library/features/mock.md).

| Enumerator | Value | Enumerator | Value |
| --- | --- | --- | --- |
| `MEDIUS_FRAME_TYPE_MOVE` | `1` | `MEDIUS_FRAME_TYPE_LOCK` | `10` |
| `MEDIUS_FRAME_TYPE_INJECT` | `3` | `MEDIUS_FRAME_TYPE_CATCH` | `11` |
| `MEDIUS_FRAME_TYPE_RESET` | `4` | `MEDIUS_FRAME_TYPE_MOTION_EVENT` | `12` |
| `MEDIUS_FRAME_TYPE_QUERY` | `5` | `MEDIUS_FRAME_TYPE_USAGE_EVENT` | `15` |
| `MEDIUS_FRAME_TYPE_RESP` | `6` | `MEDIUS_FRAME_TYPE_OPTION` | `17` |
| `MEDIUS_FRAME_TYPE_REBOOT_DL` | `7` | `MEDIUS_FRAME_TYPE_CLIP_APPEND` | `18` |
| `MEDIUS_FRAME_TYPE_LOG` | `8` | `MEDIUS_FRAME_TYPE_CLIP_CTRL` | `19` |
| `MEDIUS_FRAME_TYPE_LED` | `9` | `MEDIUS_FRAME_TYPE_CLIP_SET` | `20` |
|  |  | `MEDIUS_FRAME_TYPE_CLIP_TRIGGER` | `21` |

## Argument structs

_Tagged values you build, then pass in_

Three small PODs you build with a helper and hand to a call. The `medius_*_*` constructors set the `kind` tag and the right field for you.

## MediusUsage

_A momentary usage for inject_

What [`medius_device_inject`](/bindings/c/api.md#inject) drives. Build with [`medius_usage_button(...)`](/bindings/c/api.md#builders), `_key(...)`, or `_media(...)`; `id` holds the button id or usage per [`kind`](/bindings/c/types.md#input-kind). See [Inject](/library/inject.md).

| Field | C type | Meaning |
| --- | --- | --- |
| `kind` | [`MediusClass`](/bindings/c/types.md#input-kind) | Which class `id` names. |
| `id` | `uint16_t` | Button id, key usage, or media usage. |

## MediusMotion

_A relative axis for move_axis_

What [`medius_device_move_axis`](/bindings/c/api.md#move) drives. Build with [`medius_motion_cursor(dx, dy)`](/bindings/c/api.md#builders) or `medius_motion_wheel(delta)`. See [Move](/library/move.md).

| Field | C type | Meaning |
| --- | --- | --- |
| `kind` | [`MediusMotionKind`](/bindings/c/types.md#motion-kind) | Cursor vs wheel. |
| `dx` | `int16_t` | X movement (Cursor only). |
| `dy` | `int16_t` | Y movement (Cursor only). |
| `wheel` | `int16_t` | Scroll delta (Wheel only). |

## MediusLockTarget

_What a lock acts on_

Passed to [`medius_device_lock`](/bindings/c/api.md#lock) / `_unlock`. Build it with [`medius_lock_target_axis`](/bindings/c/api.md#builders) or `medius_lock_target_usage`; `usage` is read only when `kind` is `USAGE`. See [Lock](/library/lock.md).

| Field | C type | Meaning |
| --- | --- | --- |
| `kind` | [`MediusLockTargetKind`](/bindings/c/types.md#lock-target-kind) | X, Y, Wheel, or Usage. |
| `usage` | [`MediusUsage`](/bindings/c/types.md#input) | The button, key, or media usage, when `kind == USAGE`. |

## Query values

_PODs written through a query's out-param_

Each [`medius_device_query_*`](/bindings/c/api.md#queries) / `_caps` / `_counters` call fills one of these by value. Canonical field docs are on [Structs](/library/types/structs.md); query semantics on [Requests](/native/commands/requests.md#requests).

## MediusVersion

_Decoded firmware version and box name_

From [`medius_device_query_version`](/bindings/c/api.md#queries). Set the box's `name` with [`medius_device_set_name`](/bindings/c/api.md#led-admin-options).

| Field | C type | Meaning |
| --- | --- | --- |
| `proto_ver` | `uint8_t` | Wire-protocol version the firmware speaks. |
| `fw_major` | `uint8_t` | Firmware major version. |
| `fw_minor` | `uint8_t` | Firmware minor version. |
| `fw_patch` | `uint8_t` | Firmware patch version. |
| `mac` | `uint8_t[6]` | The device chip's base MAC, a stable per-box id. |
| `name` | `char[MEDIUS_MAX_NAME]` | The box's human-readable name (NUL-terminated; a synthesized default when unset). |

## MediusHealth

_Box readiness flags (each 0 or 1)_

From [`medius_device_query_health`](/bindings/c/api.md#queries).

| Field | C type | True (1) when |
| --- | --- | --- |
| `link_up` | `uint8_t` | The link to the host chip is up. |
| `mouse_attached` | `uint8_t` | A real mouse is plugged in. |
| `clone_configured` | `uint8_t` | The PC has set up the cloned mouse. |
| `injection_active` | `uint8_t` | At least one injected button or move is held. |
| `rate_confident` | `uint8_t` | The native-rate estimator window is full. |
| `lock_on` | `uint8_t` | At least one input lock is active. |
| `catch_on` | `uint8_t` | A catch subscription is streaming. |
| `kbd_attached` | `uint8_t` | A keyboard is attached, cloned, and injectable. |

## MediusDeviceInfo

_The cloned device's USB identity, kind, and product_

From [`medius_device_device_info`](/bindings/c/api.md#queries); all-zero/empty when nothing is cloned. `product` is a NUL-terminated UTF-8 string.

| Field | C type | Meaning |
| --- | --- | --- |
| `vid` | `uint16_t` | USB vendor id (idVendor). |
| `pid` | `uint16_t` | USB product id (idProduct). |
| `bcd_device` | `uint16_t` | Device release (bcdDevice). |
| `bcd_usb` | `uint16_t` | USB version (bcdUSB), e.g. `0x0200`. |
| `has_serial` | `uint8_t` | The clone serves a serial string. |
| `has_bos` | `uint8_t` | The clone serves a BOS descriptor. |
| `kind` | [`MediusDeviceKind`](/bindings/c/types.md#device-kind) | The device's primary kind (Boot-interface protocol). |
| `product` | `char[MEDIUS_MAX_PRODUCT]` | The product string (NUL-terminated; empty when none). |

## MediusCaps

_The whole cloned device's capabilities_

From [`medius_device_caps`](/bindings/c/api.md#queries): a mouse half and a keyboard half plus the per-class change-driven flags. Test it with [`medius_caps_has_mouse`](/bindings/c/api.md#inspectors), [`medius_caps_has_keyboard`](/bindings/c/api.md#inspectors), [`medius_caps_is_composite`](/bindings/c/api.md#inspectors).

| Field | C type | Meaning |
| --- | --- | --- |
| `mouse` | [`MediusMouseCaps`](/bindings/c/types.md#mouse-caps) | The mouse half (all-zero when no mouse is bound). |
| `keyboard` | [`MediusKbdCaps`](/bindings/c/types.md#kbd-caps) | The keyboard half (all-zero when no keyboard is bound). |
| `mouse_change_driven` | `uint8_t` | Always 0: mouse motion is continuous, so it has a learned cadence. |
| `kbd_change_driven` | `uint8_t` | 1 when a keyboard is bound: it reports only on a key change. |

## MediusMouseCaps

_What the cloned mouse can do_

The mouse half of [`MediusCaps`](/bindings/c/types.md#caps); all-zero when no mouse interface is bound.

| Field | C type | Meaning |
| --- | --- | --- |
| `n_buttons` | `uint8_t` | Buttons the mouse report carries. |
| `has_x` | `uint8_t` | The report carries an X axis. |
| `has_y` | `uint8_t` | The report carries a Y axis. |
| `has_wheel` | `uint8_t` | The report carries a wheel. |
| `has_report_id` | `uint8_t` | The mouse report sits behind a HID report ID. |
| `n_hid` | `uint8_t` | Cloned HID interfaces; `>1` = composite. |

## MediusKbdCaps

_What the cloned keyboard can do_

The keyboard half of [`MediusCaps`](/bindings/c/types.md#caps); all-zero when no keyboard is bound. `n_keys == 0xFF` signals an NKRO bitmap.

| Field | C type | Meaning |
| --- | --- | --- |
| `n_keys` | `uint8_t` | Keycode-array slots, or `0xFF` for an NKRO bitmap. |
| `nkro` | `uint8_t` | The keyboard reports an NKRO bitmap. |
| `has_consumer` | `uint8_t` | A Consumer collection is present (media injectable). |
| `has_system` | `uint8_t` | A system-control collection is present (passthrough-only). |
| `has_report_id` | `uint8_t` | The keyboard report sits behind a HID report ID. |

## MediusRate

_The native report rate and clone poll period_

From [`medius_device_query_rate`](/bindings/c/api.md#queries). Convert to Hz with [`medius_rate_native_hz(rate, &hz)`](/bindings/c/api.md#inspectors) (returns false when there's no continuous cadence).

| Field | C type | Meaning |
| --- | --- | --- |
| `native_period_us` | `uint16_t` | Realised native period in µs; `0` = not learned, or change-driven. |
| `poll_period_us` | `uint16_t` | Cloned inject-endpoint poll period in µs. |
| `confident` | `uint8_t` | The estimator window is full and the value is trustworthy. |
| `change_driven` | `uint8_t` | The active input is event-driven (keyboard/media), so no continuous cadence. |

## MediusStats

_Box-side delivery / telemetry counters_

From [`medius_device_query_stats`](/bindings/c/api.md#queries). A nonzero `tx_drops` or `tx_wedges` means delivery degraded under load.

| Field | C type | Meaning |
| --- | --- | --- |
| `inject_emits` | `uint32_t` | Pure-injection reports emitted. |
| `tx_drops` | `uint16_t` | Reports dropped on TX-queue overflow (should stay 0). |
| `tx_merges` | `uint16_t` | Backed-up reports merged instead of queued. |
| `tx_maxdepth` | `uint8_t` | Deepest the TX queue has reached. |
| `tx_wedges` | `uint8_t` | Wedged-endpoint recoveries. |
| `wakeups` | `uint16_t` | Remote-wakeups issued. |
| `reset_count` | `uint16_t` | USB bus resets seen. |
| `config_count` | `uint16_t` | SET\_CONFIGURATION events (re-enumerations). |

## MediusLocks & MediusLockEntry

_The active locks, as an entry list_

From [`medius_device_query_locks`](/bindings/c/api.md#queries): `entries[0..n]`, one per locked target. Test a target/direction with [`medius_locks_is_locked(&locks, target, dir)`](/bindings/c/api.md#inspectors), which reports a match from a specific entry or a covering whole-class `is_blanket` lock. Wire layout on the native [LOCKS](/native/commands/requests.md#requests) reply.

| Field | C type | Meaning |
| --- | --- | --- |
| `n` | `uint16_t` | Live entries in `entries`. |
| `entries` | `MediusLockEntry[MEDIUS_MAX_LOCKS]` | One per locked axis or usage. |

#### MEDIUSLOCKENTRY

| Field | C type | Meaning |
| --- | --- | --- |
| `target` | [`MediusLockTarget`](/bindings/c/types.md#lock-target) | The locked axis or usage. |
| `is_blanket` | `bool` | The lock covers a whole class; `target.usage.kind` names it and `target.usage.id` is unused. |
| `positive` | `bool` | The positive edge (axis `+`, or press) is locked. |
| `negative` | `bool` | The negative edge (axis `-`, or release) is locked. |

## MediusCatchState

_The active catch subscription_

From [`medius_device_query_catch`](/bindings/c/api.md#queries). A nonzero `dropped` means the box shed events under back-pressure.

| Field | C type | Meaning |
| --- | --- | --- |
| `mask` | `uint8_t` | Subscribed classes (the [`MEDIUS_CATCH_MASK_*`](/bindings/c/types.md#catch-mask) bits); 0 = none. |
| `dropped` | `uint32_t` | Box-side events dropped under back-pressure. |

## MediusImperfectStatus

_The imperfect-clone state (each 0 or 1)_

From [`medius_device_query_imperfect`](/bindings/c/api.md#queries). See [Options](/library/options.md).

| Field | C type | True (1) when |
| --- | --- | --- |
| `allowed` | `uint8_t` | The opt-in toggle; cloning an over-capacity device is allowed. |
| `over_capacity` | `uint8_t` | The device needs an interrupt-IN endpoint the box can't service. |
| `clone_imperfect` | `uint8_t` | The live clone is over-capacity and was cloned anyway, so one interface is dead. |

## MediusEmitPaceStatus

_The emit-rate pacing state_

From [`medius_device_query_emit_pace`](/bindings/c/api.md#queries). See [Options](/library/options.md).

| Field | C type | Meaning |
| --- | --- | --- |
| `mode` | [`MediusEmitMode`](/bindings/c/types.md#emit-mode) | The selected mode. |
| `fixed_hz` | `uint16_t` | The rate requested for `FIXED` (0 otherwise). |
| `resolved_hz` | `uint16_t` | The ceiling in effect; 0 = learnt/adaptive, or no device yet in `INTERVAL`. |

## MediusCountersSnapshot

_Host-side always-on link counters_

From [`medius_device_counters`](/bindings/c/api.md#queries). See [Logs & counters](/library/diagnostics.md).

| Field | C type | Meaning |
| --- | --- | --- |
| `frames_tx` | `uint64_t` | Frames sent to the box. |
| `frames_rx` | `uint64_t` | Frames received from the box. |
| `crc_drops` | `uint64_t` | Inbound frames dropped on a bad [checksum](/native/frame.md). |
| `reconnects` | `uint64_t` | Times the library reopened the port. |

## MediusPortInfo

_A discovered medius serial port_

Filled by [`medius_find_ports`](/bindings/c/api.md#connect); `path` and `serial` are NUL-terminated. Canonical docs on [`PortInfo`](/library/types/structs.md#port-info).

| Field | C type | Meaning |
| --- | --- | --- |
| `path` | `char[MEDIUS_MAX_PATH]` | Serial port path (NUL-terminated). |
| `vid` | `uint16_t` | USB vendor id (`0x1A86`). |
| `pid` | `uint16_t` | USB product id (`0x55D3`). |
| `serial` | `char[MEDIUS_MAX_SERIAL]` | The CH343 adapter's serial (NUL-terminated); empty when `has_serial == 0`. |
| `has_serial` | `uint8_t` | Whether the adapter serves a serial string. |

## MediusBoxInfo

_One discovered box: port, version, and cloned device_

Filled by [`medius_list`](/bindings/c/api.md#discovery): one entry per connected box, each opened and handshaked in turn. See [`BoxInfo`](/library/discovery.md#box-info).

| Field | C type | Meaning |
| --- | --- | --- |
| `port` | [`MediusPortInfo`](/bindings/c/types.md#portinfo) | The box's control port (path + CH343 serial). |
| `version` | [`MediusVersion`](/bindings/c/types.md#version) | Its firmware version, with the box MAC and name. |
| `device` | [`MediusDeviceInfo`](/bindings/c/types.md#device-info) | The device it clones. |

## Event & log types

_Fixed-size PODs off the streams_

The values you read off the [catch and log streams](/bindings/c/streams.md). Catch semantics on [Catch](/library/catch.md); canonical docs on [Structs](/library/types/structs.md).

## MediusMotionEvent

_One physical relative-axis snapshot_

The user's real motion at the merge point, before any lock suppression or injection. Surfaces as the `Motion` arm of a [`MediusCatchEvent`](/bindings/c/types.md#catch-event).

| Field | C type | Meaning |
| --- | --- | --- |
| `dx` | `int16_t` | Relative X this report (right positive). |
| `dy` | `int16_t` | Relative Y this report (down positive). |
| `dz` | `int16_t` | Wheel delta this report (up positive). |

## MediusUsageEvent

_One held-usage snapshot for a class_

The held usages of one class (button, key, or media; modifiers are key usages `0xE0 to 0xE7`) in `usages[0..n]`, buttons and keys the same shape. Test one with [`medius_usage_event_is_held(&event, usage)`](/bindings/c/api.md#inspectors), or diff successive snapshots for edges.

| Field | C type | Meaning |
| --- | --- | --- |
| `n` | `uint16_t` | Live usages in `usages`. |
| `usages` | `MediusUsage[MEDIUS_MAX_USAGES]` | The held [`MediusUsage`](/bindings/c/types.md#input) usages (button, key, or media). |

## MediusCatchEvent

_One catch-stream event (a tagged union)_

```text
struct MediusCatchEvent {
    MediusCatchEventKind kind;
    union MediusCatchEventData { MediusMotionEvent motion; MediusUsageEvent usages; } data;
}
```

Written by [`medius_event_stream_recv`](/bindings/c/api.md#streams) and friends. Read the union member named by [`kind`](/bindings/c/types.md#catch-event-kind).

| Field | C type | Meaning |
| --- | --- | --- |
| `kind` | [`MediusCatchEventKind`](/bindings/c/types.md#catch-event-kind) | Which union member is live. |
| `data.motion` | [`MediusMotionEvent`](/bindings/c/types.md#motion-event) | Read when `kind == MOTION`. |
| `data.usages` | [`MediusUsageEvent`](/bindings/c/types.md#usage-event) | Read when `kind == USAGES`. |

## MediusLogLine

_One device log line_

Written by [`medius_log_stream_recv`](/bindings/c/api.md#streams); `text` is NUL-terminated.

| Field | C type | Meaning |
| --- | --- | --- |
| `level` | [`MediusLogLevel`](/bindings/c/types.md#log-level) | Severity tag. |
| `text` | `char[MEDIUS_MAX_LOG_TEXT]` | The decoded message (NUL-terminated). |

## MediusClipTrigger

_One physical-input binding that drives the clip_

A managed binding you add with [`medius_clip_bind`](/bindings/c/api.md#clip): when `on` hits `edge`, the box runs `action` on the clip. Build the `on` usage with the [`medius_usage_*`](/bindings/c/api.md#builders) helpers. Concept on [Clip](/library/clip.md).

| Field | C type | Meaning |
| --- | --- | --- |
| `on` | [`MediusUsage`](/bindings/c/types.md#input) | The physical button, key, or media usage that fires the binding. |
| `edge` | [`MediusEdge`](/bindings/c/types.md#edge) | Which edge of `on` fires it. |
| `action` | [`MediusClipAction`](/bindings/c/types.md#clip-action) | What it does to the clip. |
| `consume` | `uint8_t` | 1 to swallow the input so the game never sees it; 0 to let it pass through. |

## MediusClipSettings

_The clip configuration read back from the box_

From [`medius_clip_query_config`](/bindings/c/api.md#clip): the auto-lock scope, the loop/retain/finalize scalars, and the live trigger set. Concept on [Clip](/library/clip.md).

| Field | C type | Meaning |
| --- | --- | --- |
| `autolock_bits` | `uint8_t` | The auto-lock scope as `CLIP_LOCK_*` wire bits (set with [`medius_clip_set_autolock`](/bindings/c/api.md#clip)). |
| `loop_` | `uint8_t` | Playback loops at the clip end (retained mode only). |
| `retain` | `uint8_t` | The loaded clip is retained so it can rewind and replay (0 = streaming). |
| `finalized` | `uint8_t` | A retained clip's end is fixed, so it can replay and loop. |
| `triggers` | [`MediusClipTrigger`](/bindings/c/types.md#clip-trigger)`[MEDIUS_CLIP_TRIG_MAX]` | The bound triggers, `triggers[0..n]`. |
| `n` | `uint8_t` | Live entries in `triggers`. |

## MediusClipStatus & MediusClipState

_Buffered-clip ring and playback state_

From [`medius_clip_query_status`](/bindings/c/api.md#clip); `state` is a `MediusClipState`. Concept on [Clip](/library/clip.md).

#### MEDIUSCLIPSTATE

| Enumerator | Value | Meaning |
| --- | --- | --- |
| `MEDIUS_CLIP_STATE_IDLE` | `0` | No clip playing (empty, or a loaded clip parked at its start). |
| `MEDIUS_CLIP_STATE_PLAYING` | `1` | Draining the ring, one entry per native frame. |
| `MEDIUS_CLIP_STATE_PAUSED` | `2` | Halted mid-clip; the cursor and any held usages are retained. |
| `MEDIUS_CLIP_STATE_FAULTED` | `3` | An append was dropped or the ring overflowed; recover with [`medius_clip_clear`](/bindings/c/api.md#clip). |

#### MEDIUSCLIPSTATUS

| Field | C type | Meaning |
| --- | --- | --- |
| `state` | `MediusClipState` | The lifecycle state. |
| `free` | `uint32_t` | Ring bytes free; pace top-ups off this. |
| `total` | `uint32_t` | The retained clip size in bytes; streaming, the buffered-but-undrained bytes. |
| `played` | `uint32_t` | Bytes played from the clip start (retained progress; ~0 while streaming). |
| `ticks` | `uint32_t` | Content frames drained since the last start (gap runs are not counted). |
| `underruns` | `uint16_t` | Empty-ring episodes. |
| `overruns` | `uint16_t` | Appends dropped because the ring was full. |
| `seq_gaps` | `uint16_t` | Dropped append frames detected. |
| `held_n` | `uint16_t` | Held usages in `held`. |
| `held` | `MediusUsage[MEDIUS_MAX_USAGES]` | The buttons, keys, and media the clip is holding down; test one with [`medius_clip_status_is_held`](/bindings/c/api.md#inspectors). |

## Errors

_MediusStatus plus a thread-local message_

```text
enum MediusStatus : int32_t   /* MEDIUS_STATUS_OK == 0; everything else is a failure */
```

Every fallible call returns a `MediusStatus` and writes its result through an out-param. On failure the detail lives in thread-local state. Read it before the next call on that thread overwrites it. Canonical mapping on [Errors](/library/types/errors.md).

| Enumerator | Value | Meaning |
| --- | --- | --- |
| `MEDIUS_STATUS_OK` | `0` | Success. |
| `MEDIUS_STATUS_ERR_IO` | `1` | An underlying serial or OS error. |
| `MEDIUS_STATUS_ERR_NOT_FOUND` | `2` | No device matched the expected VID/PID. |
| `MEDIUS_STATUS_ERR_NO_REPLY` | `3` | The box never answered the version query during the [handshake](/native/connection.md#handshake). |
| `MEDIUS_STATUS_ERR_BAD_PROTO_VER` | `4` | The box answered with an unexpected `proto_ver` (see `medius_last_error_proto_ver`). |
| `MEDIUS_STATUS_ERR_QUERY_TIMEOUT` | `5` | A query waited past its timeout with no reply. |
| `MEDIUS_STATUS_ERR_DISCONNECTED` | `6` | The link dropped (also returned by a stream when it closes). |
| `MEDIUS_STATUS_ERR_FRAME_TOO_LONG` | `7` | An outbound frame exceeded the wire limit. |
| `MEDIUS_STATUS_ERR_FLASH_TOOL` | `8` | The [flash](/library/features/flash.md) subprocess ([esptool](https://github.com/espressif/esptool)) failed. |
| `MEDIUS_STATUS_ERR_INVALID_ARG` | `9` | A bad argument (e.g. a null required pointer). |
| `MEDIUS_STATUS_ERR_PANIC` | `10` | A Rust panic was caught at the boundary. |
| `MEDIUS_STATUS_ERR_UNKNOWN` | `11` | An unclassified failure. |

| Function | Returns | Meaning |
| --- | --- | --- |
| `medius_last_error_message(char *buf, uintptr_t cap)` | `uintptr_t` | Copies the last error's text (NUL-terminated, truncated to `cap`); returns the full length, so you can size a buffer and retry. |
| `medius_last_error_proto_ver(void)` | `uint8_t` | The version byte from a `BAD_PROTO_VER` error, or 0. |

#### EXAMPLE

```c
MediusDevice *dev = NULL;
if (medius_device_find(&dev) != MEDIUS_STATUS_OK) {
    char buf[256];
    medius_last_error_message(buf, sizeof buf);
    fprintf(stderr, "open failed: %s\n", buf);
    return 1;
}
```
