Lock
Weigh one physical input; injection still drives itA 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 percentage | Block | Release |
|---|---|---|---|
| relative axis (X / Y / wheel) | scale / scale_axis | lock / lock_axis | unlock / unlock_axis |
| button, key, or media usage | truncates to a lock | lock | unlock |
| a whole class (blanket) | scale_all | lock_all | unlock_all |
All are fire-and-forget: one frame, no reply. query_locks reads the active set.
scale
Keep a percentage of a physical inputfn scale(&self, target: impl Into<LockTarget>, direction: Direction, scale: u8) -> Result<()>
Fire-and-forget
| Parameter | Type | Description |
|---|---|---|
target | impl Into<LockTarget> | An Axis (X, Y, or wheel) or any Usage (a button, key, or media usage). |
direction | Direction | A 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. |
scale | u8 | Percent 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.
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, alwayslock
Block a physical inputfn 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.
| Parameter | Type | Description |
|---|---|---|
target | impl Into<LockTarget> | An Axis (X, Y, or wheel) or any Usage (a button, key, or media usage). |
direction | Direction | Both (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.
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 Xunlock
Clear a blockfn 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.
use medius::{Device, Axis, Direction};
let device = Device::find()?;
device.unlock(Axis::X, Direction::Both)?; // X passes untouched againlock_axis / unlock_axis / scale_axis
Weigh a relative axis by signfn 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.
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 oncefn 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.
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 YOn AsyncDevice
locks fire, query_locks awaitsAsyncDevice 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.
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