diff --git a/README.md b/README.md index d9830f3..ee8ffb8 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,10 @@ This is still highly experimental software, while it's unlikely that anything ba Also consider that due to the unstable nature of the app, it's possible to encounter unexpected behavior that while in VR might cause motion sickness or physical injury. **Be very careful while in VR using this app!** +## Do you have a standalone/android based headset? + +Envision is built for PCVR headsets only at this moment, the recommended tool for standalone headsets is [WiVRn](https://github.com/WiVRn/WiVRn/). + --- ![](./data/icons/org.gabmus.envision.svg) diff --git a/dist/arch/PKGBUILD b/dist/arch/PKGBUILD index 47e0179..ebdc742 100644 --- a/dist/arch/PKGBUILD +++ b/dist/arch/PKGBUILD @@ -26,6 +26,8 @@ depends=( polkit base-devel jq + monado + xrizer ) makedepends=( meson @@ -33,9 +35,6 @@ makedepends=( ) optdepends=( 'libudev0-shim: steamvr_lh lighthouse driver support' - 'monado: monado support' - 'wivrn-server: wivrn support' - 'xrizer: xrizer support' 'opencomposite: opencomposite support' ) provides=(envision) diff --git a/src/builders/build_wivrn.rs b/src/builders/build_wivrn.rs deleted file mode 100644 index 4b61625..0000000 --- a/src/builders/build_wivrn.rs +++ /dev/null @@ -1,75 +0,0 @@ -use crate::{ - build_tools::{cmake::Cmake, git::Git}, - profile::Profile, - termcolor::TermColor, - ui::job_worker::job::WorkerJob, - util::{ - file_utils::rm_rf, - git_repos::{DEFAULT_WIVRN_BRANCH, DEFAULT_WIVRN_REPO}, - }, -}; -use std::{ - collections::{HashMap, VecDeque}, - path::Path, -}; - -pub fn get_build_wivrn_jobs(profile: &Profile, clean_build: bool) -> VecDeque { - let mut jobs = VecDeque::::new(); - jobs.push_back(WorkerJob::new_printer( - "Building WiVRn...", - Some(TermColor::Blue), - )); - - let git = Git { - repo: profile - .xrservice_repo - .as_ref() - .unwrap_or(&DEFAULT_WIVRN_REPO.into()) - .clone(), - dir: profile.xrservice_path.clone(), - branch: profile - .xrservice_branch - .as_ref() - .unwrap_or(&DEFAULT_WIVRN_BRANCH.into()) - .clone(), - }; - - jobs.extend(git.get_pre_build_jobs(profile.pull_on_build)); - - let build_dir = profile.xrservice_path.join("build"); - - let cmake = Cmake { - env: None, - vars: Some({ - let mut cmake_vars: HashMap = HashMap::new(); - for (k, v) in [ - ("CMAKE_EXPORT_COMPILE_COMMANDS", "ON"), - ("CMAKE_BUILD_TYPE", "RelWithDebInfo"), - ("XRT_HAVE_SYSTEM_CJSON", "NO"), - ("WIVRN_BUILD_CLIENT", "OFF"), - ("WIVRN_BUILD_WIVRNCTL", "OFF"), - ("WIVRN_USE_SYSTEM_BOOST", "OFF"), - ] { - cmake_vars.insert(k.to_string(), v.to_string()); - } - cmake_vars.insert( - "CMAKE_INSTALL_PREFIX".into(), - profile.prefix.to_string_lossy().to_string(), - ); - profile.xrservice_cmake_flags.iter().for_each(|(k, v)| { - cmake_vars.insert(k.clone(), v.clone()); - }); - cmake_vars - }), - source_dir: profile.xrservice_path.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 9d57245..9a7634e 100644 --- a/src/builders/mod.rs +++ b/src/builders/mod.rs @@ -5,5 +5,4 @@ pub mod build_monado; pub mod build_opencomposite; pub mod build_openhmd; pub mod build_vapor; -pub mod build_wivrn; pub mod build_xrizer; diff --git a/src/cmd_runner.rs b/src/cmd_runner.rs index d85ea65..37708b8 100644 --- a/src/cmd_runner.rs +++ b/src/cmd_runner.rs @@ -104,7 +104,6 @@ impl CmdRunner { Some(env), match profile.xrservice_type { XRServiceType::Monado => profile.prefix.join("bin/monado-service"), - XRServiceType::Wivrn => profile.prefix.join("bin/wivrn-server"), } .to_string_lossy() .to_string(), diff --git a/src/config.rs b/src/config.rs index 8da8e59..19d5e7c 100644 --- a/src/config.rs +++ b/src/config.rs @@ -6,7 +6,7 @@ use crate::{ profile::{OvrCompatibilityModuleType, Profile, XRServiceType}, profiles::{ lighthouse::lighthouse_profile, openhmd::openhmd_profile, simulated::simulated_profile, - survive::survive_profile, wivrn::wivrn_profile, wmr::wmr_profile, + survive::survive_profile, wmr::wmr_profile, }, util::file_utils::get_writer, }; @@ -206,7 +206,6 @@ impl Config { let mut profiles = vec![ lighthouse_profile(), survive_profile(), - wivrn_profile(), wmr_profile(), openhmd_profile(), simulated_profile(), diff --git a/src/depcheck/mod.rs b/src/depcheck/mod.rs index d8dd349..52f3fd5 100644 --- a/src/depcheck/mod.rs +++ b/src/depcheck/mod.rs @@ -5,7 +5,6 @@ pub mod libsurvive_deps; pub mod mercury_deps; pub mod monado_deps; pub mod openhmd_deps; -pub mod wivrn_deps; pub mod xrizer_deps; use crate::linux_distro::LinuxDistro; diff --git a/src/depcheck/wivrn_deps.rs b/src/depcheck/wivrn_deps.rs deleted file mode 100644 index db758f0..0000000 --- a/src/depcheck/wivrn_deps.rs +++ /dev/null @@ -1,299 +0,0 @@ -use super::{ - DepType, DepcheckResultGetMissing, Dependency, DependencyCheckResult, - common::{ - dep_cmake, dep_eigen, dep_gcc, dep_git, dep_glslang_validator, dep_gpp, dep_libdrm, - dep_libudev, dep_libx11, dep_libxcb, dep_ninja, dep_openxr, dep_vulkan_headers, - dep_vulkan_icd_loader, - }, -}; -use crate::{ - depcheck::common::{dep_libc, dep_libgl, dep_libxrandr}, - linux_distro::LinuxDistro, -}; -use std::collections::HashMap; - -fn wivrn_deps() -> Vec { - vec![ - dep_libc(), - dep_cmake(), - dep_ninja(), - dep_git(), - dep_gcc(), - dep_gpp(), - dep_libdrm(), - dep_openxr(), - dep_vulkan_icd_loader(), - dep_vulkan_headers(), - dep_libxcb(), - dep_libx11(), - dep_libxrandr(), - dep_libgl(), - Dependency { - name: "patch".into(), - dep_type: DepType::Executable, - filename: "patch".into(), - packages: HashMap::from([ - (LinuxDistro::Arch, "patch".into()), - (LinuxDistro::Debian, "patch".into()), - (LinuxDistro::Fedora, "patch".into()), - (LinuxDistro::Alpine, "patch".into()), - (LinuxDistro::Gentoo, "sys-devel/patch".into()), - (LinuxDistro::Suse, "patch".into()), - ]), - }, - Dependency { - name: "x264-dev".into(), - dep_type: DepType::Include, - filename: "x264.h".into(), - packages: HashMap::from([ - (LinuxDistro::Arch, "x264".into()), - (LinuxDistro::Debian, "libx264-dev".into()), - (LinuxDistro::Fedora, "x264-devel".into()), - (LinuxDistro::Gentoo, "media-libs/x264".into()), - (LinuxDistro::Suse, "libx264-devel".into()), - ]), - }, - Dependency { - name: "avahi".into(), - dep_type: DepType::Include, - filename: "avahi-client/client.h".into(), - packages: HashMap::from([ - (LinuxDistro::Arch, "avahi".into()), - (LinuxDistro::Debian, "libavahi-client-dev".into()), - (LinuxDistro::Fedora, "avahi-devel".into()), - (LinuxDistro::Gentoo, "net-dns/avahi".into()), - (LinuxDistro::Suse, "libavahi-devel".into()), - ]), - }, - Dependency { - name: "avahi-glib-dev".into(), - dep_type: DepType::Include, - filename: "avahi-glib/glib-malloc.h".into(), - packages: HashMap::from([ - (LinuxDistro::Arch, "avahi".into()), - (LinuxDistro::Debian, "libavahi-glib-dev".into()), - (LinuxDistro::Fedora, "avahi-glib-devel".into()), - // TODO - // (LinuxDistro::Gentoo, "".into()), - (LinuxDistro::Suse, "libavahi-glib-devel".into()), - ]), - }, - Dependency { - name: "libpipewire-dev".into(), - dep_type: DepType::Include, - filename: "pipewire-0.3/pipewire/pipewire.h".into(), - packages: HashMap::from([ - (LinuxDistro::Arch, "libpipewire".into()), - (LinuxDistro::Debian, "libpipewire-0.3-dev".into()), - (LinuxDistro::Fedora, "pipewire-devel".into()), - (LinuxDistro::Gentoo, "media-video/pipewire".into()), - (LinuxDistro::Suse, "pipewire-devel".into()), - ]), - }, - dep_eigen(), - Dependency { - name: "nlohmann-json".into(), - dep_type: DepType::Include, - filename: "nlohmann/json.hpp".into(), - packages: HashMap::from([ - (LinuxDistro::Arch, "nlohmann-json".into()), - (LinuxDistro::Debian, "nlohmann-json3-dev".into()), - (LinuxDistro::Fedora, "json-devel".into()), - (LinuxDistro::Gentoo, "dev-cpp/nlohmann_json".into()), - (LinuxDistro::Suse, "nlohmann_json-devel".into()), - ]), - }, - Dependency { - name: "libavcodec-dev".into(), - dep_type: DepType::Include, - filename: "libavcodec/avcodec.h".into(), - packages: HashMap::from([ - (LinuxDistro::Arch, "ffmpeg".into()), - (LinuxDistro::Debian, "libavcodec-dev".into()), - (LinuxDistro::Fedora, "ffmpeg-devel".into()), - (LinuxDistro::Gentoo, "media-video/ffmpeg".into()), - (LinuxDistro::Suse, "ffmpeg-6-libavcodec-devel".into()), - ]), - }, - Dependency { - name: "libavfilter-dev".into(), - dep_type: DepType::Include, - filename: "libavfilter/avfilter.h".into(), - packages: HashMap::from([ - (LinuxDistro::Arch, "ffmpeg".into()), - (LinuxDistro::Debian, "libavfilter-dev".into()), - (LinuxDistro::Fedora, "ffmpeg-devel".into()), - (LinuxDistro::Gentoo, "media-video/ffmpeg".into()), - (LinuxDistro::Suse, "ffmpeg-6-libavfilter-devel".into()), - ]), - }, - Dependency { - name: "libswscale-dev".into(), - dep_type: DepType::Include, - filename: "libswscale/swscale.h".into(), - packages: HashMap::from([ - (LinuxDistro::Arch, "ffmpeg".into()), - (LinuxDistro::Debian, "libswscale-dev".into()), - (LinuxDistro::Fedora, "ffmpeg-devel".into()), - (LinuxDistro::Gentoo, "media-video/ffmpeg".into()), - (LinuxDistro::Suse, "ffmpeg-6-libswscale-devel".into()), - ]), - }, - Dependency { - name: "libavutil-dev".into(), - dep_type: DepType::Include, - filename: "libavutil/hwcontext_vaapi.h".into(), - packages: HashMap::from([ - (LinuxDistro::Arch, "ffmpeg".into()), - (LinuxDistro::Debian, "libavutil-dev".into()), - (LinuxDistro::Fedora, "ffmpeg-devel".into()), - (LinuxDistro::Suse, "ffmpeg-6-libavutil-devel".into()), - ]), - }, - dep_glslang_validator(), - dep_libudev(), - Dependency { - name: "gstreamer".into(), - dep_type: DepType::SharedObject, - filename: "libgstreamer-1.0.so".into(), - packages: HashMap::from([ - (LinuxDistro::Arch, "gstreamer".into()), - (LinuxDistro::Debian, "libgstreamer1.0-dev".into()), - (LinuxDistro::Fedora, "gstreamer1-devel".into()), - (LinuxDistro::Gentoo, "media-libs/gstreamer".into()), - (LinuxDistro::Suse, "gstreamer-devel".into()), - ]), - }, - Dependency { - name: "gst-plugins-base-libs".into(), - dep_type: DepType::SharedObject, - filename: "pkgconfig/gstreamer-app-1.0.pc".into(), - packages: HashMap::from([ - (LinuxDistro::Arch, "gst-plugins-base-libs".into()), - ( - LinuxDistro::Debian, - "libgstreamer-plugins-base1.0-dev".into(), - ), - (LinuxDistro::Fedora, "gstreamer1-plugins-base-devel".into()), - (LinuxDistro::Gentoo, "media-libs/gst-plugins-base".into()), - (LinuxDistro::Suse, "gstreamer-plugins-base-devel".into()), - ]), - }, - Dependency { - name: "systemd-dev".into(), - dep_type: DepType::Include, - filename: "systemd/sd-daemon.h".into(), - packages: HashMap::from([ - (LinuxDistro::Arch, "systemd-libs".into()), - (LinuxDistro::Debian, "libsystemd-dev".into()), - (LinuxDistro::Fedora, "systemd-devel".into()), - (LinuxDistro::Gentoo, "sys-apps/systemd".into()), - (LinuxDistro::Suse, "systemd-devel".into()), - ]), - }, - Dependency { - name: "libva-dev".into(), - dep_type: DepType::Include, - filename: "va/va.h".into(), - packages: HashMap::from([ - (LinuxDistro::Arch, "libva".into()), - (LinuxDistro::Debian, "libva-dev".into()), - (LinuxDistro::Fedora, "libva-devel".into()), - (LinuxDistro::Gentoo, "media-libs/libva".into()), - (LinuxDistro::Suse, "libva-devel".into()), - ]), - }, - Dependency { - name: "cli11".into(), - dep_type: DepType::Include, - filename: "CLI/CLI.hpp".into(), - packages: HashMap::from([ - (LinuxDistro::Arch, "cli11".into()), - (LinuxDistro::Debian, "libcli11-dev".into()), - (LinuxDistro::Fedora, "cli11-devel".into()), - (LinuxDistro::Gentoo, "dev-cpp/cli11".into()), - (LinuxDistro::Suse, "cli11-devel".into()), - ]), - }, - Dependency { - name: "glib2-dev".into(), - dep_type: DepType::Include, - filename: "glib-2.0/glib.h".into(), - packages: HashMap::from([ - (LinuxDistro::Arch, "glib2".into()), - (LinuxDistro::Alpine, "glib-dev".into()), - (LinuxDistro::Debian, "libglib2.0-dev".into()), - (LinuxDistro::Fedora, "glib2-devel".into()), - (LinuxDistro::Suse, "glib2-devel".into()), - ]), - }, - Dependency { - name: "gdbus-codegen".into(), - dep_type: DepType::Executable, - filename: "gdbus-codegen".into(), - packages: HashMap::from([ - (LinuxDistro::Arch, "glib2-devel".into()), - (LinuxDistro::Alpine, "glib-dev".into()), - (LinuxDistro::Debian, "libglib2.0-dev".into()), - (LinuxDistro::Fedora, "glib2-devel".into()), - (LinuxDistro::Suse, "glib2-devel".into()), - ]), - }, - Dependency { - name: "openssl-dev".into(), - dep_type: DepType::Include, - filename: "openssl/ssl3.h".into(), - packages: HashMap::from([ - (LinuxDistro::Arch, "openssl".into()), - (LinuxDistro::Alpine, "openssl-dev".into()), - (LinuxDistro::Debian, "libssl-dev".into()), - (LinuxDistro::Fedora, "openssl-devel".into()), - (LinuxDistro::Suse, "openssl-devel".into()), - ]), - }, - Dependency { - name: "libnotify-dev".into(), - dep_type: DepType::Include, - filename: "libnotify/notify.h".into(), - packages: HashMap::from([ - (LinuxDistro::Arch, "libnotify".into()), - (LinuxDistro::Alpine, "libnotify-dev".into()), - (LinuxDistro::Debian, "libnotify-dev".into()), - (LinuxDistro::Fedora, "libnotify-devel".into()), - (LinuxDistro::Suse, "libnotify-devel".into()), - ]), - }, - Dependency { - name: "librsvg2-dev".into(), - dep_type: DepType::Include, - filename: "librsvg-2.0/librsvg/rsvg.h".into(), - packages: HashMap::from([ - (LinuxDistro::Arch, "librsvg".into()), - (LinuxDistro::Alpine, "librsvg-dev".into()), - (LinuxDistro::Debian, "librsvg2-dev".into()), - (LinuxDistro::Fedora, "librsvg2-devel".into()), - (LinuxDistro::Suse, "librsvg-devel".into()), - ]), - }, - Dependency { - name: "libarchive-dev".into(), - dep_type: DepType::Include, - filename: "archive.h".into(), - packages: HashMap::from([ - (LinuxDistro::Arch, "libarchive".into()), - (LinuxDistro::Alpine, "libarchive-dev".into()), - (LinuxDistro::Debian, "libarchive-dev".into()), - (LinuxDistro::Fedora, "libarchive-devel".into()), - (LinuxDistro::Suse, "libarchive-devel".into()), - ]), - }, - ] -} - -pub fn check_wivrn_deps() -> Vec { - Dependency::check_many(wivrn_deps()) -} - -pub fn get_missing_wivrn_deps() -> Vec { - check_wivrn_deps().filter_missing_deps() -} diff --git a/src/device_prober.rs b/src/device_prober.rs index 1e8c1cf..12c029f 100644 --- a/src/device_prober.rs +++ b/src/device_prober.rs @@ -1,6 +1,6 @@ use crate::{ profile::Profile, - profiles::{lighthouse::lighthouse_profile, wivrn::wivrn_profile, wmr::wmr_profile}, + profiles::{lighthouse::lighthouse_profile, wmr::wmr_profile}, }; use rusb::UsbContext; use std::fmt::Display; @@ -105,16 +105,6 @@ impl PhysicalXRDevice { Self::VarjoVR2 => Some(lighthouse_profile()), Self::VarjoVR3 => Some(lighthouse_profile()), Self::BigscreenBeyond => Some(lighthouse_profile()), - Self::OculusQuest => Some(wivrn_profile()), - Self::OculusQuest2 => Some(wivrn_profile()), - Self::OculusQuestPro => Some(wivrn_profile()), - Self::PicoVRGoblin => Some(wivrn_profile()), - Self::PicoNeoCV => Some(wivrn_profile()), - Self::PicoG24K => Some(wivrn_profile()), - Self::PicoNeo3Pro => Some(wivrn_profile()), - Self::Pico4 => Some(wivrn_profile()), - Self::LynxR1 => Some(wivrn_profile()), - Self::ViveFocus3 => Some(wivrn_profile()), Self::DellVisor => Some(wmr_profile()), // Self::AcerAH101 => Some(wmr_profile()), Self::HPWMR => Some(wmr_profile()), diff --git a/src/file_builders/mod.rs b/src/file_builders/mod.rs index 33c9829..add8e8b 100644 --- a/src/file_builders/mod.rs +++ b/src/file_builders/mod.rs @@ -1,6 +1,3 @@ pub mod active_runtime_json; pub mod monado_autorun; pub mod openvrpaths_vrpath; -pub mod wayvr_dashboard_config; -pub mod wivrn_config; -pub mod wivrn_encoder_presets; diff --git a/src/file_builders/wayvr_dashboard_config.rs b/src/file_builders/wayvr_dashboard_config.rs deleted file mode 100644 index 6e9315c..0000000 --- a/src/file_builders/wayvr_dashboard_config.rs +++ /dev/null @@ -1,13 +0,0 @@ -use serde::{Deserialize, Serialize}; - -#[derive(Debug, Clone, Deserialize, Serialize)] -pub struct WayVrDashboardConfigFragmentInner { - pub exec: String, - pub args: Option, - pub env: Option>, -} - -#[derive(Debug, Clone, Deserialize, Serialize)] -pub struct WayVrDashboardConfigFragment { - pub dashboard: WayVrDashboardConfigFragmentInner, -} diff --git a/src/file_builders/wivrn_config.rs b/src/file_builders/wivrn_config.rs deleted file mode 100644 index e127172..0000000 --- a/src/file_builders/wivrn_config.rs +++ /dev/null @@ -1,234 +0,0 @@ -use crate::{ - util::file_utils::{deserialize_file, get_writer}, - xdg::XDG_CONFIG_HOME, -}; -use serde::{Deserialize, Serialize}; -use serde_json::{Map, Value}; -use std::{ - fmt::Display, - path::{Path, PathBuf}, - slice::Iter, -}; - -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -#[serde(rename_all = "lowercase")] -pub enum Encoder { - X264, - Nvenc, - Vaapi, - Vulkan, -} - -impl Display for Encoder { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_str(match self { - Self::X264 => "x264", - Self::Nvenc => "NVEnc", - Self::Vaapi => "VAAPI", - Self::Vulkan => "Vulkan", - }) - } -} - -impl Encoder { - pub fn iter() -> Iter<'static, Self> { - [Self::X264, Self::Nvenc, Self::Vaapi, Self::Vulkan].iter() - } - - pub fn as_vec() -> Vec { - vec![Self::X264, Self::Nvenc, Self::Vaapi, Self::Vulkan] - } -} - -impl From<&Encoder> for u32 { - fn from(value: &Encoder) -> Self { - match value { - Encoder::X264 => 0, - Encoder::Nvenc => 1, - Encoder::Vaapi => 2, - Encoder::Vulkan => 3, - } - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -#[serde(rename_all = "lowercase")] -pub enum Codec { - H264, - H265, - AV1, -} - -impl Display for Codec { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_str(match self { - Self::H264 => "h264", - Self::H265 => "h265", - Self::AV1 => "av1", - }) - } -} - -impl Codec { - pub fn iter() -> Iter<'static, Self> { - [Self::H264, Self::H265, Self::AV1].iter() - } - - pub fn as_vec() -> Vec { - vec![Self::H264, Self::H265, Self::AV1] - } -} - -impl From<&Codec> for u32 { - fn from(value: &Codec) -> Self { - match value { - Codec::H264 => 0, - Codec::H265 => 1, - Codec::AV1 => 2, - } - } -} - -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] -pub struct WivrnConfEncoder { - pub encoder: Encoder, - pub codec: Codec, - #[serde(skip_serializing_if = "Option::is_none")] - pub width: Option, - #[serde(skip_serializing_if = "Option::is_none")] - pub height: Option, - #[serde(skip_serializing_if = "Option::is_none")] - pub offset_x: Option, - #[serde(skip_serializing_if = "Option::is_none")] - pub offset_y: Option, - #[serde(skip_serializing_if = "Option::is_none")] - pub group: Option, - /// contains unknown fields - #[serde(flatten)] - pub other: Map, -} - -impl Default for WivrnConfEncoder { - fn default() -> Self { - Self { - encoder: Encoder::X264, - codec: Codec::H264, - width: Some(1.0), - height: Some(1.0), - offset_x: Some(0.0), - offset_y: Some(0.0), - group: None, - other: Map::default(), - } - } -} - -/// An application to start when connection with the headset is established, -/// can be a string or an array of strings if parameters need to be provided. -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] -#[serde(untagged)] -pub enum WivrnConfigApplication { - Str(String), - StrArr(Vec), -} - -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] -pub struct WivrnConfig { - #[serde(skip_serializing_if = "Option::is_none")] - pub scale: Option<[f32; 2]>, - #[serde(skip_serializing_if = "Option::is_none")] - pub bitrate: Option, - #[serde(default, skip_serializing_if = "Vec::is_empty")] - pub encoders: Vec, - #[serde(default, rename = "bit-depth")] - pub bit_depth: u32, - #[serde(skip_serializing_if = "Option::is_none")] - pub application: Option, - #[serde(default, rename = "tcp-only")] - pub tcp_only: bool, - #[serde(default, rename = "use-steamvr-lh")] - pub use_steamvr_lh: bool, - /// contains unknown fields - #[serde(flatten)] - other: Map, -} - -impl Default for WivrnConfig { - fn default() -> Self { - Self { - scale: Some([0.5, 0.5]), - bitrate: Some(50000000), - encoders: vec![], - bit_depth: 8, - application: None, - tcp_only: false, - use_steamvr_lh: false, - other: Map::default(), - } - } -} - -fn get_wivrn_config_path() -> PathBuf { - XDG_CONFIG_HOME.join("wivrn/config.json") -} - -fn get_wivrn_config_from_path(path: &Path) -> Option { - deserialize_file(path) -} - -pub fn get_wivrn_config() -> WivrnConfig { - get_wivrn_config_from_path(&get_wivrn_config_path()).unwrap_or_default() -} - -fn dump_wivrn_config_to_path(config: &WivrnConfig, path: &Path) { - let writer = get_writer(path).expect("Unable to save WiVRn config"); - serde_json::to_writer_pretty(writer, config).expect("Unable to save WiVRn config"); -} - -pub fn dump_wivrn_config(config: &WivrnConfig) { - dump_wivrn_config_to_path(config, &get_wivrn_config_path()); -} - -#[cfg(test)] -mod tests { - use std::path::Path; - - use crate::file_builders::wivrn_config::{Codec, Encoder, WivrnConfigApplication}; - - use super::get_wivrn_config_from_path; - - #[test] - fn can_read_wivrn_config() { - let conf = get_wivrn_config_from_path(Path::new("./test/files/wivrn_config.json")) - .expect("Couldn't find wivrn config"); - assert_eq!(conf.scale, Some([0.8, 0.8])); - assert_eq!(conf.encoders.len(), 1); - assert_eq!(conf.encoders.first().unwrap().encoder, Encoder::X264); - assert_eq!(conf.encoders.first().unwrap().codec, Codec::H264); - assert_eq!(conf.bitrate, Some(100000000)); - assert_eq!(conf.encoders.first().unwrap().width, Some(1.0)); - assert_eq!(conf.encoders.first().unwrap().height, Some(1.0)); - assert_eq!(conf.encoders.first().unwrap().offset_x, Some(0.0)); - assert_eq!(conf.encoders.first().unwrap().offset_y, Some(0.0)); - assert_eq!( - conf.application, - Some(WivrnConfigApplication::Str("foobar".into())) - ); - assert!(!conf.tcp_only); - assert!( - serde_json::to_string(&conf) - .unwrap() - .contains("\"extraneous\":\"field\",\"other\":{\"weird\":[\"stuff\"]}") - ); - let conf = get_wivrn_config_from_path(Path::new("./test/files/wivrn_config2.json")) - .expect("Couln't find wivrn config 2"); - assert_eq!( - conf.application, - Some(WivrnConfigApplication::StrArr(vec![ - "foobar".into(), - "baz".into() - ])) - ); - assert!(conf.tcp_only); - } -} diff --git a/src/file_builders/wivrn_encoder_presets.rs b/src/file_builders/wivrn_encoder_presets.rs deleted file mode 100644 index 4aede0f..0000000 --- a/src/file_builders/wivrn_encoder_presets.rs +++ /dev/null @@ -1,84 +0,0 @@ -use super::wivrn_config::{Codec, Encoder, WivrnConfEncoder}; -use lazy_static::lazy_static; - -fn wivrn_encoder_presets() -> Vec<(&'static str, &'static str, Vec)> { - vec![ - ( - "3x VAAPI", - "Split encoding in 3 slices using VAAPI h265 hardware acceleration.", - vec![ - WivrnConfEncoder { - encoder: Encoder::Vaapi, - width: Some(0.5), - height: Some(0.25), - offset_x: Some(0.0), - offset_y: Some(0.0), - group: Some(0), - codec: Codec::H265, - ..Default::default() - }, - WivrnConfEncoder { - encoder: Encoder::Vaapi, - width: Some(0.5), - height: Some(0.75), - offset_x: Some(0.0), - offset_y: Some(0.25), - group: Some(0), - codec: Codec::H265, - ..Default::default() - }, - WivrnConfEncoder { - encoder: Encoder::Vaapi, - width: Some(0.5), - height: Some(1.0), - offset_x: Some(0.5), - offset_y: Some(0.0), - group: Some(0), - codec: Codec::H265, - ..Default::default() - }, - ], - ), - ( - "2x VAAPI + 1 Software", - "Split encoding in 3 slices, half the image using VAAPI h265 hardware acceleration, the other half using h264 software encoding. Lowest possible latency at the cost of CPU usage and some quality degradation.", - vec![ - WivrnConfEncoder { - encoder: Encoder::Vaapi, - width: Some(0.5), - height: Some(0.25), - offset_x: Some(0.0), - offset_y: Some(0.0), - group: Some(0), - codec: Codec::H265, - ..Default::default() - }, - WivrnConfEncoder { - encoder: Encoder::Vaapi, - width: Some(0.5), - height: Some(0.75), - offset_x: Some(0.0), - offset_y: Some(0.25), - group: Some(0), - codec: Codec::H265, - ..Default::default() - }, - WivrnConfEncoder { - encoder: Encoder::X264, - width: Some(0.5), - height: Some(1.0), - offset_x: Some(0.5), - offset_y: Some(0.0), - group: Some(1), - codec: Codec::H264, - ..Default::default() - }, - ], - ), - ] -} - -lazy_static! { - pub static ref WIVRN_ENCODER_PRESETS: Vec<(&'static str, &'static str, Vec)> = - wivrn_encoder_presets(); -} diff --git a/src/main.rs b/src/main.rs index 38a977a..27442d5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -55,7 +55,6 @@ pub mod termcolor; pub mod ui; pub mod util; pub mod vulkaninfo; -pub mod wivrn_dbus; pub mod xdg; pub mod xr_clients; pub mod xr_devices; diff --git a/src/paths.rs b/src/paths.rs index 481d946..7fce365 100644 --- a/src/paths.rs +++ b/src/paths.rs @@ -20,10 +20,6 @@ pub fn data_monado_path() -> PathBuf { get_data_dir().join("monado") } -pub fn data_wivrn_path() -> PathBuf { - get_data_dir().join("wivrn") -} - pub fn data_libsurvive_path() -> PathBuf { get_data_dir().join("libsurvive") } @@ -36,10 +32,6 @@ pub fn data_basalt_path() -> PathBuf { get_data_dir().join("basalt") } -pub fn wivrn_apk_download_path() -> PathBuf { - get_cache_dir().join("wivrn.apk") -} - pub const SYSTEM_PREFIX: &str = "/usr"; lazy_static! { diff --git a/src/profile.rs b/src/profile.rs index 20f2019..4e0fa61 100644 --- a/src/profile.rs +++ b/src/profile.rs @@ -5,19 +5,19 @@ use crate::{ Dependency, basalt_deps::get_missing_basalt_deps, libsurvive_deps::get_missing_libsurvive_deps, mercury_deps::get_missing_mercury_deps, monado_deps::get_missing_monado_deps, openhmd_deps::get_missing_openhmd_deps, - wivrn_deps::get_missing_wivrn_deps, xrizer_deps::get_missing_xrizer_deps, + xrizer_deps::get_missing_xrizer_deps, }, file_builders::active_runtime_json::ActiveRuntime, paths::{BWRAP_SYSTEM_PREFIX, SYSTEM_PREFIX, get_data_dir}, - profiles::system_profile::{monado_dep, wivrn_dep}, + profiles::system_profile::monado_dep, util::{ file_utils::{deserialize_file, get_writer}, git_repos::{ DEFAULT_BASALT_BRANCH, DEFAULT_BASALT_REPO, DEFAULT_LIBSURVIVE_BRANCH, DEFAULT_LIBSURVIVE_REPO, DEFAULT_MONADO_BRANCH, DEFAULT_MONADO_REPO, DEFAULT_OPENCOMPOSITE_BRANCH, DEFAULT_OPENCOMPOSITE_REPO, DEFAULT_OPENHMD_BRANCH, - DEFAULT_OPENHMD_REPO, DEFAULT_VAPOR_BRANCH, DEFAULT_VAPOR_REPO, DEFAULT_WIVRN_BRANCH, - DEFAULT_WIVRN_REPO, DEFAULT_XRIZER_BRANCH, DEFAULT_XRIZER_REPO, + DEFAULT_OPENHMD_REPO, DEFAULT_VAPOR_BRANCH, DEFAULT_VAPOR_REPO, DEFAULT_XRIZER_BRANCH, + DEFAULT_XRIZER_REPO, }, }, xdg::XDG, @@ -39,18 +39,16 @@ use uuid::Uuid; pub enum XRServiceType { #[default] Monado, - Wivrn, } impl XRServiceType { pub fn iter() -> Iter<'static, Self> { - [Self::Monado, Self::Wivrn].iter() + [Self::Monado].iter() } pub fn binary_name(&self) -> &'static str { match self { XRServiceType::Monado => "monado-service", - XRServiceType::Wivrn => "wivrn-server", } } @@ -58,7 +56,6 @@ impl XRServiceType { pub fn libopenxr_path(&self) -> &'static str { match self { Self::Monado => "libopenxr_monado.so", - Self::Wivrn => "wivrn/libopenxr_wivrn.so", } } @@ -66,14 +63,12 @@ impl XRServiceType { pub fn libmonado_path(&self) -> &'static str { match self { Self::Monado => "libmonado.so", - Self::Wivrn => "wivrn/libmonado_wivrn.so", } } pub fn openxr_json_rel_path(&self) -> &'static str { match self { Self::Monado => "share/openxr/1/openxr_monado.json", - Self::Wivrn => "share/openxr/1/openxr_wivrn.json", } } @@ -82,7 +77,6 @@ impl XRServiceType { .expect("XDG runtime directory is not available") .join(match self { XRServiceType::Monado => "monado_comp_ipc", - XRServiceType::Wivrn => "wivrn/comp_ipc", }) } } @@ -91,7 +85,6 @@ impl From<&str> for XRServiceType { fn from(s: &str) -> Self { match s.trim().to_lowercase().as_str() { "monado" => Self::Monado, - "wivrn" => Self::Wivrn, _ => Self::Monado, } } @@ -101,7 +94,6 @@ impl From for XRServiceType { fn from(i: u32) -> Self { match i { 0 => Self::Monado, - 1 => Self::Wivrn, _ => panic!("XRServiceType index out of bounds"), } } @@ -111,7 +103,6 @@ impl From<&XRServiceType> for u32 { fn from(value: &XRServiceType) -> Self { match value { XRServiceType::Monado => 0, - XRServiceType::Wivrn => 1, } } } @@ -120,7 +111,6 @@ impl Display for XRServiceType { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.write_str(match self { Self::Monado => "Monado", - Self::Wivrn => "WiVRn", }) } } @@ -513,7 +503,6 @@ impl Profile { }, runtime = match self.xrservice_type { XRServiceType::Monado => "monado", - XRServiceType::Wivrn => "wivrn", } ) } @@ -537,9 +526,7 @@ impl Profile { if self.is_system_profile { self.env_vars_full() } else { - vec![ - "PRESSURE_VESSEL_FILESYSTEMS_RW=\"$XDG_RUNTIME_DIR/wivrn_comp_ipc:$XDG_RUNTIME_DIR/wivrn/comp_ipc:$XDG_RUNTIME_DIR/monado_comp_ipc\"".into(), - ] + vec!["PRESSURE_VESSEL_FILESYSTEMS_RW=\"$XDG_RUNTIME_DIR/monado_comp_ipc\"".into()] } } @@ -707,7 +694,6 @@ impl Profile { config.and_then(|config| { match config.global_preferences.xrservice_type { XRServiceType::Monado => monado_dep(), - XRServiceType::Wivrn => wivrn_dep(), } .find_path() }) @@ -778,7 +764,6 @@ impl Profile { } else { missing_deps.extend(match self.xrservice_type { XRServiceType::Monado => get_missing_monado_deps(), - XRServiceType::Wivrn => get_missing_wivrn_deps(), }); if self.features.libsurvive.enabled { missing_deps.extend(get_missing_libsurvive_deps()); @@ -812,7 +797,6 @@ impl Profile { .as_deref() .unwrap_or(match self.xrservice_type { XRServiceType::Monado => DEFAULT_MONADO_REPO, - XRServiceType::Wivrn => DEFAULT_WIVRN_REPO, }) .into(), dir: self.xrservice_path.clone(), @@ -821,7 +805,6 @@ impl Profile { .as_deref() .unwrap_or(match self.xrservice_type { XRServiceType::Monado => DEFAULT_MONADO_BRANCH, - XRServiceType::Wivrn => DEFAULT_WIVRN_BRANCH, }) .into(), } diff --git a/src/profiles/mod.rs b/src/profiles/mod.rs index 26fe9f6..5fd56f5 100644 --- a/src/profiles/mod.rs +++ b/src/profiles/mod.rs @@ -3,5 +3,4 @@ pub mod openhmd; pub mod simulated; pub mod survive; pub mod system_profile; -pub mod wivrn; pub mod wmr; diff --git a/src/profiles/system_profile.rs b/src/profiles/system_profile.rs index 23d5ba1..b8ba620 100644 --- a/src/profiles/system_profile.rs +++ b/src/profiles/system_profile.rs @@ -18,15 +18,6 @@ pub fn monado_dep() -> Dependency { } } -pub fn wivrn_dep() -> Dependency { - Dependency { - name: "wivrn".into(), - dep_type: DepType::Executable, - filename: XRServiceType::Wivrn.binary_name().into(), - packages: HashMap::default(), - } -} - /// will generate a system profile on the fly pub fn system_profile(config: &Config) -> Profile { Profile { diff --git a/src/profiles/wivrn.rs b/src/profiles/wivrn.rs deleted file mode 100644 index 8ee0036..0000000 --- a/src/profiles/wivrn.rs +++ /dev/null @@ -1,41 +0,0 @@ -use crate::{ - constants::APP_NAME, - paths::{data_ovr_comp_path, data_wivrn_path, get_data_dir}, - profile::{ - Profile, ProfileFeatures, ProfileOvrCompatibilityModule, XRServiceType, - prepare_ld_library_path, - }, - ui::job_worker::internal_worker::LAUNCH_OPTS_CMD_PLACEHOLDER, -}; -use std::collections::HashMap; - -pub fn wivrn_profile() -> Profile { - let data_dir = get_data_dir(); - let prefix = data_dir.join("prefixes/wivrn_default"); - let mut environment: HashMap = HashMap::new(); - environment.insert("LD_LIBRARY_PATH".into(), prepare_ld_library_path(&prefix)); - environment.insert("XRT_DEBUG_GUI".into(), "1".into()); - environment.insert("XRT_CURATED_GUI".into(), "1".into()); - environment.insert("U_PACING_APP_USE_MIN_FRAME_PERIOD".into(), "1".into()); - Profile { - uuid: "wivrn-default".into(), - name: format!("WiVRn - {APP_NAME} Default"), - xrservice_path: data_wivrn_path(), - xrservice_type: XRServiceType::Wivrn, - ovr_comp: ProfileOvrCompatibilityModule { - path: data_ovr_comp_path(), - ..Default::default() - }, - features: ProfileFeatures { - ..Default::default() - }, - xrservice_launch_options: format!( - "{LAUNCH_OPTS_CMD_PLACEHOLDER} --no-instructions --no-manage-active-runtime" - ), - environment, - prefix, - is_system_profile: false, - editable: false, - ..Default::default() - } -} diff --git a/src/ui/app.rs b/src/ui/app.rs index a6cbeee..c013ca8 100644 --- a/src/ui/app.rs +++ b/src/ui/app.rs @@ -14,15 +14,13 @@ use super::{ libsurvive_setup_window::{LibsurviveSetupMsg, LibsurviveSetupWindow}, main_view::{MainView, MainViewInit, MainViewMsg, MainViewOutMsg}, util::{copiable_code_snippet, copy_text, open_with_default_handler}, - wivrn_conf_editor::{WivrnConfEditor, WivrnConfEditorInit, WivrnConfEditorMsg}, }; use crate::{ builders::{ build_basalt::get_build_basalt_jobs, build_libsurvive::get_build_libsurvive_jobs, build_mercury::get_build_mercury_jobs, build_monado::get_build_monado_jobs, build_opencomposite::get_build_opencomposite_jobs, build_openhmd::get_build_openhmd_jobs, - build_vapor::get_build_vapor_jobs, build_wivrn::get_build_wivrn_jobs, - build_xrizer::get_build_xrizer_jobs, + build_vapor::get_build_vapor_jobs, build_xrizer::get_build_xrizer_jobs, }, config::Config, constants::APP_NAME, @@ -58,7 +56,6 @@ use crate::{ rm_rf, setcap_cap_sys_nice_eip, setcap_cap_sys_nice_eip_cmd, verify_cap_sys_nice_eip, }, vulkaninfo::VulkanInfo, - wivrn_dbus, xr_clients::XRClient, xr_devices::XRDevice, }; @@ -96,9 +93,7 @@ pub struct App { profiles: Vec, libmonado: Option>, - wivrn_conf_editor: Option>, skip_depcheck: bool, - configure_wivrn_action: gtk::gio::SimpleAction, build_profile_action: gtk::gio::SimpleAction, clean_build_profile_action: gtk::gio::SimpleAction, openxr_prober_worker: Option, @@ -140,11 +135,9 @@ pub enum Msg { DebugOpenPrefix, DebugOpenData, DebugCopyEnvVars, - OpenWivrnConfig, HandleCommandLine(CmdLineOpts), StartProber, OnProberExit(bool), - WivrnCheckPairMode, OpenPreferences, OnPreferencesWindowClose(Config), ShowThemeManager, @@ -492,32 +485,6 @@ impl AsyncComponent for App { } } } - if xrservice_worker_is_alive - && self.get_selected_profile().xrservice_type == XRServiceType::Wivrn - { - // is in pairing mode? - sender.input(Msg::WivrnCheckPairMode); - } - } - Msg::WivrnCheckPairMode => { - if self.get_selected_profile().xrservice_type == XRServiceType::Wivrn { - match wivrn_dbus::is_pairing_mode().await { - Ok(state) => { - self.main_view - .sender() - .emit(MainViewMsg::SetWivrnPairingMode(state)); - self.main_view - .sender() - .emit(MainViewMsg::SetWivrnSupportsPairing(true)); - } - Err(e) => { - error!("failed to get wivrn pairing mode: {e:?}"); - self.main_view - .sender() - .emit(MainViewMsg::SetWivrnSupportsPairing(false)); - } - }; - } } Msg::EnableDebugViewChanged(val) => { self.config.debug_view_enabled = val; @@ -719,7 +686,6 @@ impl AsyncComponent for App { } jobs.extend(match profile.xrservice_type { XRServiceType::Monado => get_build_monado_jobs(&profile, clean_build), - XRServiceType::Wivrn => get_build_wivrn_jobs(&profile, clean_build), }); jobs.extend(match profile.ovr_comp.mod_type { OvrCompatibilityModuleType::Opencomposite => { @@ -977,8 +943,6 @@ impl AsyncComponent for App { } } Msg::ProfileSelected(prof) => { - self.configure_wivrn_action - .set_enabled(prof.xrservice_type == XRServiceType::Wivrn); if !prof.is_system_profile { self.config.selected_profile_uuid = prof.uuid.clone(); self.config.save(); @@ -1020,15 +984,6 @@ impl AsyncComponent for App { Msg::DebugCopyEnvVars => { copy_text(&self.get_selected_profile().env_vars_full().join(" ")); } - Msg::OpenWivrnConfig => { - let editor = WivrnConfEditor::builder() - .launch(WivrnConfEditorInit { - root_win: self.app_win.clone().upcast::(), - }) - .detach(); - editor.emit(WivrnConfEditorMsg::Present); - self.wivrn_conf_editor = Some(editor); - } Msg::HandleCommandLine(opts) => { if let Some(prof_uuid) = opts.profile_uuid && let Some(index) = self.profiles.iter().position(|p| p.uuid == prof_uuid) @@ -1254,19 +1209,6 @@ impl AsyncComponent for App { ); // this bypasses the macro because I need the underlying gio action // to enable/disable it in update() - let configure_wivrn_action = { - let action = RelmAction::::new_stateless(clone!( - #[strong] - sender, - move |_| { - sender.input(Msg::OpenWivrnConfig); - } - )); - let ret = action.gio_action().clone(); - actions.add_action(action); - ret.set_enabled(false); - ret - }; let build_profile_action = { let action = RelmAction::::new_stateless(clone!( #[strong] @@ -1374,9 +1316,7 @@ impl AsyncComponent for App { monado_gui_worker: None, restart_xrservice: false, libmonado: None, - wivrn_conf_editor: None, skip_depcheck: false, - configure_wivrn_action, build_profile_action, clean_build_profile_action, openxr_prober_worker: None, @@ -1456,7 +1396,6 @@ new_stateless_action!(pub BuildProfileAction, AppActionGroup, "buildprofile"); new_stateless_action!(pub BuildProfileCleanAction, AppActionGroup, "buildprofileclean"); new_stateless_action!(pub QuitAction, AppActionGroup, "quit"); new_stateful_action!(pub DebugViewToggleAction, AppActionGroup, "debugviewtoggle", (), bool); -new_stateless_action!(pub ConfigureWivrnAction, AppActionGroup, "configurewivrn"); new_stateless_action!(pub PreferencesAction, AppActionGroup, "preferences"); new_stateless_action!(pub ThemeManagerAction, AppActionGroup, "thememanager"); diff --git a/src/ui/factories/mod.rs b/src/ui/factories/mod.rs index c399ff1..97195f4 100644 --- a/src/ui/factories/mod.rs +++ b/src/ui/factories/mod.rs @@ -1,4 +1,3 @@ pub mod client_row_factory; pub mod device_row_factory; pub mod env_var_row_factory; -pub mod wivrn_encoder_group_factory; diff --git a/src/ui/factories/wivrn_encoder_group_factory.rs b/src/ui/factories/wivrn_encoder_group_factory.rs deleted file mode 100644 index 7b3e35c..0000000 --- a/src/ui/factories/wivrn_encoder_group_factory.rs +++ /dev/null @@ -1,208 +0,0 @@ -#![allow(unused_assignments)] // vars named in view! macro are not correctly recognized as used - -use crate::{ - file_builders::wivrn_config::{Codec, Encoder, WivrnConfEncoder}, - ui::{ - SENDER_IO_ERR_MSG, - preference_rows::{combo_row, spin_row}, - }, -}; -use relm4::{AsyncFactorySender, adw::prelude::*, factory::AsyncFactoryComponent, prelude::*}; -use uuid::Uuid; - -#[derive(Debug)] -pub struct WivrnEncoderModel { - pub encoder_conf: WivrnConfEncoder, - pub uid: String, -} - -#[derive(Debug)] -pub enum WivrnEncoderModelMsg { - EncoderChanged(u32), - CodecChanged(u32), - WidthChanged(Option), - HeightChanged(Option), - OffsetXChanged(Option), - OffsetYChanged(Option), - GroupChanged(Option), - Delete, -} - -#[derive(Debug)] -pub enum WivrnEncoderModelOutMsg { - Delete(String), -} - -#[derive(Debug, Default)] -pub struct WivrnEncoderModelInit { - pub encoder_conf: Option, -} - -#[relm4::factory(async pub)] -impl AsyncFactoryComponent for WivrnEncoderModel { - type Init = WivrnEncoderModelInit; - type Input = WivrnEncoderModelMsg; - type Output = WivrnEncoderModelOutMsg; - type CommandOutput = (); - type ParentWidget = adw::PreferencesPage; - - view! { - root = adw::PreferencesGroup { - set_title: "Encoder", - #[wrap(Some)] - set_header_suffix: delete_btn = >k::Button { - set_label: "Delete", - add_css_class: "destructive-action", - connect_clicked[sender] => move |_| { - sender.input(Self::Input::Delete) - }, - }, - add: encoder_combo = &combo_row( - "Encoder", - Some("x264: CPU based h264 encoding\nNVEnc: Nvidia GPU encoding\nVAAPI: Intel or AMD GPU encoding\nVulkan: Vulkan Video encoding (All GPUs, H264/H265 only)"), - &self.encoder_conf.encoder.to_string(), - Encoder::iter().map(Encoder::to_string).collect::>(), - { - let sender = sender.clone(); - move |row| { - sender.input(Self::Input::EncoderChanged(row.selected())); - } - } - ) -> adw::ComboRow, - add: codec_combo = &combo_row( - "Codec", - None, - &self.encoder_conf.codec.to_string(), - Codec::iter().map(Codec::to_string).collect::>(), - { - let sender = sender.clone(); - move |row| { - sender.input(Self::Input::CodecChanged(row.selected())); - } - } - ) -> adw::ComboRow, - add: width_row = &spin_row( - "Width", - None, - self.encoder_conf.width.unwrap_or(1.0).into(), - 0.0, - 1.0, - 0.01, - { - let sender = sender.clone(); - move |adj| { - sender.input(Self::Input::WidthChanged( - Some(adj.value() as f32) - )); - } - } - ) -> adw::SpinRow, - add: height_row = &spin_row( - "Height", - None, - self.encoder_conf.height.unwrap_or(1.0).into(), - 0.0, - 1.0, - 0.01, - { - let sender = sender.clone(); - move |adj| { - sender.input(Self::Input::HeightChanged( - Some(adj.value() as f32) - )); - } - } - ) -> adw::SpinRow, - add: offset_x_row = &spin_row( - "Offset X", - None, - self.encoder_conf.offset_x.unwrap_or(0.0).into(), - 0.0, - 1.0, - 0.01, - { - let sender = sender.clone(); - move |adj| { - sender.input(Self::Input::OffsetXChanged( - Some(adj.value() as f32) - )); - } - } - ) -> adw::SpinRow, - add: offset_y_row = &spin_row( - "Offset Y", - None, - self.encoder_conf.offset_y.unwrap_or(0.0).into(), - 0.0, - 1.0, - 0.01, - { - let sender = sender.clone(); - move |adj| { - sender.input(Self::Input::OffsetYChanged( - Some(adj.value() as f32) - )); - } - } - ) -> adw::SpinRow, - add: group_row = &spin_row( - "Group", - None, - self.encoder_conf.group.unwrap_or(0).into(), - 0.0, - 99999.0, - 1.0, - { - let sender = sender.clone(); - move |adj| { - sender.input(Self::Input::GroupChanged( - Some(adj.value().trunc() as i32) - )); - } - } - ) -> adw::SpinRow, - } - } - - async fn update(&mut self, message: Self::Input, sender: AsyncFactorySender) { - match message { - Self::Input::EncoderChanged(idx) => { - self.encoder_conf.encoder = Encoder::as_vec().get(idx as usize).unwrap().clone(); - } - Self::Input::CodecChanged(idx) => { - self.encoder_conf.codec = Codec::as_vec().get(idx as usize).unwrap().clone(); - } - Self::Input::WidthChanged(val) => { - self.encoder_conf.width = val; - } - Self::Input::HeightChanged(val) => { - self.encoder_conf.height = val; - } - Self::Input::OffsetXChanged(val) => { - self.encoder_conf.offset_x = val; - } - Self::Input::OffsetYChanged(val) => { - self.encoder_conf.offset_y = val; - } - Self::Input::GroupChanged(val) => { - self.encoder_conf.group = val; - } - Self::Input::Delete => { - sender - .output(Self::Output::Delete(self.uid.clone())) - .expect(SENDER_IO_ERR_MSG); - } - } - } - - async fn init_model( - init: Self::Init, - _index: &DynamicIndex, - _sender: AsyncFactorySender, - ) -> Self { - Self { - encoder_conf: init.encoder_conf.unwrap_or_default(), - uid: Uuid::new_v4().to_string(), - } - } -} diff --git a/src/ui/install_wivrn_box.rs b/src/ui/install_wivrn_box.rs deleted file mode 100644 index 839c703..0000000 --- a/src/ui/install_wivrn_box.rs +++ /dev/null @@ -1,286 +0,0 @@ -use super::{ADB_ERR_NO_DEV, alert::alert}; -use crate::{ - async_process::async_process, - depcheck::common::dep_adb, - downloader::{cache_file, cache_file_path}, - profile::{Profile, XRServiceType}, -}; -use gtk::prelude::*; -use relm4::{new_action_group, new_stateless_action, prelude::*}; -use std::fs::remove_file; -use tracing::error; - -const WIVRN_LATEST_RELEASE_APK_URL: &str = - "https://github.com/WiVRn/WiVRn/releases/latest/download/WiVRn-release.apk"; - -#[derive(Debug)] -enum GetWivrnApkRefErr { - NotWivrn, - RepoDirNotFound, - RepoManipulationFailed(git2::Error), -} - -#[derive(Debug, Clone)] -enum WivrnApkRef { - Tag(String), - Commit(String), -} - -fn get_wivrn_apk_ref(p: &Profile) -> Result { - if p.xrservice_type != XRServiceType::Wivrn { - Err(GetWivrnApkRefErr::NotWivrn) - } else if !p.xrservice_path.is_dir() { - Err(GetWivrnApkRefErr::RepoDirNotFound) - } else { - let repo = git2::Repository::open(&p.xrservice_path) - .map_err(GetWivrnApkRefErr::RepoManipulationFailed)?; - if let Ok(tag) = repo - .describe( - git2::DescribeOptions::new() - .describe_tags() - .max_candidates_tags(0), - ) - .and_then(|d| d.format(None)) - { - Ok(WivrnApkRef::Tag(tag)) - } else { - Ok(WivrnApkRef::Commit( - repo.head() - .map_err(GetWivrnApkRefErr::RepoManipulationFailed)? - .peel_to_commit() - .map_err(GetWivrnApkRefErr::RepoManipulationFailed)? - .id() - .to_string(), - )) - } - } -} - -#[derive(PartialEq, Eq, Debug, Clone)] -pub enum InstallWivrnStatus { - Success, - Done(Option), - InProgress, -} - -#[tracker::track] -pub struct InstallWivrnBox { - selected_profile: Profile, - install_wivrn_status: InstallWivrnStatus, - #[tracker::do_not_track] - root_win: gtk::Window, -} - -#[allow(clippy::large_enum_variant)] -#[derive(Debug)] -pub enum InstallWivrnBoxMsg { - UpdateSelectedProfile(Profile), - /// prepares state for async action, calls DoInstall - InstallWivrnApk, - /// dowloads, installs, sets state back to what it needs to be - DoInstall(String), -} - -#[derive(Debug)] -pub struct InstallWivrnBoxInit { - pub selected_profile: Profile, - pub root_win: gtk::Window, -} - -#[relm4::component(pub async)] -impl AsyncComponent for InstallWivrnBox { - type Init = InstallWivrnBoxInit; - type Input = InstallWivrnBoxMsg; - type Output = (); - type CommandOutput = (); - - view! { - gtk::Box { - set_orientation: gtk::Orientation::Vertical, - set_spacing: 12, - add_css_class: "card", - add_css_class: "padded", - #[track = "model.changed(Self::selected_profile())"] - set_visible: model.selected_profile.xrservice_type == XRServiceType::Wivrn, - gtk::Label { - add_css_class: "heading", - set_hexpand: true, - set_xalign: 0.0, - set_label: "Install WiVRn APK", - set_wrap: true, - set_wrap_mode: gtk::pango::WrapMode::Word, - }, - gtk::Label { - add_css_class: "dim-label", - set_hexpand: true, - set_label: concat!( - "Install the WiVRn APK on your standalone Android headset. ", - "You will need to enable Developer Mode on your headset, ", - "then press the \"Install WiVRn\" button." - ), - set_xalign: 0.0, - set_wrap: true, - set_wrap_mode: gtk::pango::WrapMode::Word, - }, - gtk::Button { - add_css_class: "suggested-action", - set_label: "Install WiVRn", - set_halign: gtk::Align::Start, - #[track = "model.changed(Self::install_wivrn_status())"] - set_sensitive: model.install_wivrn_status != InstallWivrnStatus::InProgress, - connect_clicked[sender] => move |_| { - sender.input(Self::Input::InstallWivrnApk) - }, - }, - gtk::Label { - add_css_class: "error", - set_xalign: 0.0, - set_wrap: true, - set_wrap_mode: gtk::pango::WrapMode::Word, - #[track = "model.changed(Self::install_wivrn_status())"] - set_visible: matches!(&model.install_wivrn_status, InstallWivrnStatus::Done(Some(_))), - #[track = "model.changed(Self::install_wivrn_status())"] - set_label: match &model.install_wivrn_status { - InstallWivrnStatus::Done(Some(err)) => err.as_str(), - _ => "", - }, - }, - gtk::Label { - add_css_class: "success", - set_xalign: 0.0, - #[track = "model.changed(Self::install_wivrn_status())"] - set_visible: model.install_wivrn_status == InstallWivrnStatus::Success, - set_label: "WiVRn Installed Successfully", - }, - } - } - - async fn update( - &mut self, - message: Self::Input, - sender: AsyncComponentSender, - _root: &Self::Root, - ) { - self.reset(); - - match message { - Self::Input::InstallWivrnApk => { - if !dep_adb().check() { - alert( - "ADB is not installed", - Some( - "Please install ADB on your computer to install WiVRn on your Android headset", - ), - Some(&self.root_win), - ); - return; - } - self.set_install_wivrn_status(InstallWivrnStatus::InProgress); - - match get_wivrn_apk_ref(&self.selected_profile) { - Err(GetWivrnApkRefErr::NotWivrn) => { - error!("this is not a WiVRn profile, how did you get here?"); - } - Err(GetWivrnApkRefErr::RepoDirNotFound) => { - self.set_install_wivrn_status(InstallWivrnStatus::Done(Some( - "Could not open WiVRn repository. Please build the profile before attempting to install the client APK".into() - ))); - } - Err(GetWivrnApkRefErr::RepoManipulationFailed(giterr)) => { - error!( - "failed to manipulate WiVRn repo: {giterr}, falling back to latest release APK" - ); - let existing = cache_file_path(WIVRN_LATEST_RELEASE_APK_URL, Some("apk")); - if existing.is_file() - && let Err(e) = remove_file(&existing) - { - error!("failed to remove file {}: {e}", existing.to_string_lossy()); - } - sender.input(Self::Input::DoInstall(WIVRN_LATEST_RELEASE_APK_URL.into())); - } - Ok(WivrnApkRef::Tag(tag)) => { - sender.input(Self::Input::DoInstall( - format!("https://github.com/WiVRn/WiVRn/releases/download/{tag}/WiVRn-release.apk") - )); - } - Ok(WivrnApkRef::Commit(commit)) => { - sender.input(Self::Input::DoInstall( - format!("https://github.com/WiVRn/WiVRn-APK/releases/download/apk-{commit}/org.meumeu.wivrn-release.apk") - )); - } - }; - } - Self::Input::DoInstall(url) => { - // TODO: we gonna cache or just download async every time? - match cache_file(&url, Some("apk")).await { - Err(e) => { - error!("failed to download apk: {e}"); - self.set_install_wivrn_status(InstallWivrnStatus::Done(Some( - "Error downloading WiVRn client APK".into(), - ))); - } - Ok(apk_path) => { - self.set_install_wivrn_status(match async_process( - "adb", - Some(&["install", "-r", "-g", apk_path.to_string_lossy().to_string().as_str()]), - None, - ) - .await - { - Ok(out) if out.exit_code == 0 => { - InstallWivrnStatus::Success - } - Ok(out) => { - if out.stdout.contains(ADB_ERR_NO_DEV) - || out.stderr.contains(ADB_ERR_NO_DEV) - { - InstallWivrnStatus::Done(Some( - concat!( - "No devices connected. Make sure your headset is connected ", - "to this computer and USB debugging is turned on." - ) - .into(), - )) - } else { - error!("ADB failed with code {}.\nstdout:\n{}\n======\nstderr:\n{}", out.exit_code, out.stdout, out.stderr); - InstallWivrnStatus::Done(Some( - format!("ADB exited with code \"{}\"", out.exit_code) - )) - } - } - Err(e) => { - error!("failed to run ADB: {e}"); - InstallWivrnStatus::Done(Some( - "Failed to run ADB".into() - )) - } - }); - } - }; - } - Self::Input::UpdateSelectedProfile(p) => { - self.set_selected_profile(p); - } - } - } - - async fn init( - init: Self::Init, - root: Self::Root, - sender: AsyncComponentSender, - ) -> AsyncComponentParts { - let model = Self { - selected_profile: init.selected_profile, - install_wivrn_status: InstallWivrnStatus::Done(None), - root_win: init.root_win, - tracker: 0, - }; - - let widgets = view_output!(); - - AsyncComponentParts { model, widgets } - } -} - -new_action_group!(pub InstallWivrnActionGroup, "installwivrn"); -new_stateless_action!(pub WivrnApkStandardAction, InstallWivrnActionGroup, "apkoculus"); diff --git a/src/ui/main_view.rs b/src/ui/main_view.rs index 04c3dec..dc11674 100644 --- a/src/ui/main_view.rs +++ b/src/ui/main_view.rs @@ -2,13 +2,11 @@ use super::{ SENDER_IO_ERR_MSG, - app::{AboutAction, ConfigureWivrnAction, DebugViewToggleAction}, + app::{AboutAction, DebugViewToggleAction}, devices_box::{DevicesBox, DevicesBoxMsg}, - install_wivrn_box::{InstallWivrnBox, InstallWivrnBoxInit, InstallWivrnBoxMsg}, openhmd_calibration_box::{OpenHmdCalibrationBox, OpenHmdCalibrationBoxMsg}, steam_launch_options_box::{SteamLaunchOptionsBox, SteamLaunchOptionsBoxMsg}, steamvr_calibration_box::{SteamVrCalibrationBox, SteamVrCalibrationBoxMsg}, - wivrn_wired_start_box::{WivrnWiredStartBox, WivrnWiredStartBoxInit, WivrnWiredStartBoxMsg}, }; use crate::{ config::Config, @@ -29,7 +27,6 @@ use crate::{ }, steam_library_folder::chaperone_info_exists, }, - wivrn_dbus, xr_clients::XRClient, xr_devices::XRDevice, }; @@ -44,10 +41,6 @@ pub struct MainView { #[no_eq] selected_profile: Profile, #[tracker::do_not_track] - install_wivrn_box: AsyncController, - #[tracker::do_not_track] - wivrn_wired_start_box: AsyncController, - #[tracker::do_not_track] steam_launch_options_box: Controller, #[tracker::do_not_track] devices_box: Controller, @@ -58,9 +51,6 @@ pub struct MainView { #[tracker::do_not_track] openhmd_calibration_box: Controller, xrservice_ready: bool, - wivrn_pairing_mode: bool, - wivrn_pin: Option, - wivrn_supports_pairing: bool, show_amd_gpu_power_profile_warn: bool, show_setcap_warn: bool, root_win: gtk::Window, @@ -77,10 +67,6 @@ pub enum MainViewMsg { UpdateDevices(Vec), UpdateClients(Vec), UpdateXrServiceReady(bool), - SetWivrnSupportsPairing(bool), - SetWivrnPairingMode(bool), - StopWivrnPairingMode, - StartWivrnPairingMode, CheckAmdGpuPowerProfile, CheckSetcap, DoSetcap, @@ -113,7 +99,6 @@ impl AsyncComponent for MainView { "_Preferences" => PreferencesAction, // value inside action is ignored "_Developer mode" => DebugViewToggleAction, - "Configure _WiVRn" => ConfigureWivrnAction, }, section! { "Change _theme" => ThemeManagerAction, @@ -199,7 +184,7 @@ impl AsyncComponent for MainView { set_visible: model.xrservice_active, add_css_class: "card", gtk::Label { - #[track = "model.changed(Self::xrservice_active()) || model.changed(Self::xrservice_ready()) || model.changed(Self::wivrn_pairing_mode())"] + #[track = "model.changed(Self::xrservice_active()) || model.changed(Self::xrservice_ready())"] set_label: { match model.selected_profile.xrservice_type { XRServiceType::Monado => @@ -208,26 +193,16 @@ impl AsyncComponent for MainView { } else { "Starting…" } - XRServiceType::Wivrn => - if model.wivrn_pairing_mode { - "Pairing mode" - } else { - "Starting, connect your client device…" - } } }, set_margin_all: 18, add_css_class: "heading", add_css_class: "success", add_css_class: "warning", - #[track = "model.changed(Self::xrservice_active()) || model.changed(Self::xrservice_ready()) || model.changed(Self::wivrn_pairing_mode())"] + #[track = "model.changed(Self::xrservice_active()) || model.changed(Self::xrservice_ready())"] set_class_active: ( "success", model.xrservice_ready - && ( - model.selected_profile.xrservice_type != XRServiceType::Wivrn - || !model.wivrn_pairing_mode - ) ), set_wrap: true, set_justify: gtk::Justification::Center, @@ -235,101 +210,6 @@ impl AsyncComponent for MainView { }, model.devices_box.widget(), model.clients_box.widget(), - gtk::Box { - set_orientation: gtk::Orientation::Vertical, - set_hexpand: true, - set_vexpand: false, - set_spacing: 12, - add_css_class: "card", - add_css_class: "padded", - #[track = "model.changed(Self::wivrn_supports_pairing()) || model.changed(Self::xrservice_active()) || model.changed(Self::selected_profile()) || model.changed(Self::wivrn_pairing_mode()) || model.changed(Self::wivrn_pin())"] - set_visible: model.wivrn_supports_pairing - && model.xrservice_active - && model.selected_profile.xrservice_type == XRServiceType::Wivrn - && !model.wivrn_pairing_mode, - gtk::Label { - add_css_class: "heading", - set_hexpand: true, - set_xalign: 0.0, - set_label: "Pairing mode", - set_wrap: true, - set_wrap_mode: gtk::pango::WrapMode::Word, - }, - gtk::Label { - add_css_class: "dim-label", - set_hexpand: true, - set_label: concat!( - "To connect a new device to WiVRn, you ", - "will need to pair it first.\n\n", - "You can do so by starting the pairing mode ", - "with the button below." - ), - set_xalign: 0.0, - set_wrap: true, - set_wrap_mode: gtk::pango::WrapMode::Word, - }, - gtk::Button { - add_css_class: "suggested-action", - set_label: "Start pairing mode", - set_halign: gtk::Align::Start, - connect_clicked[sender] => move |_| { - sender.input(Self::Input::StartWivrnPairingMode); - } - }, - }, - gtk::Box { - set_orientation: gtk::Orientation::Vertical, - set_hexpand: true, - set_vexpand: false, - set_spacing: 12, - add_css_class: "card", - add_css_class: "padded", - #[track = "model.changed(Self::wivrn_supports_pairing()) || model.changed(Self::xrservice_active()) || model.changed(Self::selected_profile()) || model.changed(Self::wivrn_pairing_mode()) || model.changed(Self::wivrn_pin())"] - set_visible: model.wivrn_supports_pairing - && model.xrservice_active - && model.selected_profile.xrservice_type == XRServiceType::Wivrn - && model.wivrn_pairing_mode && model.wivrn_pin.is_some(), - gtk::Label { - add_css_class: "heading", - set_hexpand: true, - set_xalign: 0.0, - set_label: "Pairing mode", - set_wrap: true, - set_wrap_mode: gtk::pango::WrapMode::Word, - }, - gtk::Label { - add_css_class: "dim-label", - set_hexpand: true, - set_label: concat!( - "WiVRn is in pairing mode. Pair your client ", - "device with the following PIN:" - ), - set_xalign: 0.0, - set_wrap: true, - set_wrap_mode: gtk::pango::WrapMode::Word, - }, - gtk::Label { - add_css_class: "title-2", - add_css_class: "monospace", - set_hexpand: true, - set_selectable: true, - #[track = "model.changed(Self::wivrn_pin())"] - set_label: model.wivrn_pin - .as_deref().unwrap_or(""), - set_xalign: 0.5, - set_justify: gtk::Justification::Center, - set_wrap: true, - set_wrap_mode: gtk::pango::WrapMode::Word, - }, - gtk::Button { - add_css_class: "destructive-action", - set_label: "Stop pairing mode", - set_halign: gtk::Align::Start, - connect_clicked[sender] => move |_| { - sender.input(Self::Input::StopWivrnPairingMode); - } - }, - }, gtk::Button { #[track = "model.changed(Self::xrservice_active()) || model.changed(Self::xrservice_ready())"] set_visible: model.xrservice_active @@ -431,8 +311,6 @@ impl AsyncComponent for MainView { }, model.steam_launch_options_box.widget(), - model.wivrn_wired_start_box.widget(), - model.install_wivrn_box.widget(), model.steamvr_calibration_box.widget(), model.openhmd_calibration_box.widget(), @@ -490,38 +368,6 @@ impl AsyncComponent for MainView { match message { Self::Input::ClockTicking => {} - Self::Input::SetWivrnSupportsPairing(supported) => { - if self.wivrn_supports_pairing != supported { - self.set_wivrn_supports_pairing(supported) - } - } - Self::Input::SetWivrnPairingMode(enabled) => { - if self.wivrn_pairing_mode != enabled { - self.set_wivrn_pairing_mode(enabled); - if enabled { - match wivrn_dbus::pairing_pin().await { - Ok(pin) => { - self.set_wivrn_pin(Some(pin)); - } - Err(e) => { - error!("failed to get wivrn pairing pin: {e}"); - } - }; - } else { - self.set_wivrn_pin(None); - } - } - } - Self::Input::StopWivrnPairingMode => { - if let Err(e) = wivrn_dbus::disable_pairing().await { - error!("failed to stop wivrn pairing mode: {e}"); - } - } - Self::Input::StartWivrnPairingMode => { - if let Err(e) = wivrn_dbus::enable_pairing().await { - error!("failed to start wivrn pairing mode: {e}"); - } - } Self::Input::StartStopClicked => { sender .output(Self::Output::DoStartStopXRService) @@ -535,7 +381,6 @@ impl AsyncComponent for MainView { Self::Input::XRServiceActiveChanged(active, profile, show_launch_opts) => { if !active { self.set_xrservice_ready(false); - sender.input(Self::Input::SetWivrnPairingMode(false)); } self.set_xrservice_active(active); self.steamvr_calibration_box @@ -572,12 +417,6 @@ impl AsyncComponent for MainView { .emit(OpenHmdCalibrationBoxMsg::SetVisible( prof.features.openhmd.enabled, )); - self.install_wivrn_box - .sender() - .emit(InstallWivrnBoxMsg::UpdateSelectedProfile(prof.clone())); - self.wivrn_wired_start_box - .sender() - .emit(WivrnWiredStartBoxMsg::UpdateSelectedProfile(prof.clone())); } Self::Input::UpdateDevices(devs) => { self.devices_box @@ -601,10 +440,7 @@ impl AsyncComponent for MainView { Self::Input::CheckSetcap => { let config = Config::get_config(); self.set_show_setcap_warn( - if self.selected_profile.xrservice_type == XRServiceType::Wivrn { - false - } else if let Some(executable) = - self.selected_profile.xrservice_binary(Some(&config)) + if let Some(executable) = self.selected_profile.xrservice_binary(Some(&config)) { !verify_cap_sys_nice_eip(&executable).await.unwrap_or(true) } else { @@ -659,27 +495,12 @@ impl AsyncComponent for MainView { xrservice_active: false, enable_debug_view: init.config.debug_view_enabled, steam_launch_options_box: SteamLaunchOptionsBox::builder().launch(()).detach(), - install_wivrn_box: InstallWivrnBox::builder() - .launch(InstallWivrnBoxInit { - selected_profile: init.selected_profile.clone(), - root_win: init.root_win.clone(), - }) - .detach(), - wivrn_wired_start_box: WivrnWiredStartBox::builder() - .launch(WivrnWiredStartBoxInit { - selected_profile: init.selected_profile.clone(), - root_win: init.root_win.clone(), - }) - .detach(), devices_box: DevicesBox::builder().launch(()).detach(), clients_box: ClientsBox::builder().launch(()).detach(), selected_profile: init.selected_profile.clone(), steamvr_calibration_box, openhmd_calibration_box, xrservice_ready: false, - wivrn_pairing_mode: false, - wivrn_supports_pairing: false, - wivrn_pin: None, show_amd_gpu_power_profile_warn: false, show_setcap_warn: false, root_win: init.root_win.clone(), diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 5d251cd..d1d53c5 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -8,7 +8,6 @@ pub mod cmdline_opts; mod debug_view; mod devices_box; mod factories; -mod install_wivrn_box; pub mod job_worker; mod libsurvive_setup_window; mod macros; @@ -21,9 +20,6 @@ mod steam_launch_options_box; mod steamvr_calibration_box; mod term_widget; mod util; -mod wivrn_conf_editor; -mod wivrn_encoder_presets_win; -mod wivrn_wired_start_box; pub const SENDER_IO_ERR_MSG: &str = "relm4 sender i/o failed"; pub const ADW_DIALOG_WIDTH: i32 = 600; diff --git a/src/ui/preference_rows.rs b/src/ui/preference_rows.rs index ae5c1d1..7f3bd3a 100644 --- a/src/ui/preference_rows.rs +++ b/src/ui/preference_rows.rs @@ -56,68 +56,6 @@ pub fn entry_row( row } -fn is_int(t: &str) -> bool { - t.find(|c: char| !c.is_ascii_digit()).is_none() -} - -fn convert_to_int(t: &str) -> String { - t.trim().chars().filter(|c| c.is_ascii_digit()).collect() -} - -fn is_float(t: &str) -> bool { - let mut has_dot = false; - for c in t.chars() { - if c == '.' { - if has_dot { - return false; - } - has_dot = true; - } else if !c.is_ascii_digit() { - return false; - } - } - true -} - -fn convert_to_float(t: &str) -> String { - let mut s = String::new(); - let mut has_dot = false; - for c in t.trim().chars() { - if c.is_ascii_digit() { - s.push(c); - } else if c == '.' && !has_dot { - s.push(c); - has_dot = true; - } - } - s -} - -pub fn number_entry_row( - title: &str, - value: &str, - float: bool, - cb: F, -) -> adw::EntryRow { - let validator = if float { is_float } else { is_int }; - let converter = if float { - convert_to_float - } else { - convert_to_int - }; - let row = entry_row(title, value, move |row| { - let txt_gstr = row.text(); - let txt = txt_gstr.as_str(); - if validator(txt) { - cb(row) - } else { - row.set_text(&converter(txt)); - } - }); - row.set_input_purpose(gtk::InputPurpose::Number); - row -} - pub fn spin_row( title: &str, subtitle: Option<&str>, @@ -313,33 +251,3 @@ pub fn combo_row( row } - -#[cfg(test)] -mod tests { - use crate::ui::preference_rows::{convert_to_float, is_float}; - - #[test] - fn accepts_float() { - assert!(is_float("132.1425")); - } - - #[test] - fn rejects_float_with_many_dots() { - assert!(!is_float("132.142.5")); - } - - #[test] - fn accepts_float_without_dots() { - assert!(is_float("1321425")); - } - - #[test] - fn rejects_float_with_alphas() { - assert!(!is_float("123.34a65")); - } - - #[test] - fn converts_to_float() { - assert_eq!(convert_to_float("123a.435.123"), "123.435123"); - } -} diff --git a/src/ui/preferences_window.rs b/src/ui/preferences_window.rs index 5be3074..7ee4dc5 100644 --- a/src/ui/preferences_window.rs +++ b/src/ui/preferences_window.rs @@ -3,7 +3,7 @@ use crate::{ config::Config, plugins::XRPlugin, - profile::{OvrCompatibilityModuleType, XRServiceType}, + profile::OvrCompatibilityModuleType, ui::{ SENDER_IO_ERR_MSG, preference_rows::{combo_row, spin_row, switch_row}, @@ -56,15 +56,15 @@ impl AsyncComponent for PreferencesWindow { set_title: "General", set_icon_name: Some("preferences-system-symbolic"), add: general_grp = &adw::PreferencesGroup { - add: &combo_row( - "XR service", - Some("Choose Monado for PCVR and WiVRn for standalone"), - model.config.borrow().global_preferences.xrservice_type.to_string().as_str(), - XRServiceType::iter().map(XRServiceType::to_string).collect(), - clone!(#[strong(rename_to=config)] model.config, move |row| { - config.borrow_mut().global_preferences.xrservice_type = XRServiceType::from(row.selected()); - }) - ), + // add: &combo_row( + // "XR service", + // None, + // model.config.borrow().global_preferences.xrservice_type.to_string().as_str(), + // XRServiceType::iter().map(XRServiceType::to_string).collect(), + // clone!(#[strong(rename_to=config)] model.config, move |row| { + // config.borrow_mut().global_preferences.xrservice_type = XRServiceType::from(row.selected()); + // }) + // ), add: &combo_row( "OpenVR compatibility", None, diff --git a/src/ui/profile_editor.rs b/src/ui/profile_editor.rs index 57ed4eb..6e49486 100644 --- a/src/ui/profile_editor.rs +++ b/src/ui/profile_editor.rs @@ -8,7 +8,7 @@ use super::{ }; use crate::{ env_var_descriptions::ENV_VAR_DESCRIPTIONS_AS_PARAGRAPH, - profile::{LighthouseDriver, OvrCompatibilityModuleType, Profile, XRServiceType}, + profile::{LighthouseDriver, OvrCompatibilityModuleType, Profile}, }; use adw::prelude::*; use gtk::glib::{self, clone}; @@ -146,18 +146,18 @@ impl SimpleComponent for ProfileEditor { "a placeholder for the actual XR Service command, ", "similarly to how Steam launch options work.", )), - add: &combo_row( - "XR Service Type", - Some("Monado is for PCVR headsets, while WiVRn is for Android standalone headsets"), - model.profile.borrow().xrservice_type.to_string().as_str(), - XRServiceType::iter() - .map(XRServiceType::to_string) - .collect::>(), - clone!(#[strong] prof, move |row| { - prof.borrow_mut().xrservice_type = - XRServiceType::from(row.selected()); - }), - ), + // add: &combo_row( + // "XR Service Type", + // None, + // model.profile.borrow().xrservice_type.to_string().as_str(), + // XRServiceType::iter() + // .map(XRServiceType::to_string) + // .collect::>(), + // clone!(#[strong] prof, move |row| { + // prof.borrow_mut().xrservice_type = + // XRServiceType::from(row.selected()); + // }), + // ), add: &entry_row( "XR Service Launch Options", model.profile.borrow().xrservice_launch_options.as_str(), diff --git a/src/ui/util.rs b/src/ui/util.rs index 46a8a9a..13292fa 100644 --- a/src/ui/util.rs +++ b/src/ui/util.rs @@ -39,14 +39,6 @@ pub fn copy_text(txt: &str) { } } -pub fn bits_to_mbits(bits: u32) -> Option { - bits.checked_div(1000000) -} - -pub fn bits_from_mbits(mbits: u32) -> Option { - mbits.checked_mul(1000000) -} - pub fn copiable_code_snippet(code: &str) -> gtk::Widget { let container = gtk::Box::builder() .orientation(gtk::Orientation::Horizontal) diff --git a/src/ui/wivrn_conf_editor.rs b/src/ui/wivrn_conf_editor.rs deleted file mode 100644 index e32bc02..0000000 --- a/src/ui/wivrn_conf_editor.rs +++ /dev/null @@ -1,349 +0,0 @@ -#![allow(unused_assignments)] // vars named in view! macro are not correctly recognized as used - -use super::{ - factories::wivrn_encoder_group_factory::{ - WivrnEncoderModel, WivrnEncoderModelInit, WivrnEncoderModelOutMsg, - }, - util::bits_from_mbits, - wivrn_encoder_presets_win::{ - WivrnEncoderPresetsWin, WivrnEncoderPresetsWinMsg, WivrnEncoderPresetsWinOutMsg, - }, -}; -use crate::{ - file_builders::wivrn_config::{ - WivrnConfEncoder, WivrnConfig, dump_wivrn_config, get_wivrn_config, - }, - ui::{ - ADW_DIALOG_WIDTH, - preference_rows::{number_entry_row, spin_row, switch_row}, - util::bits_to_mbits, - wivrn_encoder_presets_win::WivrnEncoderPresetsWinInit, - }, -}; -use adw::prelude::*; -use gtk::glib::clone; -use relm4::{factory::AsyncFactoryVecDeque, prelude::*}; -use tracing::error; - -#[tracker::track] -pub struct WivrnConfEditor { - conf: WivrnConfig, - #[tracker::do_not_track] - win: Option, - #[tracker::do_not_track] - pub encoder_models: Option>, - #[tracker::do_not_track] - pub scalex_row: Option, - #[tracker::do_not_track] - pub scaley_row: Option, - #[tracker::do_not_track] - bitrate_row: Option, - #[tracker::do_not_track] - wivrn_encoder_presets_win: Option>, - #[tracker::do_not_track] - parent: gtk::Window, -} - -#[derive(Debug)] -pub enum WivrnConfEditorMsg { - Present, - Save, - AddEncoder, - DeleteEncoder(String), - TcpOnlyChanged(bool), - UseSteamVrLhChanged(bool), - OpenEncoderPresetsWin, - SetEncoderPreset(Vec), - BitDepthChanged(bool), -} - -pub struct WivrnConfEditorInit { - pub root_win: gtk::Window, -} - -#[relm4::component(pub)] -impl SimpleComponent for WivrnConfEditor { - type Init = WivrnConfEditorInit; - type Input = WivrnConfEditorMsg; - type Output = (); - - view! { - #[name(win)] - adw::Dialog { - set_title: "WiVRn Configuration", - set_content_width: ADW_DIALOG_WIDTH, - #[wrap(Some)] - set_child: tbview = &adw::ToolbarView { - set_top_bar_style: adw::ToolbarStyle::Flat, - set_hexpand: true, - set_vexpand: true, - add_top_bar: top_bar = &adw::HeaderBar { - set_vexpand: false, - set_show_end_title_buttons: false, - set_show_start_title_buttons: false, - pack_end: save_btn = >k::Button { - set_label: "Save", - add_css_class: "suggested-action", - connect_clicked[sender] => move |_| { - sender.input(Self::Input::Save); - }, - }, - pack_start: cancel_btn = >k::Button { - set_label: "Cancel", - add_css_class: "destructive-action", - connect_clicked[win] => move |_| { - win.close(); - } - }, - }, - #[wrap(Some)] - set_content: pref_page = &adw::PreferencesPage { - set_hexpand: true, - set_vexpand: true, - set_description: "Warning: you likely don't need to change the default configuration, this is for advanced users only. Proceed at your own risk!\n\nWiVRn Configuration Documentation", - add: scalegrp = &adw::PreferencesGroup { - set_title: "Scale", - set_description: Some(concat!("Foveation scale, 1.0 means no foveation. ", - "A value too high may overload your headset's decoder.\n", - "This does not affect game render resolution. ", - "Render resolution is set from within the Android app.", - )), - add: scalex_row = &spin_row( - "Scale X", - None, - match model.conf.scale { - Some([x, _]) => x.into(), - None => 0.5, - }, - 0.0, - 1.0, - 0.01, - move |_| {} - ) -> adw::SpinRow, - add: scaley_row = &spin_row( - "Scale Y", - None, - match model.conf.scale { - Some([_, y]) => y.into(), - None => 0.5, - }, - 0.0, - 1.0, - 0.01, - move |_| {} - ) -> adw::SpinRow, - }, - add: bitrategrp = &adw::PreferencesGroup { - set_title: "Bitrate", - add: bitrate_row = &number_entry_row( - "Bitrate (Mbps)", - &model.conf.bitrate - .and_then(|n| bits_to_mbits(n).map(|mbits| mbits.to_string())) - .unwrap_or_default(), - false, - move |_| {} - ) -> adw::EntryRow, - }, - // TODO: add application? conflicts with envision autostart - add: networkgrp = &adw::PreferencesGroup { - set_title: "Network", - add: &switch_row( - "TCP Only Mode", - Some(concat!( - "Only use TCP for communications with the client, ", - "this may have increased latency. If off, WiVRn ", - "will use both TCP and UDP." - )), - model.conf.tcp_only, - clone!(#[strong] sender, move |_, val| { - sender.input(Self::Input::TcpOnlyChanged(val)); - }), - ), - }, - add: lhgrp = &adw::PreferencesGroup { - set_title: "SteamVR", - add: &switch_row( - "SteamVR Lighthouse Tracking", - Some(concat!( - "Enables the steamvr_lh driver. ", - "Only use if you have devices that use SteamVR Lighthouse tracking, ", - "like Valve Index Knuckles, VIVE Wands, VIVE/Tundra trackers, etc." - )), - model.conf.use_steamvr_lh, - clone!(#[strong] sender, move |_, val| { - sender.input(Self::Input::UseSteamVrLhChanged(val)); - }), - ), - }, - add: encodersrgp = &adw::PreferencesGroup { - set_title: "Encoders", - adw::ActionRow { - set_title: "Add encoder", - add_suffix: presets_btn = >k::Button { - set_valign: gtk::Align::Center, - set_label: "Use Preset", - connect_clicked[sender] => move |_| { - sender.input(Self::Input::OpenEncoderPresetsWin) - } - }, - add_suffix: add_encoder_btn = >k::Button { - set_halign: gtk::Align::Center, - set_valign: gtk::Align::Center, - add_css_class: "suggested-action", - set_icon_name: "list-add-symbolic", - set_tooltip_text: Some("Add encoder"), - connect_clicked[sender] => move |_| { - sender.input(Self::Input::AddEncoder) - } - }, - }, - add: &switch_row( - "10-bit Encoding", - Some("Enables 10-bit encoding."), - model.conf.bit_depth == 10, - clone!(#[strong] sender, move |_, val| { - sender.input(Self::Input::BitDepthChanged(val)); - }), - ), - }, - } - } - } - } - - fn update(&mut self, message: Self::Input, _sender: ComponentSender) { - self.reset(); - - match message { - Self::Input::Present => { - self.set_conf(get_wivrn_config()); - self.win.as_ref().unwrap().present(Some(&self.parent)); - } - Self::Input::OpenEncoderPresetsWin => { - self.wivrn_encoder_presets_win - .as_ref() - .unwrap() - .sender() - .emit(WivrnEncoderPresetsWinMsg::Present); - } - Self::Input::SetEncoderPreset(preset) => { - self.encoder_models.as_mut().unwrap().guard().clear(); - preset.iter().for_each(|enc| { - self.encoder_models.as_mut().unwrap().guard().push_back( - WivrnEncoderModelInit { - encoder_conf: Some(enc.clone()), - }, - ); - }); - } - Self::Input::Save => { - let x = self.scalex_row.as_ref().unwrap().adjustment().value(); - let y = self.scaley_row.as_ref().unwrap().adjustment().value(); - self.conf.scale = Some([x as f32, y as f32]); - self.conf.bitrate = { - let txt = self.bitrate_row.as_ref().unwrap().text(); - if txt.is_empty() { - None - } else { - match txt.parse::() { - Ok(mbits) => bits_from_mbits(mbits), - Err(_) => None, - } - } - }; - self.conf.encoders = self - .encoder_models - .as_ref() - .unwrap() - .iter() - .filter(Option::is_some) - .map(|m| m.as_ref().unwrap().encoder_conf.clone()) - .collect(); - dump_wivrn_config(&self.conf); - self.win.as_ref().unwrap().close(); - } - Self::Input::TcpOnlyChanged(val) => { - self.conf.tcp_only = val; - } - Self::Input::UseSteamVrLhChanged(val) => { - self.conf.use_steamvr_lh = val; - } - Self::Input::AddEncoder => { - self.encoder_models - .as_mut() - .unwrap() - .guard() - .push_back(WivrnEncoderModelInit::default()); - } - Self::Input::DeleteEncoder(id) => { - let idx_opt = self - .encoder_models - .as_ref() - .unwrap() - .iter() - .position(|m_opt| m_opt.is_some_and(|m| m.uid == id)); - if let Some(idx) = idx_opt { - self.encoder_models.as_mut().unwrap().guard().remove(idx); - } else { - error!("couldn't find encoder model with id {id}"); - } - } - Self::Input::BitDepthChanged(val) => { - self.conf.bit_depth = if val { 10 } else { 8 }; - } - } - } - - fn init( - init: Self::Init, - root: Self::Root, - sender: ComponentSender, - ) -> ComponentParts { - let mut model = Self { - conf: get_wivrn_config(), - encoder_models: None, - win: None, - scalex_row: None, - scaley_row: None, - bitrate_row: None, - wivrn_encoder_presets_win: None, - parent: init.root_win, - tracker: 0, - }; - - let widgets = view_output!(); - - model.scalex_row = Some(widgets.scalex_row.clone()); - model.scaley_row = Some(widgets.scaley_row.clone()); - model.bitrate_row = Some(widgets.bitrate_row.clone()); - - let mut encoder_models: AsyncFactoryVecDeque = - AsyncFactoryVecDeque::builder() - .launch(widgets.pref_page.clone()) - .forward(sender.input_sender(), |msg| match msg { - WivrnEncoderModelOutMsg::Delete(id) => WivrnConfEditorMsg::DeleteEncoder(id), - }); - for encoder_conf in model.conf.encoders.clone() { - encoder_models.guard().push_back(WivrnEncoderModelInit { - encoder_conf: Some(encoder_conf), - }); - } - model.encoder_models = Some(encoder_models); - - model.win = Some(widgets.win.clone()); - - model.wivrn_encoder_presets_win = Some( - WivrnEncoderPresetsWin::builder() - .launch(WivrnEncoderPresetsWinInit { - parent_win: widgets.win.clone().upcast(), - }) - .forward(sender.input_sender(), move |msg| match msg { - WivrnEncoderPresetsWinOutMsg::Selected(preset) => { - Self::Input::SetEncoderPreset(preset) - } - }), - ); - - ComponentParts { model, widgets } - } -} diff --git a/src/ui/wivrn_encoder_presets_win.rs b/src/ui/wivrn_encoder_presets_win.rs deleted file mode 100644 index 9b7a43f..0000000 --- a/src/ui/wivrn_encoder_presets_win.rs +++ /dev/null @@ -1,106 +0,0 @@ -#![allow(unused_assignments)] // vars named in view! macro are not correctly recognized as used - -use adw::prelude::*; -use relm4::prelude::*; - -use crate::file_builders::{ - wivrn_config::WivrnConfEncoder, wivrn_encoder_presets::WIVRN_ENCODER_PRESETS, -}; - -use super::SENDER_IO_ERR_MSG; - -pub struct WivrnEncoderPresetsWin { - win: Option, - parent: gtk::Widget, -} - -#[derive(Debug)] -pub enum WivrnEncoderPresetsWinMsg { - Present, - Selected(Vec), -} - -#[derive(Debug)] -pub enum WivrnEncoderPresetsWinOutMsg { - Selected(Vec), -} - -pub struct WivrnEncoderPresetsWinInit { - pub parent_win: gtk::Widget, -} - -#[relm4::component(pub)] -impl SimpleComponent for WivrnEncoderPresetsWin { - type Init = WivrnEncoderPresetsWinInit; - type Input = WivrnEncoderPresetsWinMsg; - type Output = WivrnEncoderPresetsWinOutMsg; - - view! { - #[name(win)] - adw::Dialog { - set_title: "WiVRn Encoder Presets", - set_presentation_mode: adw::DialogPresentationMode::BottomSheet, - #[wrap(Some)] - set_child: tbview = &adw::ToolbarView { - set_top_bar_style: adw::ToolbarStyle::Flat, - set_hexpand: true, - set_vexpand: true, - add_top_bar: top_bar = &adw::HeaderBar { - set_vexpand: false, - }, - #[wrap(Some)] - set_content: prefpage = &adw::PreferencesPage { - set_title: "Encoder Presets", - add: prefgrp = &adw::PreferencesGroup {} - } - }, - } - } - - fn update(&mut self, message: Self::Input, sender: ComponentSender) { - match message { - Self::Input::Present => { - self.win.as_ref().unwrap().present(Some(&self.parent)); - } - Self::Input::Selected(preset) => { - sender - .output(Self::Output::Selected(preset)) - .expect(SENDER_IO_ERR_MSG); - self.win.as_ref().unwrap().close(); - } - } - } - - fn init( - init: Self::Init, - root: Self::Root, - sender: ComponentSender, - ) -> ComponentParts { - let mut model = Self { - win: None, - parent: init.parent_win, - }; - - let widgets = view_output!(); - - model.win = Some(widgets.win.clone()); - - WIVRN_ENCODER_PRESETS - .iter() - .for_each(|(name, desc, enc_preset)| { - let row = adw::ActionRow::builder() - .title(*name) - .subtitle_lines(0) - .subtitle(*desc) - .activatable(true) - .build(); - let sndr = sender.clone(); - row.connect_activated(move |_| { - sndr.input(Self::Input::Selected(enc_preset.clone())) - }); - widgets.prefgrp.add(&row); - }); - - ComponentParts { model, widgets } - } -} diff --git a/src/ui/wivrn_wired_start_box.rs b/src/ui/wivrn_wired_start_box.rs deleted file mode 100644 index fcbd44f..0000000 --- a/src/ui/wivrn_wired_start_box.rs +++ /dev/null @@ -1,197 +0,0 @@ -use super::{ADB_ERR_NO_DEV, alert::alert}; -use crate::{ - async_process::async_process, - constants::APP_NAME, - depcheck::common::dep_adb, - profile::{Profile, XRServiceType}, -}; -use gtk::prelude::*; -use relm4::prelude::*; -use tracing::error; - -#[derive(PartialEq, Eq, Debug, Clone)] -pub enum StartClientStatus { - Success, - Done(Option), - InProgress, -} - -#[tracker::track] -pub struct WivrnWiredStartBox { - selected_profile: Profile, - start_client_status: StartClientStatus, - #[tracker::do_not_track] - root_win: gtk::Window, -} - -#[allow(clippy::large_enum_variant)] -#[derive(Debug)] -pub enum WivrnWiredStartBoxMsg { - UpdateSelectedProfile(Profile), - /// prepares state for async action, calls DoStartClient - StartWivrnClient, - /// actually sends the adb commands to start the client - DoStartClient, -} - -#[derive(Debug)] -pub struct WivrnWiredStartBoxInit { - pub selected_profile: Profile, - pub root_win: gtk::Window, -} - -#[relm4::component(pub async)] -impl AsyncComponent for WivrnWiredStartBox { - type Init = WivrnWiredStartBoxInit; - type Input = WivrnWiredStartBoxMsg; - type Output = (); - type CommandOutput = (); - - view! { - gtk::Box { - set_orientation: gtk::Orientation::Vertical, - set_spacing: 12, - add_css_class: "card", - add_css_class: "padded", - #[track = "model.changed(Self::selected_profile())"] - set_visible: model.selected_profile.xrservice_type == XRServiceType::Wivrn, - gtk::Label { - add_css_class: "heading", - set_hexpand: true, - set_xalign: 0.0, - set_label: "Start WiVRn Client (Wired)", - set_wrap: true, - set_wrap_mode: gtk::pango::WrapMode::Word, - }, - gtk::Label { - add_css_class: "dim-label", - set_hexpand: true, - set_label: concat!( - "Start the WiVRn client on your Android headset. This only ", - "works in wired connection mode." - ), - set_xalign: 0.0, - set_wrap: true, - set_wrap_mode: gtk::pango::WrapMode::Word, - }, - gtk::Button { - add_css_class: "suggested-action", - set_label: "Start WiVRn Client", - set_halign: gtk::Align::Start, - #[track = "model.changed(Self::start_client_status())"] - set_sensitive: model.start_client_status != StartClientStatus::InProgress, - connect_clicked[sender] => move |_| { - sender.input(Self::Input::StartWivrnClient) - }, - }, - gtk::Label { - add_css_class: "error", - set_xalign: 0.0, - set_wrap: true, - set_wrap_mode: gtk::pango::WrapMode::Word, - #[track = "model.changed(Self::start_client_status())"] - set_visible: matches!(&model.start_client_status, StartClientStatus::Done(Some(_))), - #[track = "model.changed(Self::start_client_status())"] - set_label: match &model.start_client_status { - StartClientStatus::Done(Some(err)) => err.as_str(), - _ => "", - }, - }, - } - } - - async fn update( - &mut self, - message: Self::Input, - sender: AsyncComponentSender, - _root: &Self::Root, - ) { - self.reset(); - - match message { - Self::Input::UpdateSelectedProfile(p) => self.set_selected_profile(p), - Self::Input::StartWivrnClient => { - if !dep_adb().check() { - alert( - "ADB is not installed", - Some(&format!( - "Please install ADB on your computer to start the WiVRn client from {APP_NAME}." - )), - Some(&self.root_win), - ); - return; - } - self.set_start_client_status(StartClientStatus::InProgress); - sender.input(Self::Input::DoStartClient); - } - Self::Input::DoStartClient => { - let n_status = match async_process( - "sh", - Some(&[ - "-c", - concat!( - "set -e;", - // package from store is org.meumeu.wivrn - // package from github is org.meumeu.wivrn.github - // locally built one is org.meumeu.wivrn.local - // select by preference "local", then "github" and last store one - "PACKAGE=$(adb shell pm list packages org.meumeu.wivrn | sort | tail -1 | sed 's/package://');", - "adb reverse tcp:9757 tcp:9757 && ", - "adb shell am force-stop $PACKAGE && ", - // wait for force-stop - "sleep 1 && ", - "adb shell am start -a android.intent.action.VIEW -d \"wivrn+tcp://127.0.0.1\" $PACKAGE" - ) - ]), - None - ).await { - Ok(out) if out.exit_code == 0 => - StartClientStatus::Success - , - Ok(out) => { - if out.stdout.contains(ADB_ERR_NO_DEV) - || out.stderr.contains(ADB_ERR_NO_DEV) - { - StartClientStatus::Done(Some( - concat!( - "No devices connected. Make sure your headset is connected ", - "to this computer and USB debugging is turned on." - ) - .into(), - )) - } else { - error!("ADB failed with code {}.\nstdout:\n{}\n======\nstderr:\n{}", out.exit_code, out.stdout, out.stderr); - StartClientStatus::Done(Some( - format!("ADB exited with code \"{}\"", out.exit_code) - )) - } - }, - Err(e) => { - error!("failed to run ADB: {e}"); - StartClientStatus::Done(Some( - "Failed to run ADB".into() - )) - }, - }; - self.set_start_client_status(n_status); - } - } - } - - async fn init( - init: Self::Init, - root: Self::Root, - sender: AsyncComponentSender, - ) -> AsyncComponentParts { - let model = Self { - selected_profile: init.selected_profile, - start_client_status: StartClientStatus::Done(None), - root_win: init.root_win, - tracker: 0, - }; - - let widgets = view_output!(); - - AsyncComponentParts { model, widgets } - } -} diff --git a/src/util/git_repos.rs b/src/util/git_repos.rs index c66c396..efffda8 100644 --- a/src/util/git_repos.rs +++ b/src/util/git_repos.rs @@ -16,8 +16,5 @@ pub const DEFAULT_OPENHMD_BRANCH: &str = "rift-room-config"; pub const DEFAULT_VAPOR_REPO: &str = "https://github.com/micheal65536/VapoR.git"; pub const DEFAULT_VAPOR_BRANCH: &str = "master"; -pub const DEFAULT_WIVRN_REPO: &str = "https://github.com/WiVRn/WiVRn"; -pub const DEFAULT_WIVRN_BRANCH: &str = "release"; - pub const DEFAULT_XRIZER_REPO: &str = "https://github.com/Supreeeme/xrizer"; pub const DEFAULT_XRIZER_BRANCH: &str = "main"; diff --git a/src/wivrn_dbus/internal.rs b/src/wivrn_dbus/internal.rs deleted file mode 100644 index 2fa36e2..0000000 --- a/src/wivrn_dbus/internal.rs +++ /dev/null @@ -1,122 +0,0 @@ -//! # D-Bus interface proxy for: `io.github.wivrn.Server` -//! -//! This code was generated by `zbus-xmlgen` `5.0.1` from D-Bus introspection data. -//! Source: `io.github.wivrn.Server.xml`. -//! -//! You may prefer to adapt it, instead of using it verbatim. -//! -//! More information can be found in the [Writing a client proxy] section of the zbus -//! documentation. -//! -//! This type implements the [D-Bus standard interfaces], (`org.freedesktop.DBus.*`) for which the -//! following zbus API can be used: -//! -//! * [`zbus::fdo::PropertiesProxy`] -//! -//! Consequently `zbus-xmlgen` did not generate code for the above interfaces. -//! -//! [Writing a client proxy]: https://dbus2.github.io/zbus/client.html -//! [D-Bus standard interfaces]: https://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces, -use zbus::proxy; -#[proxy( - interface = "io.github.wivrn.Server", - default_path = "/io/github/wivrn/Server", - default_service = "io.github.wivrn.Server" -)] -pub trait Server { - /// DisablePairing method - fn disable_pairing(&self) -> zbus::Result<()>; - - /// Disconnect method - fn disconnect(&self) -> zbus::Result<()>; - - /// EnablePairing method - fn enable_pairing(&self, TimeoutSecs: i32) -> zbus::Result; - - /// Quit method - fn quit(&self) -> zbus::Result<()>; - - /// RenameKey method - fn rename_key(&self, PublicKey: &str, Name: &str) -> zbus::Result<()>; - - /// RevokeKey method - fn revoke_key(&self, PublicKey: &str) -> zbus::Result<()>; - - /// AvailableRefreshRates property - #[zbus(property)] - fn available_refresh_rates(&self) -> zbus::Result>; - - /// EncryptionEnabled property - #[zbus(property)] - fn encryption_enabled(&self) -> zbus::Result; - - /// EyeGaze property - #[zbus(property)] - fn eye_gaze(&self) -> zbus::Result; - - /// FaceTracking property - #[zbus(property)] - fn face_tracking(&self) -> zbus::Result; - - /// FieldOfView property - #[zbus(property)] - fn field_of_view(&self) -> zbus::Result>; - - /// HandTracking property - #[zbus(property)] - fn hand_tracking(&self) -> zbus::Result; - - /// HeadsetConnected property - #[zbus(property)] - fn headset_connected(&self) -> zbus::Result; - - /// JsonConfiguration property - #[zbus(property)] - fn json_configuration(&self) -> zbus::Result; - #[zbus(property)] - fn set_json_configuration(&self, value: &str) -> zbus::Result<()>; - - /// KnownKeys property - #[zbus(property)] - fn known_keys(&self) -> zbus::Result>; - - /// MicChannels property - #[zbus(property)] - fn mic_channels(&self) -> zbus::Result; - - /// MicSampleRate property - #[zbus(property)] - fn mic_sample_rate(&self) -> zbus::Result; - - /// PairingEnabled property - #[zbus(property)] - fn pairing_enabled(&self) -> zbus::Result; - - /// Pin property - #[zbus(property)] - fn pin(&self) -> zbus::Result; - - /// PreferredRefreshRate property - #[zbus(property)] - fn preferred_refresh_rate(&self) -> zbus::Result; - - /// RecommendedEyeSize property - #[zbus(property)] - fn recommended_eye_size(&self) -> zbus::Result<(u32, u32)>; - - /// SpeakerChannels property - #[zbus(property)] - fn speaker_channels(&self) -> zbus::Result; - - /// SpeakerSampleRate property - #[zbus(property)] - fn speaker_sample_rate(&self) -> zbus::Result; - - /// SteamCommand property - #[zbus(property)] - fn steam_command(&self) -> zbus::Result; - - /// SupportedCodecs property - #[zbus(property)] - fn supported_codecs(&self) -> zbus::Result>; -} diff --git a/src/wivrn_dbus/mod.rs b/src/wivrn_dbus/mod.rs deleted file mode 100644 index dfa610c..0000000 --- a/src/wivrn_dbus/mod.rs +++ /dev/null @@ -1,34 +0,0 @@ -// how to regenerate this one: -// -// ```bash -// cargo install zbus_xmlgen -// curl -sSLO https://github.com/WiVRn/WiVRn/blob/master/dbus/io.github.wivrn.Server.xml -// zbus-xmlgen file io.github.wivrn.Server.xml -// ``` -// -// it should output a file called server.rs, move it accordingly -#[rustfmt::skip] -#[allow(non_snake_case)] -mod internal; - -async fn proxy<'a>() -> zbus::Result> { - let connection = zbus::Connection::session().await?; - let proxy = internal::ServerProxy::new(&connection).await?; - Ok(proxy) -} - -pub async fn is_pairing_mode() -> zbus::Result { - proxy().await?.pairing_enabled().await -} - -pub async fn enable_pairing() -> zbus::Result { - proxy().await?.enable_pairing(0).await -} - -pub async fn disable_pairing() -> zbus::Result<()> { - proxy().await?.disable_pairing().await -} - -pub async fn pairing_pin() -> zbus::Result { - proxy().await?.pin().await -}