diff --git a/Cargo.lock b/Cargo.lock index a79a34f..70871d2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -70,6 +70,29 @@ version = "0.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" +[[package]] +name = "bindgen" +version = "0.68.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "726e4313eb6ec35d2730258ad4e15b547ee75d6afaa1361a922e78e59b7d8078" +dependencies = [ + "bitflags 2.4.0", + "cexpr", + "clang-sys", + "lazy_static", + "lazycell", + "log", + "peeking_take_while", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn 2.0.33", + "which", +] + [[package]] name = "bit-set" version = "0.2.0" @@ -150,6 +173,15 @@ dependencies = [ "libc", ] +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + [[package]] name = "cfg-expr" version = "0.15.5" @@ -166,6 +198,35 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "clang-sys" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "cmake" +version = "0.1.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31c789563b815f77f4250caee12365734369f942439b7defd71e18a48197130" +dependencies = [ + "cc", +] + +[[package]] +name = "convert_case" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +dependencies = [ + "unicode-segmentation", +] + [[package]] name = "core-foundation" version = "0.9.3" @@ -182,6 +243,35 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" +[[package]] +name = "dlopen2" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bc2c7ed06fd72a8513ded8d0d2f6fd2655a85d6885c48cae8625d80faf28c03" +dependencies = [ + "dlopen2_derive", + "libc", + "once_cell", + "winapi", +] + +[[package]] +name = "dlopen2_derive" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2b99bf03862d7f545ebc28ddd33a665b50865f4dfd84031a393823879bd4c54" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.33", +] + +[[package]] +name = "either" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" + [[package]] name = "encoding_rs" version = "0.8.33" @@ -200,6 +290,7 @@ dependencies = [ "git2", "gtk4", "libadwaita", + "libmonado-rs", "libusb", "nix", "phf", @@ -257,6 +348,12 @@ dependencies = [ "rustc_version", ] +[[package]] +name = "flagset" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a7e408202050813e6f1d9addadcaafef3dca7530c7ddfb005d4081cce6779" + [[package]] name = "flume" version = "0.11.0" @@ -585,6 +682,12 @@ dependencies = [ "system-deps", ] +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + [[package]] name = "gobject-sys" version = "0.18.0" @@ -747,6 +850,15 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" +[[package]] +name = "home" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" +dependencies = [ + "windows-sys", +] + [[package]] name = "http" version = "0.2.9" @@ -884,6 +996,12 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + [[package]] name = "libadwaita" version = "0.5.2" @@ -936,6 +1054,29 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "libloading" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +dependencies = [ + "cfg-if", + "winapi", +] + +[[package]] +name = "libmonado-rs" +version = "0.1.0" +source = "git+https://github.com/technobaboo/libmonado-rs#3b3f098cb131843ee90f078e26362fcefe02b822" +dependencies = [ + "bindgen", + "cmake", + "convert_case", + "dlopen2", + "flagset", + "semver", +] + [[package]] name = "libssh2-sys" version = "0.3.0" @@ -1057,6 +1198,12 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "miniz_oxide" version = "0.7.1" @@ -1117,6 +1264,16 @@ dependencies = [ "pin-utils", ] +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + [[package]] name = "num_cpus" version = "1.16.0" @@ -1240,6 +1397,12 @@ dependencies = [ "system-deps", ] +[[package]] +name = "peeking_take_while" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" + [[package]] name = "percent-encoding" version = "2.3.0" @@ -1311,6 +1474,16 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +[[package]] +name = "prettyplease" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" +dependencies = [ + "proc-macro2", + "syn 2.0.33", +] + [[package]] name = "proc-macro-crate" version = "1.3.1" @@ -1514,6 +1687,12 @@ version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + [[package]] name = "rustc_version" version = "0.4.0" @@ -1638,6 +1817,12 @@ dependencies = [ "serde", ] +[[package]] +name = "shlex" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7cee0529a6d40f580e7a5e6c495c8fbfe21b7b52795ed4bb5e62cdf92bc6380" + [[package]] name = "siphasher" version = "0.3.11" @@ -1977,6 +2162,12 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "unicode-segmentation" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" + [[package]] name = "url" version = "2.4.1" @@ -2107,6 +2298,18 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix", +] + [[package]] name = "winapi" version = "0.3.9" diff --git a/Cargo.toml b/Cargo.toml index ef47679..8aa9db4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,7 @@ gtk4 = { version = "0.7.2", features = [ libadwaita = { version = "0.5.2", features = [ "v1_3" ] } +libmonado-rs = { git = "https://github.com/technobaboo/libmonado-rs", version = "0.1.0" } libusb = "0.3.0" nix = { version = "0.26.4", features = [ "fs" diff --git a/src/main.rs b/src/main.rs index 2a03a02..809fec4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -38,6 +38,7 @@ pub mod runner_pipeline; pub mod steamvr_utils; pub mod ui; pub mod xr_devices; +pub mod monado_utils; fn restore_steam_xr_files() { let active_runtime = get_current_active_runtime(); diff --git a/src/monado_utils.rs b/src/monado_utils.rs new file mode 100644 index 0000000..d8c2643 --- /dev/null +++ b/src/monado_utils.rs @@ -0,0 +1,11 @@ +use crate::profile::Profile; + +pub fn get_devs(prof: &Profile) { + if let Ok(monado) = libmonado_rs::Monado::create(prof.libmonado_so().unwrap()) { + if let Ok(devs) = monado.devices() { + for dev in devs { + println!(">>> {}", dev.name); + } + } + } +} diff --git a/src/profile.rs b/src/profile.rs index 01a0681..ea299f3 100644 --- a/src/profile.rs +++ b/src/profile.rs @@ -350,6 +350,23 @@ impl Profile { pub fn can_start(&self) -> bool { Path::new(&self.xrservice_binary()).is_file() } + + pub fn libmonado_so(&self) -> Option { + let mut res = format!("{}/lib/libmonado.so", self.prefix); + if Path::new(&res).is_file() { + return Some(res); + } + res = format!("{}/lib64/libmonado.so", self.prefix); + if Path::new(&res).is_file() { + return Some(res); + } + + None + } + + pub fn has_libmonado(&self) -> bool { + self.libmonado_so().is_some() + } } #[cfg(test)] diff --git a/src/ui/app.rs b/src/ui/app.rs index 26c3916..f9ab148 100644 --- a/src/ui/app.rs +++ b/src/ui/app.rs @@ -309,27 +309,37 @@ impl SimpleComponent for App { } Msg::ClockTicking => { self.main_view.sender().emit(MainViewMsg::ClockTicking); + if let Some(w) = self.xrservice_worker.as_ref() { + if w.state.lock().unwrap().exit_status.is_none() { + self.xr_devices.merge(XRDevices::from_libmonado(&self.get_selected_profile())); + self.main_view.sender().emit(MainViewMsg::UpdateDevices( + Some(self.xr_devices.clone()), + )); + } + } } Msg::ParseLog(rows) => { for row in rows { match MonadoLog::new_from_str(row.as_str()) { None => {} Some(parsed) => { - if parsed.func == "p_create_system" { - match XRDevices::from_log_message(parsed.message.as_str()) { - None => {} - Some(devices) => { - self.xr_devices.merge(devices.clone()); - self.main_view.sender().emit(MainViewMsg::UpdateDevices( - Some(self.xr_devices.clone()), - )); - break; - } - }; - } else { - self.xr_devices - .search_log_for_generic_trackers(parsed.message.as_str()); - } + // if parsed.func == "p_create_system" { + // match XRDevices::from_log_message(parsed.message.as_str()) { + // None => {} + // Some(devices) => { + // self.xr_devices.merge(devices.clone()); + // self.main_view.sender().emit(MainViewMsg::UpdateDevices( + // Some(self.xr_devices.clone()), + // )); + // break; + // } + // }; + // } else { + // self.xr_devices + // .search_log_for_generic_trackers(parsed.message.as_str()); + // } + self.xr_devices + .search_log_for_generic_trackers(parsed.message.as_str()); } }; } diff --git a/src/xr_devices.rs b/src/xr_devices.rs index 9a7b4f6..06f25b6 100644 --- a/src/xr_devices.rs +++ b/src/xr_devices.rs @@ -1,3 +1,7 @@ +use std::slice::Iter; + +use crate::profile::Profile; + #[derive(Debug, Clone, PartialEq, Eq)] pub enum XRDevice { Head, @@ -10,6 +14,35 @@ pub enum XRDevice { GenericTracker, } +impl XRDevice { + pub fn iter() -> Iter<'static, Self> { + [ + Self::Head, + Self::Left, + Self::Right, + Self::Gamepad, + Self::Eyes, + Self::HandTrackingLeft, + Self::HandTrackingRight, + Self::GenericTracker, + ] + .iter() + } + + pub fn to_monado_str(&self) -> &str { + match self { + Self::Head => "head", + Self::Left => "left", + Self::Right => "right", + Self::Gamepad => "gamepad", + Self::Eyes => "eyes", + Self::HandTrackingLeft => "hand_tracking.left", + Self::HandTrackingRight => "hand_tracking.right", + Self::GenericTracker => "generic_tracker", + } + } +} + #[derive(Debug, Default, Clone, PartialEq, Eq)] pub struct XRDevices { pub head: Option, @@ -25,6 +58,41 @@ pub struct XRDevices { const GENERIC_TRACKER_PREFIX: &str = "Found generic tracker device: "; impl XRDevices { + fn set_device(&mut self, dev: &XRDevice, name: String) { + match dev { + XRDevice::Head => self.head = Some(name), + XRDevice::Left => self.left = Some(name), + XRDevice::Right => self.right = Some(name), + XRDevice::Gamepad => self.gamepad = Some(name), + XRDevice::Eyes => self.eyes = Some(name), + XRDevice::HandTrackingLeft => self.hand_tracking_left = Some(name), + XRDevice::HandTrackingRight => self.hand_tracking_right = Some(name), + _ => {} + } + } + + pub fn from_libmonado(prof: &Profile) -> Self { + let mut res = Self::default(); + if let Some(libmonado_path) = prof.libmonado_so() { + if let Ok(monado) = libmonado_rs::Monado::create(libmonado_path) { + [ + XRDevice::Head, + XRDevice::Left, + XRDevice::Right, + XRDevice::Gamepad, + XRDevice::Eyes, + ] + .iter() + .for_each(|xrd| { + if let Ok(dev) = monado.device_from_role(xrd.to_monado_str()) { + res.set_device(&xrd, dev.name); + } + }); + } + } + res + } + pub fn from_log_message(s: &str) -> Option { let rows = s.split('\n'); let mut in_section = false;