From 62ec3d6eb06cfb4c3d7202baa605223c773ef1be Mon Sep 17 00:00:00 2001 From: Julian Ospald Date: Thu, 29 Jun 2017 01:35:30 +0200 Subject: [PATCH] Update --- Cargo.toml | 1 + src/app_state.rs | 11 ++++++--- src/audio.rs | 57 +++++++++++++++++++++++++++++++++++++++----- src/gui_callbacks.rs | 4 +++- src/main.rs | 8 ++++++- 5 files changed, 70 insertions(+), 11 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d9c66c4ce..2b921a4e6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,6 +5,7 @@ authors = ["Julian Ospald "] [dependencies] alsa = "^0.1.8" +alsa-sys = "^0.1.1" libc = "^0.2.23" gdk-sys = { git = "https://github.com/gtk-rs/sys" } gtk-sys = { git = "https://github.com/gtk-rs/sys" } diff --git a/src/app_state.rs b/src/app_state.rs index af6af5bbf..7eeb28629 100644 --- a/src/app_state.rs +++ b/src/app_state.rs @@ -5,6 +5,9 @@ use alsa::card::Card; use alsa::mixer::{Mixer, SelemId, Selem}; use audio; use errors::*; +use std::rc::Rc; +use std::cell::RefCell; + // TODO: fix import use libc::pollfd; @@ -22,7 +25,7 @@ pub struct AlsaCard { pub card: Card, pub mixer: Mixer, pub selem_id: SelemId, - pub watch_ids: Vec, + pub watch_ids: Vec, } impl AlsaCard { @@ -37,20 +40,22 @@ impl AlsaCard { } }; let mixer = audio::get_mixer(&card)?; + let rc_mixer = RefCell::new(audio::get_mixer(&card)?); let selem_id = audio::get_selem_by_name( &mixer, elem_name.unwrap_or(String::from("Master")), ).unwrap() .get_id(); let vec_pollfd = PollDescriptors::get(&mixer)?; - // let watch_ids = + // let watch_ids = vec![]; + let watch_ids = audio::watch_poll_descriptors(vec_pollfd, rc_mixer); return Ok(AlsaCard { _cannot_construct: (), card: card, mixer: mixer, selem_id: selem_id, - watch_ids: vec![], + watch_ids: watch_ids, }); } diff --git a/src/audio.rs b/src/audio.rs index 44cdb859c..abb178057 100644 --- a/src/audio.rs +++ b/src/audio.rs @@ -1,4 +1,5 @@ extern crate alsa; +extern crate alsa_sys; extern crate glib_sys; use self::alsa::card::Card; @@ -8,11 +9,15 @@ use std::iter::Map; use libc::c_int; use libc::c_uint; use libc::c_void; +use libc::size_t; use errors::*; use std::convert::From; use libc::pollfd; use app_state; use std::cell::RefCell; +use std::mem; +use std::ptr; +use std::u8; @@ -121,24 +126,27 @@ pub fn set_mute(selem: &Selem, mute: bool) -> Result<()> { pub fn watch_poll_descriptors( polls: Vec, - acard: RefCell, + mixer: RefCell, ) -> Vec { let mut watch_ids: Vec = vec![]; + let mixer = unsafe { + mem::transmute::(mixer.into_inner()) + }; for poll in polls { unsafe { - let gioc = glib_sys::g_io_channel_unix_new(poll.fd); + let gioc: *mut glib_sys::GIOChannel = glib_sys::g_io_channel_unix_new(poll.fd); watch_ids.push(glib_sys::g_io_add_watch( gioc, - glib_sys::GIOCondition::from_bits_truncate( + glib_sys::GIOCondition::from_bits( glib_sys::G_IO_IN.bits() | glib_sys::G_IO_ERR.bits(), - ), + ).unwrap(), Some(watch_cb), - acard.as_ptr() as glib_sys::gpointer, + mixer as glib_sys::gpointer, )); } } - return vec![]; + return watch_ids; } extern "C" fn watch_cb( @@ -146,5 +154,42 @@ extern "C" fn watch_cb( cond: glib_sys::GIOCondition, data: glib_sys::gpointer, ) -> glib_sys::gboolean { + + // println!("Blah"); + // println!("GIOC: {:?}", chan); + + let mixer = data as *mut alsa_sys::snd_mixer_t; + + unsafe { + alsa_sys::snd_mixer_handle_events(mixer); + } + + if cond == glib_sys::G_IO_ERR { + return false as glib_sys::gboolean; + } + + // println!("GIOC (later): {:?}", chan); + let mut sread: usize = 1; + let mut buf: u8 = 0; + + while sread > 0 { + let stat = unsafe { glib_sys::g_io_channel_read_chars(chan, + &mut buf as *mut u8, + 250, + &mut sread as *mut size_t, + ptr::null_mut()) + }; + match stat { + glib_sys::G_IO_STATUS_AGAIN => continue, + glib_sys::G_IO_STATUS_NORMAL => (), + glib_sys::G_IO_STATUS_ERROR => (), + glib_sys::G_IO_STATUS_EOF => (), + _ => (), + } + return true as glib_sys::gboolean; + }; + return true as glib_sys::gboolean; } + + diff --git a/src/gui_callbacks.rs b/src/gui_callbacks.rs index ff807d5e1..ac07c0b59 100644 --- a/src/gui_callbacks.rs +++ b/src/gui_callbacks.rs @@ -13,6 +13,7 @@ use app_state::*; use errors::*; use std::cell::RefCell; use std::rc::Rc; +use audio; pub fn init<'a>(appstate: &'a AppS, rc_acard: Rc>) { @@ -55,7 +56,8 @@ fn init_popup_window(appstate: &AppS, rc_acard: Rc>) { popup_window.connect_show(move |_| { let acard = card.borrow(); - let cur_vol = try_w!(acard.vol()); + let cur_vol = try_w!(audio::get_vol(&acard.selem())); + println!("Cur vol: {}", cur_vol); gui::set_slider(&vol_scale_adj, cur_vol); let muted = acard.get_mute(); diff --git a/src/main.rs b/src/main.rs index d3bf9f32c..84eb97654 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,4 @@ + extern crate flexi_logger; #[macro_use] extern crate log; @@ -33,6 +34,11 @@ mod app_state; fn main() { gtk::init().unwrap(); + + let x = 4 / 0; + + println!("Zero: {}", x); + let ref apps = AppS { status_icon: gtk::StatusIcon::new_from_icon_name("pnmixer"), builder_popup: gtk::Builder::new_from_string( @@ -42,7 +48,7 @@ fn main() { let acard = Rc::new(RefCell::new( AlsaCard::new( - Some(String::from("Intel 82801AA-ICH")), + None, Some(String::from("Master")), ).unwrap(), ));