diff --git a/src/builders/build_openhmd.rs b/src/builders/build_openhmd.rs new file mode 100644 index 0000000..cdc7a4e --- /dev/null +++ b/src/builders/build_openhmd.rs @@ -0,0 +1,60 @@ +use crate::{ + build_tools::{cmake::Cmake, git::Git}, + file_utils::rm_rf, + profile::Profile, + ui::job_worker::job::WorkerJob, +}; +use std::{ + collections::{HashMap, VecDeque}, + path::Path, +}; + +pub fn get_build_openhmd_jobs(profile: &Profile, clean_build: bool) -> VecDeque { + let mut jobs = VecDeque::::new(); + + let git = Git { + repo: match profile.features.openhmd.repo.as_ref() { + Some(r) => r.clone(), + None => "https://github.com/OpenHMD/OpenHMD".into(), + }, + dir: profile.features.openhmd.path.as_ref().unwrap().clone(), + }; + + jobs.push_back(git.get_override_remote_url_job()); + + git.get_clone_or_pull_job(profile).map(|j| { + jobs.push_back(j); + }); + + git.get_checkout_ref_job().map(|j| { + jobs.push_back(j); + if profile.pull_on_build { + jobs.push_back(git.get_pull_job()); + } + }); + + let build_dir = format!("{}/build", profile.features.openhmd.path.as_ref().unwrap()); + let mut cmake_vars: HashMap = HashMap::new(); + cmake_vars.insert("CMAKE_BUILD_TYPE".into(), "Release".into()); + cmake_vars.insert("CMAKE_INSTALL_PREFIX".into(), profile.prefix.clone()); + cmake_vars.insert( + "CMAKE_INSTALL_LIBDIR".into(), + format!("{}/lib", profile.prefix), + ); + cmake_vars.insert("OPENHMD_DRIVER_OCULUS_RIFT_S".into(), "OFF".into()); + + let cmake = Cmake { + env: None, + vars: Some(cmake_vars), + source_dir: profile.features.openhmd.path.as_ref().unwrap().clone(), + build_dir: build_dir.clone(), + }; + if !Path::new(&build_dir).is_dir() || clean_build { + rm_rf(&build_dir); + jobs.push_back(cmake.get_prepare_job()); + } + jobs.push_back(cmake.get_build_job()); + jobs.push_back(cmake.get_install_job()); + + jobs +} diff --git a/src/builders/mod.rs b/src/builders/mod.rs index 03f25aa..c84be3b 100644 --- a/src/builders/mod.rs +++ b/src/builders/mod.rs @@ -3,4 +3,5 @@ pub mod build_libsurvive; pub mod build_mercury; pub mod build_monado; pub mod build_opencomposite; +pub mod build_openhmd; pub mod build_wivrn; diff --git a/src/dependencies/mod.rs b/src/dependencies/mod.rs index 751c939..9203bf9 100644 --- a/src/dependencies/mod.rs +++ b/src/dependencies/mod.rs @@ -3,5 +3,6 @@ pub mod basalt_deps; pub mod libsurvive_deps; pub mod mercury_deps; pub mod monado_deps; +pub mod openhmd_deps; pub mod pkexec_dep; pub mod wivrn_deps; diff --git a/src/dependencies/openhmd_deps.rs b/src/dependencies/openhmd_deps.rs new file mode 100644 index 0000000..0a96de3 --- /dev/null +++ b/src/dependencies/openhmd_deps.rs @@ -0,0 +1,17 @@ +use crate::depcheck::{check_dependencies, Dependency, DependencyCheckResult}; + +fn openhmd_deps() -> Vec { + vec![] +} + +pub fn check_openhmd_deps() -> Vec { + check_dependencies(openhmd_deps()) +} + +pub fn get_missing_openhmd_deps() -> Vec { + check_openhmd_deps() + .iter() + .filter(|res| !res.found) + .map(|res| res.dependency.clone()) + .collect() +} diff --git a/src/paths.rs b/src/paths.rs index e0b8723..3338ae6 100644 --- a/src/paths.rs +++ b/src/paths.rs @@ -17,6 +17,10 @@ pub fn data_libsurvive_path() -> String { format!("{data}/libsurvive", data = get_data_dir()) } +pub fn data_openhmd_path() -> String { + format!("{data}/openhmd", data = get_data_dir()) +} + pub fn wivrn_apk_download_path() -> String { format!("{cache}/wivrn.apk", cache = get_cache_dir()) } diff --git a/src/profile.rs b/src/profile.rs index 63886cb..01a0681 100644 --- a/src/profile.rs +++ b/src/profile.rs @@ -57,6 +57,7 @@ impl Display for XRServiceType { pub enum ProfileFeatureType { Libsurvive, Basalt, + OpenHmd, } impl ProfileFeatureType { @@ -78,6 +79,7 @@ impl Display for ProfileFeatureType { f.write_str(match self { Self::Libsurvive => "Libsurvive", Self::Basalt => "Basalt", + Self::OpenHmd => "OpenHMD", }) } } @@ -101,24 +103,44 @@ impl Default for ProfileFeature { } } +impl ProfileFeature { + pub fn default_libsurvive() -> Self { + Self { + feature_type: ProfileFeatureType::Libsurvive, + ..Default::default() + } + } + + pub fn default_basalt() -> Self { + Self { + feature_type: ProfileFeatureType::Basalt, + ..Default::default() + } + } + + pub fn default_openhmd() -> Self { + Self { + feature_type: ProfileFeatureType::OpenHmd, + ..Default::default() + } + } +} + #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct ProfileFeatures { pub libsurvive: ProfileFeature, pub basalt: ProfileFeature, + #[serde(default = "ProfileFeature::default_openhmd")] + pub openhmd: ProfileFeature, pub mercury_enabled: bool, } impl Default for ProfileFeatures { fn default() -> Self { Self { - libsurvive: ProfileFeature { - feature_type: ProfileFeatureType::Libsurvive, - ..Default::default() - }, - basalt: ProfileFeature { - feature_type: ProfileFeatureType::Basalt, - ..Default::default() - }, + libsurvive: ProfileFeature::default_libsurvive(), + basalt: ProfileFeature::default_basalt(), + openhmd: ProfileFeature::default_openhmd(), mercury_enabled: false, } } @@ -216,17 +238,7 @@ impl Default for Profile { xrservice_path: data_monado_path(), xrservice_type: XRServiceType::Monado, opencomposite_path: data_opencomposite_path(), - features: ProfileFeatures { - libsurvive: ProfileFeature { - feature_type: ProfileFeatureType::Libsurvive, - ..Default::default() - }, - basalt: ProfileFeature { - feature_type: ProfileFeatureType::Basalt, - ..Default::default() - }, - mercury_enabled: false, - }, + features: ProfileFeatures::default(), environment: HashMap::new(), prefix: format!( "{data}/prefixes/default_profile_prefix", @@ -318,6 +330,14 @@ impl Profile { .as_ref() .unwrap_or(&"".to_string()) .is_empty()) + && (!self.features.openhmd.enabled + || !self + .features + .openhmd + .path + .as_ref() + .unwrap_or(&"".to_string()) + .is_empty()) } pub fn xrservice_binary(&self) -> String { @@ -382,10 +402,8 @@ mod tests { path: Some(String::from("/home/user/libsurvive")), repo: None, }, - basalt: ProfileFeature { - feature_type: ProfileFeatureType::Basalt, - ..Default::default() - }, + basalt: ProfileFeature::default_basalt(), + openhmd: ProfileFeature::default_openhmd(), mercury_enabled: false, }, environment: env, diff --git a/src/profiles/mod.rs b/src/profiles/mod.rs index 1f9b3c3..ddc6212 100644 --- a/src/profiles/mod.rs +++ b/src/profiles/mod.rs @@ -1,4 +1,5 @@ pub mod lighthouse; +pub mod openhmd; pub mod system_valve_index; pub mod valve_index; pub mod wivrn; diff --git a/src/profiles/openhmd.rs b/src/profiles/openhmd.rs new file mode 100644 index 0000000..e386209 --- /dev/null +++ b/src/profiles/openhmd.rs @@ -0,0 +1,46 @@ +use crate::{ + constants::APP_NAME, + paths::{data_monado_path, data_opencomposite_path, data_openhmd_path, get_data_dir}, + profile::{ + LighthouseDriver, Profile, ProfileFeature, ProfileFeatureType, ProfileFeatures, + XRServiceType, + }, +}; +use std::collections::HashMap; + +pub fn openhmd_profile() -> Profile { + let data_dir = get_data_dir(); + let prefix = format!("{data}/prefixes/openhmd_default", data = data_dir); + let mut environment: HashMap = HashMap::new(); + environment.insert("XRT_JSON_LOG".into(), "1".into()); + environment.insert("XRT_COMPOSITOR_SCALE_PERCENTAGE".into(), "140".into()); + environment.insert("XRT_COMPOSITOR_COMPUTE".into(), "1".into()); + environment.insert("XRT_DEBUG_GUI".into(), "0".into()); + environment.insert("XRT_CURATED_GUI".into(), "1".into()); + environment.insert( + "LD_LIBRARY_PATH".into(), + format!("{pfx}/lib:{pfx}/lib64", pfx = prefix), + ); + Profile { + uuid: "openhmd-default".into(), + name: format!("OpenHMD - {name} Default", name = APP_NAME), + xrservice_path: data_monado_path(), + xrservice_type: XRServiceType::Monado, + opencomposite_path: data_opencomposite_path(), + features: ProfileFeatures { + openhmd: ProfileFeature { + feature_type: ProfileFeatureType::OpenHmd, + enabled: true, + path: Some(data_openhmd_path()), + repo: None, + }, + ..Default::default() + }, + environment, + prefix, + can_be_built: true, + editable: false, + lighthouse_driver: LighthouseDriver::Vive, + ..Default::default() + } +} diff --git a/src/ui/app.rs b/src/ui/app.rs index 507e778..95f4458 100644 --- a/src/ui/app.rs +++ b/src/ui/app.rs @@ -13,6 +13,7 @@ use crate::builders::build_libsurvive::get_build_libsurvive_jobs; use crate::builders::build_mercury::get_build_mercury_job; use crate::builders::build_monado::get_build_monado_jobs; use crate::builders::build_opencomposite::get_build_opencomposite_jobs; +use crate::builders::build_openhmd::get_build_openhmd_jobs; use crate::builders::build_wivrn::get_build_wivrn_jobs; use crate::config::Config; use crate::constants::APP_NAME; @@ -21,6 +22,7 @@ use crate::dependencies::basalt_deps::get_missing_basalt_deps; use crate::dependencies::libsurvive_deps::get_missing_libsurvive_deps; use crate::dependencies::mercury_deps::get_missing_mercury_deps; use crate::dependencies::monado_deps::get_missing_monado_deps; +use crate::dependencies::openhmd_deps::get_missing_openhmd_deps; use crate::dependencies::pkexec_dep::pkexec_dep; use crate::dependencies::wivrn_deps::get_missing_wivrn_deps; use crate::file_builders::active_runtime_json::{ @@ -34,6 +36,7 @@ use crate::log_parser::MonadoLog; use crate::paths::get_ipc_file_path; use crate::profile::{Profile, XRServiceType}; use crate::profiles::lighthouse::lighthouse_profile; +use crate::profiles::openhmd::openhmd_profile; use crate::profiles::system_valve_index::system_valve_index_profile; use crate::profiles::valve_index::valve_index_profile; use crate::profiles::wivrn::wivrn_profile; @@ -229,6 +232,7 @@ impl App { valve_index_profile(), system_valve_index_profile(), wivrn_profile(), + openhmd_profile(), ]; profiles.extend(config.user_profiles.clone()); profiles.sort_unstable_by(|a, b| a.name.cmp(&b.name)); @@ -382,6 +386,10 @@ impl SimpleComponent for App { missing_deps.extend(get_missing_libsurvive_deps()); jobs.extend(get_build_libsurvive_jobs(&profile, clean_build)); } + if profile.features.openhmd.enabled { + missing_deps.extend(get_missing_openhmd_deps()); + jobs.extend(get_build_openhmd_jobs(&profile, clean_build)); + } if profile.features.basalt.enabled { missing_deps.extend(get_missing_basalt_deps()); jobs.extend(get_build_basalt_jobs(&profile, clean_build)); diff --git a/src/ui/profile_editor.rs b/src/ui/profile_editor.rs index 0aba65c..557e035 100644 --- a/src/ui/profile_editor.rs +++ b/src/ui/profile_editor.rs @@ -234,6 +234,43 @@ impl SimpleComponent for ProfileEditor { ) }, }, + add: openhmdgrp = &adw::PreferencesGroup { + set_title: "OpenHMD", + set_description: Some("Legacy driver for older Oculus HMDs\n\nWhen specifying a repository, you can set a specific git ref (branch, tag, commit...) by appending a '#' followed by the ref"), + add: { + withclones![prof]; + &switch_row( + "Enable OpenHMD", None, + model.profile.borrow().features.openhmd.enabled, + move |_, state| { + prof.borrow_mut().features.openhmd.enabled = state; + gtk::Inhibit(false) + } + ) + }, + add: { + withclones![prof]; + &path_row( + "OpenHMD Path", None, + model.profile.borrow().features.openhmd.path.clone(), + Some(init.root_win.clone()), + move |n_path| { + prof.borrow_mut().features.openhmd.path = n_path; + } + ) + }, + add: { + withclones![prof]; + &entry_row( + "OpenHMD Repo", + model.profile.borrow().features.openhmd.repo.clone().unwrap_or_default().as_str(), + move |row| { + let n_val = row.text().to_string(); + prof.borrow_mut().features.openhmd.repo = (!n_val.is_empty()).then_some(n_val); + } + ) + }, + }, add: basaltgrp = &adw::PreferencesGroup { set_title: "Basalt", set_description: Some("Camera based SLAM tracking driver\n\nWhen specifying a repository, you can set a specific git ref (branch, tag, commit...) by appending a '#' followed by the ref"),