Skip to content

Commit

Permalink
Merge pull request #130 from mahkoh/jorth/input-cli
Browse files Browse the repository at this point in the history
cli: add an input subcommand
  • Loading branch information
mahkoh authored Mar 15, 2024
2 parents b88a4ea + efae1cd commit 7fcfe35
Show file tree
Hide file tree
Showing 30 changed files with 1,732 additions and 161 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ panic = "abort"
panic = "abort"

[dependencies]
uapi = "0.2.12"
uapi = "0.2.13"
thiserror = "1.0.56"
ahash = "0.8.7"
log = { version = "0.4.20", features = ["std"] }
Expand Down
43 changes: 43 additions & 0 deletions src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use {
fixed::Fixed,
gfx_api::GfxFramebuffer,
ifs::wl_seat::wl_pointer::{CONTINUOUS, FINGER, HORIZONTAL_SCROLL, VERTICAL_SCROLL, WHEEL},
libinput::consts::DeviceCapability,
video::drm::{ConnectorType, DrmError, DrmVersion},
},
jay_config::video::GfxApi,
Expand Down Expand Up @@ -118,14 +119,41 @@ pub trait InputDevice {
fn on_change(&self, cb: Rc<dyn Fn()>);
fn grab(&self, grab: bool);
fn has_capability(&self, cap: InputDeviceCapability) -> bool;
fn left_handed(&self) -> Option<bool> {
None
}
fn set_left_handed(&self, left_handed: bool);
fn accel_profile(&self) -> Option<InputDeviceAccelProfile> {
None
}
fn set_accel_profile(&self, profile: InputDeviceAccelProfile);
fn accel_speed(&self) -> Option<f64> {
None
}
fn set_accel_speed(&self, speed: f64);
fn transform_matrix(&self) -> Option<TransformMatrix> {
None
}
fn set_transform_matrix(&self, matrix: TransformMatrix);
fn name(&self) -> Rc<String>;
fn dev_t(&self) -> Option<c::dev_t> {
None
}
fn tap_enabled(&self) -> Option<bool> {
None
}
fn set_tap_enabled(&self, enabled: bool);
fn drag_enabled(&self) -> Option<bool> {
None
}
fn set_drag_enabled(&self, enabled: bool);
fn drag_lock_enabled(&self) -> Option<bool> {
None
}
fn set_drag_lock_enabled(&self, enabled: bool);
fn natural_scrolling_enabled(&self) -> Option<bool> {
None
}
fn set_natural_scrolling_enabled(&self, enabled: bool);
}

Expand All @@ -140,6 +168,21 @@ pub enum InputDeviceCapability {
Switch,
}

impl InputDeviceCapability {
pub fn to_libinput(self) -> DeviceCapability {
use crate::libinput::consts::*;
match self {
InputDeviceCapability::Keyboard => LIBINPUT_DEVICE_CAP_KEYBOARD,
InputDeviceCapability::Pointer => LIBINPUT_DEVICE_CAP_POINTER,
InputDeviceCapability::Touch => LIBINPUT_DEVICE_CAP_TOUCH,
InputDeviceCapability::TabletTool => LIBINPUT_DEVICE_CAP_TABLET_TOOL,
InputDeviceCapability::TabletPad => LIBINPUT_DEVICE_CAP_TABLET_PAD,
InputDeviceCapability::Gesture => LIBINPUT_DEVICE_CAP_GESTURE,
InputDeviceCapability::Switch => LIBINPUT_DEVICE_CAP_SWITCH,
}
}
}

