From 2f441f4669eb0c64dd9d521006971ecc3786d2d6 Mon Sep 17 00:00:00 2001 From: GHOSCHT <31184695+GHOSCHT@users.noreply.github.com> Date: Wed, 30 Aug 2023 13:04:00 +0200 Subject: [PATCH] Implement set_default_sink with pulseaudio --- Cargo.lock | 162 +++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 4 ++ src/pulse.rs | 79 +++++++++++++++++++++++++ 3 files changed, 245 insertions(+) create mode 100644 src/pulse.rs diff --git a/Cargo.lock b/Cargo.lock index 5b058fe..94fedcf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,18 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + [[package]] name = "darling" version = "0.14.4" @@ -76,6 +88,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + [[package]] name = "fnv" version = "1.0.7" @@ -103,6 +121,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "hashbrown" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" + [[package]] name = "heck" version = "0.3.3" @@ -118,6 +142,16 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" +[[package]] +name = "indexmap" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +dependencies = [ + "equivalent", + "hashbrown", +] + [[package]] name = "itertools" version = "0.11.0" @@ -142,6 +176,39 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "libpulse-binding" +version = "2.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3557a2dfc380c8f061189a01c6ae7348354e0c9886038dc6c171219c08eaff" +dependencies = [ + "bitflags", + "libc", + "libpulse-sys", + "num-derive", + "num-traits", + "winapi", +] + +[[package]] +name = "libpulse-sys" +version = "1.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc19e110fbf42c17260d30f6d3dc545f58491c7830d38ecb9aaca96e26067a9b" +dependencies = [ + "libc", + "num-derive", + "num-traits", + "pkg-config", + "winapi", +] + +[[package]] +name = "memchr" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f478948fd84d9f8e86967bf432640e46adfb5a4bd4f14ef7e864ab38220534ae" + [[package]] name = "mpris" version = "2.0.1" @@ -155,12 +222,35 @@ dependencies = [ "thiserror", ] +[[package]] +name = "num-derive" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" +dependencies = [ + "proc-macro2", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "num-traits" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" +dependencies = [ + "autocfg", +] + [[package]] name = "pico_kontroller" version = "0.1.0" dependencies = [ "itertools", + "libpulse-binding", "mpris", + "serde", + "toml", ] [[package]] @@ -193,6 +283,35 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "serde" +version = "1.0.188" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.188" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +dependencies = [ + "proc-macro2", + "quote 1.0.33", + "syn 2.0.29", +] + +[[package]] +name = "serde_spanned" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186" +dependencies = [ + "serde", +] + [[package]] name = "strsim" version = "0.10.0" @@ -261,6 +380,40 @@ dependencies = [ "syn 2.0.29", ] +[[package]] +name = "toml" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17e963a819c331dcacd7ab957d80bc2b9a9c1e71c804826d2f283dd65306542" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.19.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + [[package]] name = "unicode-ident" version = "1.0.11" @@ -300,3 +453,12 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "winnow" +version = "0.5.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c2e3184b9c4e92ad5167ca73039d0c42476302ab603e2fec4487511f38ccefc" +dependencies = [ + "memchr", +] diff --git a/Cargo.toml b/Cargo.toml index d142144..292fa20 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,4 +7,8 @@ edition = "2021" [dependencies] itertools = "0.11.0" +libpulse-binding = "2.28.1" mpris = "2.0.1" +serde = {version ="1.0.188", features = ["derive"]} +toml = "0.7.6" + diff --git a/src/pulse.rs b/src/pulse.rs new file mode 100644 index 0000000..013e53d --- /dev/null +++ b/src/pulse.rs @@ -0,0 +1,79 @@ +extern crate libpulse_binding as pulse; +use pulse::context::{Context, FlagSet as ContextFlagSet}; +use pulse::def::Retval; +use pulse::mainloop::standard::{IterateResult, Mainloop}; +use pulse::proplist::Proplist; +use std::cell::RefCell; +use std::ops::Deref; +use std::rc::Rc; + +pub fn set_default_sink(name: &str) { + let mut proplist = Proplist::new().unwrap(); + proplist + .set_str( + pulse::proplist::properties::APPLICATION_NAME, + "picoKontroller", + ) + .unwrap(); + + let mainloop = Rc::new(RefCell::new( + Mainloop::new().expect("Failed to create mainloop"), + )); + + let context = Rc::new(RefCell::new( + Context::new_with_proplist( + mainloop.borrow().deref(), + "picoKontrollerContext", + &proplist, + ) + .expect("Failed to create new context"), + )); + + context + .borrow_mut() + .connect(None, ContextFlagSet::NOFLAGS, None) + .expect("Failed to connect context"); + + loop { + match mainloop.borrow_mut().iterate(false) { + IterateResult::Quit(_) | IterateResult::Err(_) => { + eprintln!("Iterate state was not success, quitting..."); + return; + } + IterateResult::Success(_) => {} + } + match context.borrow().get_state() { + pulse::context::State::Ready => { + break; + } + pulse::context::State::Failed | pulse::context::State::Terminated => { + eprintln!("Context state failed/terminated, quitting..."); + return; + } + _ => {} + } + } + + let op = context.borrow_mut().set_default_sink(name, |_| {}); + loop { + match mainloop.borrow_mut().iterate(false) { + IterateResult::Quit(_) | IterateResult::Err(_) => { + eprintln!("Iterate state was not success, quitting..."); + return; + } + IterateResult::Success(_) => {} + } + match op.get_state() { + pulse::operation::State::Done => { + break; + } + pulse::operation::State::Cancelled => { + eprintln!("Setting default sink was cancelled..."); + return; + } + _ => {} + } + } + + mainloop.borrow_mut().quit(Retval(0)); +}