Medius - Rust LibraryLock

Lock

Weigh one physical input; injection still drives it

A scale sets how much of the physical device reaches the game PC on one input, while host injection still drives that same input at full strength. Blocking and passing are its two ends.

  scale 0     physical  --X   blocked
  scale 40    physical  -.->  40% gets through
  scale 100   physical  -->   untouched
  scale 200   physical  ==>   doubled

  injection always -->  unweighed, whatever the scale
Weigh a...Any percentageBlockRelease
relative axis (X / Y / wheel)scale / scale_axislock / lock_axisunlock / unlock_axis
button, key, or media usagetruncates to a locklockunlock
a whole class (blanket)scale_alllock_allunlock_all

All are fire-and-forget: one frame, no reply. query_locks reads the active set.

scale

Keep a percentage of a physical input
fn scale(&self, target: impl Into<LockTarget>, direction: Direction, scale: u8) -> Result<()>

Fire-and-forget

ParameterTypeDescription
targetimpl Into<LockTarget>An Axis (X, Y, or wheel) or any Usage (a button, key, or media usage).
directionDirectionA fixed sign or edge, or With / Against measured against the bearing. Only an axis has a bearing, so a relative direction anywhere else is Error::RelativeDirection. A media usage has no edges, so an edge on one goes out as Both.
scaleu8Percent of the physical value kept. LOCK_SCALE_BLOCK (0) blocks, LOCK_SCALE_PASS (100) passes untouched, up to LOCK_SCALE_MAX (255) amplifies.

A delta picks up one fixed-direction scale and one relative one, multiplied, so a block in either zeroes the product. With and Against need a live bearing; see set_bearing. A momentary usage carries one bit, so any scale under 100 locks it.

Direction::Both writes the scale to the two fixed signs and a full pass to the relative pair, so Both of 50 means 50% whether or not a bearing is live. Why.

EXAMPLE
use medius::{Device, Axis, Direction};

let device = Device::find()?;
device.scale(Axis::X, Direction::Against, 40)?;  // 40% of movement opposing the injection
device.scale(Axis::X, Direction::With, 130)?;    // 130% of movement along it
device.scale(Axis::Y, Direction::Negative, 60)?; // 60% of upward movement, always

lock

Block a physical input
fn lock(&self, target: impl Into<LockTarget>, direction: Direction) -> Result<()>

Fire-and-forget

scale at LOCK_SCALE_BLOCK. LockTarget picks the input and Direction picks the sign or edge, also spelled Direction::PRESS and Direction::RELEASE.

ParameterTypeDescription
targetimpl Into<LockTarget>An Axis (X, Y, or wheel) or any Usage (a button, key, or media usage).
directionDirectionBoth (every direction), Positive (axis +, usage press), Negative (axis -, usage release), or With / Against the bearing, which only an axis has.

A lock holds until you unlock it. The box also clears every lock on control-PC silence, on reset, on inter-chip link loss, and when the real device detaches. See the native LOCK command for the wire layout.

EXAMPLE
use medius::{Device, Axis, Button, Key, MediaKey, Direction};

let device = Device::find()?;
device.lock(Axis::X, Direction::Both)?;           // freeze horizontal motion
device.lock(Button::Left, Direction::Positive)?;  // block left-click press
device.lock(Key::LEFT_GUI, Direction::Both)?;     // block the GUI/Windows key
device.lock(MediaKey::PLAY_PAUSE, Direction::Both)?; // media has no edges
device.move_rel(50, 0)?;                          // injection still moves X

unlock

Clear a block
fn unlock(&self, target: impl Into<LockTarget>, direction: Direction) -> Result<()>

Fire-and-forget

scale at LOCK_SCALE_PASS: the same target and direction, back to passing untouched. Direction::Both clears every direction of the target, the bearing-relative pair included, so an unlock never leaves the relative pair still weighing.

EXAMPLE
use medius::{Device, Axis, Direction};

let device = Device::find()?;
device.unlock(Axis::X, Direction::Both)?;   // X passes untouched again

lock_axis / unlock_axis / scale_axis

Weigh a relative axis by sign
fn lock_axis(&self, axis: Axis, direction: Direction) -> Result<()>
fn unlock_axis(&self, axis: Axis, direction: Direction) -> Result<()>
fn scale_axis(&self, axis: Axis, direction: Direction, scale: u8) -> Result<()>

Fire-and-forget

Convenience for lock / unlock / scale with an Axis, where the direction is a sign.

EXAMPLE
use medius::{Device, Axis, Direction};

let device = Device::find()?;
device.lock_axis(Axis::Wheel, Direction::Positive)?; // block scroll up, keep scroll down
device.unlock_axis(Axis::Wheel, Direction::Positive)?;

lock_all / unlock_all / scale_all

Weigh a whole class at once
fn lock_all(&self, what: Blanket, direction: Direction) -> Result<()>
fn unlock_all(&self, what: Blanket, direction: Direction) -> Result<()>
fn scale_all(&self, what: Blanket, direction: Direction, scale: u8) -> Result<()>

Fire-and-forget

Weigh an entire input group at once with a Blanket (Aim, Wheel, Buttons, Keys, or Media). direction reaches every member the same way it reaches one, so Keys takes an edge and Media, having none, sends Both.

Blanket::Aim is how you address X and Y together in BearingMode::Vector, where the box reads X and Y as one thing.

EXAMPLE
use medius::{Device, Blanket, Direction};

let device = Device::find()?;
device.lock_all(Blanket::Keys, Direction::Both)?;        // every key, both edges
device.lock_all(Blanket::Keys, Direction::Positive)?;    // press edges only: a held key still releases
device.unlock_all(Blanket::Keys, Direction::Both)?;
device.scale_all(Blanket::Aim, Direction::Against, 40)?; // 40% of motion opposing the injection, X and Y

On AsyncDevice

locks fire, query_locks awaits

AsyncDevice keeps every lock call synchronous (scale, lock/unlock, scale_axis, and scale_all with their lock and unlock pairs) since they expect no reply; query_locks is a future like the other queries.

EXAMPLE
use futures::executor::block_on;
use medius::{AsyncDevice, Axis, Direction};

let device = AsyncDevice::open("/dev/ttyACM0")?;
device.lock(Axis::Y, Direction::Both)?;       // sync, no await
let locks = block_on(device.query_locks())?;  // query awaits