From 9c66045029023b98584551212a78f6b7d6eb8cb6 Mon Sep 17 00:00:00 2001 From: Thomas Forgione Date: Mon, 10 Dec 2018 14:49:38 +0100 Subject: [PATCH] Added hdmi sound option --- src/lib.rs | 41 +++++++++++++++++++++++++++++++++++++---- src/tv.rs | 11 +++++++++++ 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index ffb5c00..0375a31 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,6 +10,30 @@ pub fn resolution_to_string(res: (u32, u32)) -> String { format!("{}x{}", res.0, res.1).to_owned() } +/// Sets the sound to the HDMI output. +pub fn enable_hdmi_sound() -> Result<(), Error>{ + Command::new("pactl") + .args(&[ + "set-card-profile", + "0", + "output:hdmi-stereo", + ]) + .output()?; + Ok(()) +} + +/// Disables the HDMI sound output. +pub fn disable_hdmi_sound() -> Result<(), Error>{ + Command::new("pactl") + .args(&[ + "set-card-profile", + "0", + "output:analog-stereo+input:analog-stereo", + ]) + .output()?; + Ok(()) +} + /// The different kinds of errors that can happen. #[derive(Debug)] pub enum Error { @@ -92,16 +116,16 @@ impl From for Error { #[derive(Debug)] pub struct Screen { /// The name of the screen received from xrandr. - name: String, + pub name: String, /// The available resolutions of the screen. - resolutions: Vec<(u32, u32)>, + pub resolutions: Vec<(u32, u32)>, /// Whether the screen is primary or not - primary: bool, + pub primary: bool, /// Whether the screen is connected or not. - connected: bool, + pub connected: bool, } impl Screen { @@ -319,6 +343,15 @@ impl MultiScreen { Ok(()) } + /// If a HDMI screen is detected, puts the sound on it. Otherwise, disables it. + pub fn enable_hdmi_sound_if_present(&self) -> Result<(), Error> { + let hdmi = self.screens.iter().fold(false, |acc, x| acc || x.name.to_lowercase().contains("hdmi")); + Ok(if hdmi { + enable_hdmi_sound()? + } else { + disable_hdmi_sound()? + }) + } } diff --git a/src/tv.rs b/src/tv.rs index b8d2685..cfa1bd7 100644 --- a/src/tv.rs +++ b/src/tv.rs @@ -19,11 +19,16 @@ fn main() { .help("Specify the position of the second screen") .possible_values(&["left", "right", "above", "below"]) .required_if("action", "enable")) + .arg(Arg::with_name("sound") + .help("Outputs the sound to the HDMI (requires pulseaudio)") + .short("s") + .long("sound")) .get_matches(); let screens = MultiScreen::detect() .expect("An error happened while finding screens"); + let sound = matches.occurrences_of("sound") > 0; let result = match matches.value_of("action") { Some("disable") => screens.only_primary(), @@ -37,5 +42,11 @@ fn main() { _ => Ok(()) }; + if sound { + if let Err(e) = screens.enable_hdmi_sound_if_present() { + eprintln!("Error: couldn't set hdmi sound: {:?}", e); + } + } + result.expect("An error happenned while executing the command"); }