This commit is contained in:
Ospald, Julian 2017-06-28 17:53:19 +02:00
parent 6504c5c5ab
commit 4760355ef1
5 changed files with 122 additions and 7 deletions

View File

@ -9,6 +9,7 @@ libc = "^0.2.23"
gdk-sys = { git = "https://github.com/gtk-rs/sys" }
gtk-sys = { git = "https://github.com/gtk-rs/sys" }
glib = { git = "https://github.com/gtk-rs/glib.git" }
glib-sys = { git = "https://github.com/gtk-rs/sys" }
ffi = "^0.0.2"
flexi_logger = "^0.5.1"
log = "^0.3.8"

View File

@ -1,10 +1,14 @@
use gtk;
use alsa::poll::PollDescriptors;
use alsa::card::Card;
use alsa::mixer::{Mixer, SelemId, Selem};
use audio;
use errors::*;
// TODO: fix import
use libc::pollfd;
pub struct AppS {
/* we keep this to ensure the lifetime is across the whole application */
pub status_icon: gtk::StatusIcon,
@ -12,10 +16,13 @@ pub struct AppS {
pub builder_popup: gtk::Builder,
}
// TODO: implement free/destructor
pub struct AlsaCard {
card: Card,
mixer: Mixer,
selem_id: SelemId,
_cannot_construct: (),
pub card: Card,
pub mixer: Mixer,
pub selem_id: SelemId,
pub watch_ids: Vec<pollfd>,
}
impl AlsaCard {
@ -35,11 +42,15 @@ impl AlsaCard {
elem_name.unwrap_or(String::from("Master")),
).unwrap()
.get_id();
let vec_pollfd = PollDescriptors::get(&mixer)?;
// let watch_ids =
return Ok(AlsaCard {
_cannot_construct: (),
card: card,
mixer: mixer,
selem_id: selem_id,
watch_ids: vec![],
});
}
@ -53,6 +64,10 @@ impl AlsaCard {
return audio::get_vol(&self.selem());
}
pub fn set_vol(&self, new_vol: f64) -> Result<()> {
return audio::set_vol(&self.selem(), new_vol);
}
pub fn has_mute(&self) -> bool {
return audio::has_mute(&self.selem());
}
@ -65,3 +80,19 @@ impl AlsaCard {
return audio::set_mute(&self.selem(), mute);
}
}
pub enum AudioUser {
AudioUserUnknown,
AudioUserPopup,
AudioUserTrayIcon,
AudioUserHotkeys,
}
enum AudioSignal {
AudioNoCard,
AudioCardInitialized,
AudioCardCleanedUp,
AudioCardDisconnected,
AudioCardError,
AudioValuesChanged,
}

View File

@ -1,13 +1,18 @@
extern crate alsa;
extern crate libc;
extern crate glib_sys;
use self::alsa::card::Card;
use self::alsa::mixer::{Mixer, Selem, Elem};
use alsa::mixer::SelemChannelId::*;
use std::iter::Map;
use self::libc::c_int;
use libc::c_int;
use libc::c_uint;
use libc::c_void;
use errors::*;
use std::convert::From;
use libc::pollfd;
use app_state;
use std::cell::RefCell;
@ -60,15 +65,41 @@ pub fn get_selem_by_name(mixer: &Mixer, name: String) -> Result<Selem> {
bail!("Not found a matching selem named {}", name);
}
pub fn vol_to_percent(vol: i64, range: (i64, i64)) -> f64 {
let (min, max) = range;
return ((vol - min) as f64) / ((max - min) as f64) * 100.0;
}
pub fn percent_to_vol(vol: f64, range: (i64, i64)) -> i64 {
let (min, max) = range;
let _v = vol / 100.0 * ((max - min) as f64) + (min as f64);
/* TODO: precision? Use direction. */
return _v as i64;
}
pub fn get_vol(selem: &Selem) -> Result<f64> {
let (min, max) = selem.get_playback_volume_range();
let range = selem.get_playback_volume_range();
let volume = selem.get_playback_volume(FrontRight).map(|v| {
return ((v - min) as f64) / ((max - min) as f64) * 100.0;
return vol_to_percent(v, range);
});
return volume.cherr();
}
pub fn set_vol(selem: &Selem, new_vol: f64) -> Result<()> {
/* auto-unmute */
if get_mute(selem)? {
set_mute(selem, false)?;
}
let range = selem.get_playback_volume_range();
selem.set_playback_volume_all(
percent_to_vol(new_vol, range),
)?;
return Ok(());
}
pub fn has_mute(selem: &Selem) -> bool {
return selem.has_playback_switch();
}
@ -83,3 +114,37 @@ pub fn set_mute(selem: &Selem, mute: bool) -> Result<()> {
let _ = selem.set_playback_switch_all(!mute as i32)?;
return Ok(());
}
/* GIO */
pub fn watch_poll_descriptors(
polls: Vec<pollfd>,
acard: RefCell<app_state::AlsaCard>,
) -> Vec<c_uint> {
let mut watch_ids: Vec<c_uint> = vec![];
for poll in polls {
unsafe {
let gioc = 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::G_IO_IN.bits() | glib_sys::G_IO_ERR.bits(),
),
Some(watch_cb),
acard.as_ptr() as glib_sys::gpointer,
));
}
}
return vec![];
}
extern "C" fn watch_cb(
chan: *mut glib_sys::GIOChannel,
cond: glib_sys::GIOCondition,
data: glib_sys::gpointer,
) -> glib_sys::gboolean {
return true as glib_sys::gboolean;
}

View File

@ -63,6 +63,23 @@ fn init_popup_window(appstate: &AppS, rc_acard: Rc<RefCell<AlsaCard>>) {
});
}
/* vol_scale_adj.connect_value_changed */
{
let vol_scale_adj: Rc<gtk::Adjustment> =
Rc::new(
appstate.builder_popup.get_object("vol_scale_adj").unwrap(),
);
let card = rc_acard.clone();
let vol_scale = vol_scale_adj.clone();
vol_scale_adj.connect_value_changed(move |_| {
let acard = card.borrow();
let val = vol_scale.get_value();
try_w!(acard.set_vol(val));
});
}
/* mute_check.connect_toggled */
{
let mute_check: gtk::CheckButton =

View File

@ -10,6 +10,7 @@ extern crate gtk_sys;
extern crate gdk;
extern crate gdk_sys;
extern crate alsa;
extern crate libc;
use gtk::prelude::*;
use gdk_sys::GDK_KEY_Escape;