#[derive(Debug, Copy, Clone)]
pub enum InputDeviceAccelProfile {
Flat,
Expand Down
205 changes: 151 additions & 54 deletions src/backends/metal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,7 @@ use {
libinput::{
consts::{
AccelProfile, LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE,
LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT, LIBINPUT_DEVICE_CAP_GESTURE,
LIBINPUT_DEVICE_CAP_KEYBOARD, LIBINPUT_DEVICE_CAP_POINTER,
LIBINPUT_DEVICE_CAP_SWITCH, LIBINPUT_DEVICE_CAP_TABLET_PAD,
LIBINPUT_DEVICE_CAP_TABLET_TOOL, LIBINPUT_DEVICE_CAP_TOUCH,
LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT,
},
device::RegisteredDevice,
LibInput, LibInputAdapter, LibInputError,
Expand Down Expand Up @@ -281,7 +278,7 @@ pub async fn create(state: &Rc<State>) -> Result<Rc<MetalBackend>, MetalError> {
struct MetalInputDevice {
slot: usize,
id: InputDeviceId,
_devnum: c::dev_t,
devnum: c::dev_t,
fd: CloneCell<Option<Rc<OwnedFd>>>,
inputdev: CloneCell<Option<Rc<RegisteredDevice>>>,
devnode: CString,
Expand All @@ -290,17 +287,22 @@ struct MetalInputDevice {
events: SyncQueue<InputEvent>,
cb: CloneCell<Option<Rc<dyn Fn()>>>,
name: CloneCell<Rc<String>>,
natural_scrolling: Cell<bool>,
transform_matrix: Cell<Option<TransformMatrix>>,

// state
pressed_keys: SmallMap<u32, (), 5>,
pressed_buttons: SmallMap<u32, (), 2>,

// config
desired: InputDeviceProperties,
effective: InputDeviceProperties,
}

#[derive(Default)]
struct InputDeviceProperties {
left_handed: Cell<Option<bool>>,
accel_profile: Cell<Option<AccelProfile>>,
accel_speed: Cell<Option<f64>>,
transform_matrix: Cell<Option<TransformMatrix>>,
tap_enabled: Cell<Option<bool>>,
drag_enabled: Cell<Option<bool>>,
drag_lock_enabled: Cell<Option<bool>>,
Expand Down Expand Up @@ -341,30 +343,58 @@ impl LibInputAdapter for DeviceHolder {

impl MetalInputDevice {
fn apply_config(&self) {
let dev = match self.inputdev.get() {
Some(dev) => dev,
_ => return,
};
if let Some(lh) = self.left_handed.get() {
dev.device().set_left_handed(lh);
if self.inputdev.is_none() {
return;
}
if let Some(lh) = self.desired.left_handed.get() {
self.set_left_handed(lh);
}
if let Some(profile) = self.accel_profile.get() {
dev.device().set_accel_profile(profile);
if let Some(profile) = self.desired.accel_profile.get() {
self.set_accel_profile_(profile);
}
if let Some(speed) = self.accel_speed.get() {
dev.device().set_accel_speed(speed);
if let Some(speed) = self.desired.accel_speed.get() {
self.set_accel_speed(speed);
}
if let Some(enabled) = self.tap_enabled.get() {
dev.device().set_tap_enabled(enabled);
if let Some(enabled) = self.desired.tap_enabled.get() {
self.set_tap_enabled(enabled);
}
if let Some(enabled) = self.desired.drag_enabled.get() {
self.set_drag_enabled(enabled);
}
if let Some(enabled) = self.desired.drag_lock_enabled.get() {
self.set_drag_lock_enabled(enabled);
}
if let Some(enabled) = self.desired.natural_scrolling_enabled.get() {
self.set_natural_scrolling_enabled(enabled);
}
self.fetch_effective();
}

fn fetch_effective(&self) {
let Some(dev) = self.inputdev.get() else {
return;
};
let device = dev.device();
if device.left_handed_available() {
self.effective.left_handed.set(Some(device.left_handed()));
}
if let Some(enabled) = self.drag_enabled.get() {
dev.device().set_drag_enabled(enabled);
if device.accel_available() {
self.effective
.accel_profile
.set(Some(device.accel_profile()));
self.effective.accel_speed.set(Some(device.accel_speed()));
}
if let Some(enabled) = self.drag_lock_enabled.get() {
dev.device().set_drag_lock_enabled(enabled);
if device.tap_available() {
self.effective.tap_enabled.set(Some(device.tap_enabled()));
self.effective.drag_enabled.set(Some(device.drag_enabled()));
self.effective
.drag_lock_enabled
.set(Some(device.drag_lock_enabled()));
}
if let Some(enabled) = self.natural_scrolling_enabled.get() {
self.do_set_natural_scrolling_enabled(&dev, enabled);
if device.has_natural_scrolling() {
self.effective
.natural_scrolling_enabled
.set(Some(device.natural_scrolling_enabled()));
}
}

Expand All @@ -386,10 +416,16 @@ impl MetalInputDevice {
}
}

fn do_set_natural_scrolling_enabled(&self, dev: &RegisteredDevice, enabled: bool) {
dev.device().set_natural_scrolling_enabled(enabled);
self.natural_scrolling
.set(dev.device().natural_scrolling_enabled());
fn set_accel_profile_(&self, profile: AccelProfile) {
self.desired.accel_profile.set(Some(profile));
if let Some(dev) = self.inputdev.get() {
if dev.device().accel_available() {
dev.device().set_accel_profile(profile);
self.effective
.accel_profile
.set(Some(dev.device().accel_profile()));
}
}
}
}

Expand All @@ -415,25 +451,22 @@ impl InputDevice for MetalInputDevice {
}

fn has_capability(&self, cap: InputDeviceCapability) -> bool {
let li = match cap {
InputDeviceCapability::Keyboard => LIBINPUT_DEVICE_CAP_KEYBOARD,
InputDeviceCapability::Pointer => LIBINPUT_DEVICE_CAP_POINTER,
InputDeviceCapability::Touch => LIBINPUT_DEVICE_CAP_TOUCH,
InputDeviceCapability::TabletTool => LIBINPUT_DEVICE_CAP_TABLET_TOOL,
InputDeviceCapability::TabletPad => LIBINPUT_DEVICE_CAP_TABLET_PAD,
InputDeviceCapability::Gesture => LIBINPUT_DEVICE_CAP_GESTURE,
InputDeviceCapability::Switch => LIBINPUT_DEVICE_CAP_SWITCH,
};
let li = cap.to_libinput();
match self.inputdev.get() {
Some(dev) => dev.device().has_cap(li),
_ => false,
}
}

fn set_left_handed(&self, left_handed: bool) {
self.left_handed.set(Some(left_handed));
self.desired.left_handed.set(Some(left_handed));
if let Some(dev) = self.inputdev.get() {
dev.device().set_left_handed(left_handed);
if dev.device().left_handed_available() {
dev.device().set_left_handed(left_handed);
self.effective
.left_handed
.set(Some(dev.device().left_handed()));
}
}
}

Expand All @@ -442,16 +475,18 @@ impl InputDevice for MetalInputDevice {
InputDeviceAccelProfile::Flat => LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT,
InputDeviceAccelProfile::Adaptive => LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE,
};
self.accel_profile.set(Some(profile));
if let Some(dev) = self.inputdev.get() {
dev.device().set_accel_profile(profile);
}
self.set_accel_profile_(profile);
}

fn set_accel_speed(&self, speed: f64) {
self.accel_speed.set(Some(speed));
self.desired.accel_speed.set(Some(speed));
if let Some(dev) = self.inputdev.get() {
dev.device().set_accel_speed(speed);
if dev.device().accel_available() {
dev.device().set_accel_speed(speed);
self.effective
.accel_speed
.set(Some(dev.device().accel_speed()));
}
}
}

Expand All @@ -463,33 +498,95 @@ impl InputDevice for MetalInputDevice {
self.name.get()
}

fn dev_t(&self) -> Option<c::dev_t> {
Some(self.devnum)
}

fn set_tap_enabled(&self, enabled: bool) {
self.tap_enabled.set(Some(enabled));
self.desired.tap_enabled.set(Some(enabled));
if let Some(dev) = self.inputdev.get() {
dev.device().set_tap_enabled(enabled);
if dev.device().tap_available() {
dev.device().set_tap_enabled(enabled);
self.effective
.tap_enabled
.set(Some(dev.device().tap_enabled()));
}
}
}

fn set_drag_enabled(&self, enabled: bool) {
self.drag_enabled.set(Some(enabled));
self.desired.drag_enabled.set(Some(enabled));
if let Some(dev) = self.inputdev.get() {
dev.device().set_drag_enabled(enabled);
if dev.device().tap_available() {
dev.device().set_drag_enabled(enabled);
self.effective
.drag_enabled
.set(Some(dev.device().drag_enabled()));
}
}
}

fn set_drag_lock_enabled(&self, enabled: bool) {
self.drag_lock_enabled.set(Some(enabled));
self.desired.drag_lock_enabled.set(Some(enabled));
if let Some(dev) = self.inputdev.get() {
dev.device().set_drag_lock_enabled(enabled);
if dev.device().tap_available() {
dev.device().set_drag_lock_enabled(enabled);
self.effective
.drag_lock_enabled
.set(Some(dev.device().drag_lock_enabled()));
}
}
}

fn set_natural_scrolling_enabled(&self, enabled: bool) {
self.natural_scrolling_enabled.set(Some(enabled));
self.desired.natural_scrolling_enabled.set(Some(enabled));
if let Some(dev) = self.inputdev.get() {
self.do_set_natural_scrolling_enabled(&dev, enabled);
if dev.device().has_natural_scrolling() {
dev.device().set_natural_scrolling_enabled(enabled);
self.effective
.natural_scrolling_enabled
.set(Some(dev.device().natural_scrolling_enabled()));
}
}
}

fn left_handed(&self) -> Option<bool> {
self.effective.left_handed.get()
}

fn accel_profile(&self) -> Option<InputDeviceAccelProfile> {
let p = self.effective.accel_profile.get()?;
let p = match p {
LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT => InputDeviceAccelProfile::Flat,
LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE => InputDeviceAccelProfile::Adaptive,
_ => return None,
};
Some(p)
}

fn accel_speed(&self) -> Option<f64> {
self.effective.accel_speed.get()
}

fn transform_matrix(&self) -> Option<TransformMatrix> {
self.transform_matrix.get()
}

fn tap_enabled(&self) -> Option<bool> {
self.effective.tap_enabled.get()
}

fn drag_enabled(&self) -> Option<bool> {
self.effective.drag_enabled.get()
}

fn drag_lock_enabled(&self) -> Option<bool> {
self.effective.drag_lock_enabled.get()
}

fn natural_scrolling_enabled(&self) -> Option<bool> {
self.effective.natural_scrolling_enabled.get()
}
}

impl MetalInputDevice {
Expand Down
Loading

0 comments on commit 7fcfe35

Please sign in to comment.