commit 342bdc38fdbf97e6744500295b26500fc8ff4a3b Author: Julian Ospald Date: Mon Jun 26 09:08:37 2017 +0200 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..eb5a316cb --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +target diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 000000000..78a3e34ef --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "pnmixer" +version = "0.1.0" +authors = ["Julian Ospald "] + +[dependencies] +alsa = "0.1.8" +gdk = "0.5.0" +lazy_static = "0.1.*" + +[dependencies.gtk] +version = "0.1.0" +features = [ "v3_10" ] diff --git a/data/desktop/pnmixer.desktop.in b/data/desktop/pnmixer.desktop.in new file mode 100644 index 000000000..830d1d131 --- /dev/null +++ b/data/desktop/pnmixer.desktop.in @@ -0,0 +1,10 @@ +[Desktop Entry] +Name=PNMixer +_GenericName=System Tray Mixer +_Comment=An audio mixer for the system tray +Exec=pnmixer +TryExec=pnmixer +Icon=pnmixer +Terminal=false +Type=Application +Categories=AudioVideo; diff --git a/data/icons/pnmixer.png b/data/icons/pnmixer.png new file mode 100644 index 000000000..0f5189123 Binary files /dev/null and b/data/icons/pnmixer.png differ diff --git a/data/pixmaps/pnmixer-about.png b/data/pixmaps/pnmixer-about.png new file mode 100644 index 000000000..0f5189123 Binary files /dev/null and b/data/pixmaps/pnmixer-about.png differ diff --git a/data/pixmaps/pnmixer-high.png b/data/pixmaps/pnmixer-high.png new file mode 100644 index 000000000..072ffd5e0 Binary files /dev/null and b/data/pixmaps/pnmixer-high.png differ diff --git a/data/pixmaps/pnmixer-low.png b/data/pixmaps/pnmixer-low.png new file mode 100644 index 000000000..8cf510ebb Binary files /dev/null and b/data/pixmaps/pnmixer-low.png differ diff --git a/data/pixmaps/pnmixer-medium.png b/data/pixmaps/pnmixer-medium.png new file mode 100644 index 000000000..fab9749d3 Binary files /dev/null and b/data/pixmaps/pnmixer-medium.png differ diff --git a/data/pixmaps/pnmixer-muted.png b/data/pixmaps/pnmixer-muted.png new file mode 100644 index 000000000..8aec465b8 Binary files /dev/null and b/data/pixmaps/pnmixer-muted.png differ diff --git a/data/pixmaps/pnmixer-off.png b/data/pixmaps/pnmixer-off.png new file mode 100644 index 000000000..531fde8e1 Binary files /dev/null and b/data/pixmaps/pnmixer-off.png differ diff --git a/data/ui/hotkey-dialog.glade b/data/ui/hotkey-dialog.glade new file mode 100644 index 000000000..01ab71204 --- /dev/null +++ b/data/ui/hotkey-dialog.glade @@ -0,0 +1,190 @@ + + + + + + 300 + 200 + False + 5 + Set xxx HotKey + True + True + input-keyboard + dialog + + + + + True + False + 2 + + + True + False + end + + + False + True + True + True + + + True + False + center + + + True + False + gtk-cancel + + + False + True + 0 + + + + + True + False + 5 + Cancel + + + False + True + 1 + + + + + + + False + False + 0 + + + + + False + True + end + 3 + + + + + True + False + + + True + False + 10 + 10 + 57 + input-keyboard + 3 + + + False + False + 0 + + + + + True + False + vertical + + + True + False + Defining HotKey + + + + + + True + True + 0 + + + + + True + False + (press <Ctrl>C to reset) + + + True + True + 1 + + + + + True + True + 1 + + + + + False + True + 0 + + + + + True + False + + + False + True + 1 + + + + + True + False + Press new HotKey for xxx + True + + + True + True + 2 + + + + + True + False + + + + + + True + True + 4 + + + + + + button1 + + + diff --git a/data/ui/popup-menu.glade b/data/ui/popup-menu.glade new file mode 100644 index 000000000..b98e43b17 --- /dev/null +++ b/data/ui/popup-menu.glade @@ -0,0 +1,271 @@ + + + + + + False + popup + False + mouse + utility + True + True + False + + + False + + + False + True + False + _Popup + True + + + True + False + + + False + True + False + Mute/Unmute Volume + + + + True + False + + + False + True + True + False + center + True + + + 0 + + + + + True + False + 4 + 8 + Mute + + + 1 + + + + + + + + + False + True + False + Open Volume Control + + + + True + False + + + True + False + system-run + + + 0 + + + + + True + False + 4 + 8 + Volume Control + + + 1 + + + + + + + + + False + True + False + Preferences + + + + True + False + + + True + False + preferences-desktop + 1 + + + 0 + + + + + True + False + 4 + 8 + Preferences + + + 1 + + + + + + + + + False + True + False + Reload Sound + + + + True + False + + + True + False + gtk-refresh + 1 + + + 0 + + + + + True + False + 4 + 8 + Reload Sound + + + 1 + + + + + + + + + False + True + False + About + + + + True + False + + + True + False + help-about + 1 + + + 0 + + + + + True + False + 4 + 8 + About + + + 1 + + + + + + + + + False + True + False + + + + + False + True + False + Quit + + + + True + False + + + True + False + gtk-quit + 1 + + + 0 + + + + + True + False + 4 + 8 + Quit + + + 1 + + + + + + + + + + + + + + diff --git a/data/ui/popup-window-horizontal.glade b/data/ui/popup-window-horizontal.glade new file mode 100644 index 000000000..5e095c1ca --- /dev/null +++ b/data/ui/popup-window-horizontal.glade @@ -0,0 +1,103 @@ + + + + + + 100 + 1 + 10 + + + popup + False + False + mouse + utility + True + True + False + + + + + + True + False + vertical + 8 + 12 + + + True + True + horizontal + vol_scale_adj + False + 0 + 0 + 200 + + + + True + True + 0 + + + + + True + False + + + Mute + False + True + True + False + True + + + + False + False + 0 + + + + + True + False + + + True + True + 1 + + + + + Mixer + False + True + True + True + + + + False + False + 2 + + + + + False + False + 1 + + + + + + diff --git a/data/ui/popup-window-vertical.glade b/data/ui/popup-window-vertical.glade new file mode 100644 index 000000000..1271dabdc --- /dev/null +++ b/data/ui/popup-window-vertical.glade @@ -0,0 +1,94 @@ + + + + + + 100 + 1 + 10 + + + popup + False + False + mouse + utility + True + True + False + + + + + + True + False + vertical + 8 + 12 + + + True + True + vertical + vol_scale_adj + True + 0 + 0 + 200 + + + + True + True + 0 + + + + + True + False + vertical + 4 + + + Mute + False + True + True + False + True + + + + False + False + 0 + + + + + Mixer + False + True + True + True + + + + False + False + 1 + + + + + False + False + 1 + + + + + + diff --git a/data/ui/prefs-dialog.glade b/data/ui/prefs-dialog.glade new file mode 100644 index 000000000..9e9a4dc61 --- /dev/null +++ b/data/ui/prefs-dialog.glade @@ -0,0 +1,1225 @@ + + + + + + True + False + start + vertical + 5 + + + True + False + center + Notification support disabled at compile time. + + + + + + + + 1000000000 + 100 + 10 + + + True + False + start + vertical + 5 + + + True + False + none + + + True + False + 12 + 2 + 2 + 15 + + + Enable Notifications + False + True + True + False + start + True + + + + GTK_EXPAND + + + + + True + False + start + Timeout (ms): + + + 1 + 2 + GTK_EXPAND + + + + + True + True + False + False + noti_timeout_adjustment + + + 1 + 2 + 1 + 2 + GTK_EXPAND + + + + + + + True + False + 5 + <b>Notification Options</b> + True + + + + + False + False + 5 + 0 + + + + + True + False + none + + + True + False + vertical + 12 + 3 + + + HotKeys + False + True + True + False + start + True + + + True + True + 0 + + + + + Mouse Scroll + False + True + True + False + start + True + + + True + True + 1 + + + + + Adjustment in Popups + False + True + True + False + start + True + + + True + True + 2 + + + + + External Change + False + True + True + False + start + True + + + True + True + 3 + + + + + + + True + False + 5 + <b>Notify for volume changes from:</b> + True + + + + + False + False + 5 + 1 + + + + + 100 + 1 + 10 + + + 100 + 1 + 10 + + + 100 + 10 + 10 + + + False + dialog + PNMixer Preferences + False + preferences-system + + + True + False + vertical + 2 + + + True + False + 10 + end + + + False + True + True + True + + + True + False + center + + + True + False + gtk-cancel + + + False + True + 0 + + + + + True + False + 5 + Cancel + + + False + True + 1 + + + + + + + False + False + 0 + + + + + False + True + True + True + + + True + False + center + + + True + False + gtk-ok + + + False + True + 0 + + + + + True + False + 5 + Ok + + + False + True + 1 + + + + + + + + + False + True + 1 + + + + + True + True + False + + + True + False + start + vertical + 5 + + + True + False + none + + + True + False + 12 + 3 + 2 + 15 + + + True + False + start + Slider Orientation: + + + GTK_EXPAND + + + + + True + False + 0 + + Vertical + Horizontal + + + + 1 + 2 + GTK_EXPAND + + + + + Display Text Volume + False + True + True + False + start + True + + + + 2 + 1 + 2 + GTK_EXPAND + + + + + True + False + Text Volume Position: + start + + + 2 + 3 + GTK_EXPAND + + + + + True + False + 0 + + Top + Bottom + Left + Right + + + + 1 + 2 + 2 + 3 + GTK_EXPAND + + + + + + + True + False + 5 + <b>Volume Popup</b> + True + + + + + False + False + 5 + 0 + + + + + True + False + none + + + True + False + 12 + 3 + 2 + 15 + + + Draw Volume Meter on Tray Icon + False + True + True + False + start + True + + + + 2 + GTK_EXPAND + + + + + True + False + Volume Meter Offset (%): + start + + + 1 + 2 + GTK_EXPAND + + + + + True + False + Volume Meter Color: + start + + + 2 + 3 + GTK_EXPAND + + + + + True + True + + False + False + vol_meter_pos_adjustment + 0.050000000000000003 + True + + + 1 + 2 + 1 + 2 + GTK_EXPAND + + + + + False + True + True + True + rgb(0,0,0) + + + 1 + 2 + 2 + 3 + GTK_EXPAND + + + + + + + True + False + 5 + <b>Volume Meter</b> + True + + + + + False + False + 5 + 1 + + + + + True + False + none + + + Use System Theme + False + True + True + False + 12 + start + True + + + + + True + False + 5 + <b>Icon Theme</b> + True + + + + + False + False + 5 + 2 + + + + + + + True + False + View + + + False + + + + + True + False + start + vertical + 5 + + + True + False + none + + + True + False + 12 + 3 + 2 + 15 + + + True + False + Card: + start + + + GTK_EXPAND + + + + + True + False + Channel: + start + + + 1 + 2 + GTK_EXPAND + + + + + True + False + + + + 1 + 2 + GTK_EXPAND + + + + + True + False + + + 1 + 2 + 1 + 2 + GTK_EXPAND + + + + + True + True + False + True + + + + + + 1 + 2 + 2 + 3 + GTK_EXPAND + + + + + True + False + Normalize Volume: + start + Change volume on a logarithmic scale, closer to human perception. + + + 2 + 3 + + + + + + + True + False + 5 + <b>Sound Device</b> + True + + + + + False + False + 5 + + + + + 1 + + + + + True + False + Device + + + 1 + False + + + + + True + False + start + vertical + 5 + + + True + False + none + + + True + True + 12 + + False + False + + + + + True + False + 5 + <b>Volume Control Command</b> + True + + + + + False + False + 5 + 0 + + + + + True + False + none + + + True + False + 12 + 2 + 2 + 5 + 15 + + + True + False + Scroll Step: + start + + + GTK_EXPAND + + + + + True + False + Fine Scroll Step: + start + + + 1 + 2 + GTK_EXPAND + + + + + True + True + 2 + True + + False + False + scroll_step_adjustment + + + 1 + 2 + GTK_EXPAND + + + + + True + True + 2 + True + + False + False + fine_scroll_step_adjustment + + + 1 + 2 + 1 + 2 + GTK_EXPAND + + + + + + + True + False + 5 + <b>Volume Scrolling</b> + True + + + + + False + False + 5 + 1 + + + + + True + False + none + + + True + False + 12 + 2 + 2 + 5 + 15 + + + True + False + Middle Click Action: + start + + + GTK_EXPAND + + + + + True + False + Custom Command: + start + + + 1 + 2 + GTK_EXPAND + + + + + True + False + + Mute/Unmute + Show Preferences + Volume Control + Custom (set below) + + + + + 1 + 2 + GTK_EXPAND + + + + + True + True + + False + False + + + 1 + 2 + 1 + 2 + GTK_EXPAND + + + + + + + True + False + 5 + <b>Mouse</b> + True + + + + + False + False + 5 + 2 + + + + + 2 + + + + + True + False + Behavior + + + 2 + False + + + + + True + False + start + vertical + 5 + + + True + False + none + + + True + False + vertical + 12 + + + Enable HotKeys + False + True + True + False + start + True + + + + False + False + 5 + 0 + + + + + True + False + 5 + 5 + 2 + 15 + + + True + False + Command + start + + + + + + + + True + False + Mute/Unmute: + start + + + 1 + 2 + + + + + True + False + Volume Up: + start + + + 2 + 3 + + + + + True + False + Volume Down: + start + + + 3 + 4 + + + + + True + False + Double-click a HotKey to assign a new HotKey + + + 2 + 4 + 5 + + + + + True + False + HotKey + + + + + + 1 + 2 + + + + + True + False + + + + True + False + (None) + + + + + + + + 1 + 2 + 1 + 2 + + + + + True + False + + + + True + False + (None) + + + + + + + + 1 + 2 + 2 + 3 + + + + + True + False + + + + True + False + (None) + + + + + + + + 1 + 2 + 3 + 4 + + + + + False + False + 5 + 1 + + + + + + + True + False + 5 + <b>HotKey Settings</b> + True + + + + + False + False + 5 + 0 + + + + + 3 + + + + + True + False + HotKeys + + + 3 + False + + + + + True + True + 5 + 1 + + + + + + ok_button + cancel_button + + + diff --git a/src/audio.rs b/src/audio.rs new file mode 100644 index 000000000..2c779b29e --- /dev/null +++ b/src/audio.rs @@ -0,0 +1,50 @@ +extern crate alsa; + +use self::alsa::card::{Card}; +use self::alsa::mixer::{Mixer, Selem}; + + + +pub fn get_default_alsa_card() -> Card { + let default_card: Card = Card::new(0); + + return default_card; +} + +pub fn get_mixer(card: Card) -> Mixer { + let mixer = Mixer::new(&format!("hw:{}", card.get_index()), + false).unwrap(); + + for elem in mixer.iter() { + let selem: Selem = Selem::new(elem).unwrap(); + println!("Elem: {}", selem.get_id().get_name().unwrap()); + } + + return mixer; +} + +pub fn get_channels(mixer: &Mixer) -> alsa::mixer::Iter { + return mixer.iter(); +} + +pub fn get_channel_by_name<'a>(mixer: &'a Mixer, name: String) -> Option> { + for elem in mixer.iter() { + let m_selem = Selem::new(elem); + let m_name = m_selem.and_then(|x| x.get_id().get_name().ok()); + let retval = m_name.map_or(false, |n| { + return n == name; + }); + + if retval { + return Selem::new(elem); + } + } + + return None; +} + + +// pub fn list_channels(card: Card, hctl: HCtl) -> [str] { + +// } + diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 000000000..430d4689a --- /dev/null +++ b/src/main.rs @@ -0,0 +1,71 @@ +extern crate gtk; +extern crate gdk; +extern crate alsa; + +// #[macro_use] +// extern crate lazy_static; + +// use gdk::EventButton; +// use gdk::EventType; + + +// use std::ops::Deref; + +// use std::boxed::Box; +// use std::rc::Rc; +// use std::sync::Arc; + +use gtk::prelude::*; + +use alsa::mixer::SelemChannelId::*; + +mod audio; + + +fn main() { + gtk::init().unwrap(); + + let tray_icon = gtk::StatusIcon::new_from_icon_name("pnmixer"); + + let glade_src = include_str!("../data/ui/popup-window-vertical.glade"); + let builder_popup = gtk::Builder::new_from_string(glade_src); + + let popup_window: gtk::Window = builder_popup.get_object("popup_window").unwrap(); + + // let builder_prefs_dialog = Rc::new(Builder::new_from_file("data/ui/prefs-dialog.glade")); + + // with_builder!(builder_popup_window, + // tray_icon.connect_activate(move |_| { + // let popup_window: gtk::Window = builder + // .get_object("popup_window").unwrap(); + // popup_window.show_all(); + // }) + // ); + + // 2nd binding + + tray_icon.connect_button_press_event(move |_, e| { + let bt = e.as_ref().button; + match bt { + 3 => { + popup_window.show_all(); + return true; + } + _ => { + println!("Blah"); + return false; + } + } + }); + + let alsa_card = audio::get_default_alsa_card(); + let mixer = audio::get_mixer(alsa_card); + let channel = audio::get_channel_by_name(&mixer, String::from("Master")).unwrap(); + + println!("Range: {:?}", channel.get_playback_volume_range()); + println!("Channel: {}", channel.get_playback_volume(FrontCenter).unwrap()); + + tray_icon.set_visible(true); + + gtk::main(); +}