diff --git a/.gitignore b/.gitignore index eb5a316cb..afc990127 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ target +Cargo.lock +*.bk diff --git a/Cargo.toml b/Cargo.toml index a3f2f0afa..8746b6577 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,10 +6,17 @@ authors = ["Julian Ospald "] [dependencies] alsa = "0.1.8" libc = "0.2.23" -gdk = "0.5.3" -gdk-sys = "0.3.4" -gtk-sys = "0.3.4" +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" } +ffi = "0.0.2" +flexi_logger = "^0.5.1" +log = "0.3.8" [dependencies.gtk] -git = 'https://github.com/gtk-rs/gtk.git' -features = [ "v3_12", "v3_22" ] +git = "https://github.com/gtk-rs/gtk.git" +features = [ "v3_10", "v3_12", "v3_22" ] + +[dependencies.gdk] +git = "https://github.com/gtk-rs/gdk.git" +features = [ "v3_10", "v3_12", "v3_22" ] diff --git a/src/audio.rs b/src/audio.rs index 4e3eec4c2..bc5b54671 100644 --- a/src/audio.rs +++ b/src/audio.rs @@ -2,7 +2,7 @@ extern crate alsa; extern crate std; extern crate libc; -use self::alsa::card::{Card}; +use self::alsa::card::Card; use self::alsa::mixer::{Mixer, Selem, Elem}; use alsa::mixer::SelemChannelId::*; use std::iter::Map; @@ -23,8 +23,7 @@ pub fn get_alsa_cards() -> alsa::card::Iter { } pub fn get_mixer(card: Card) -> Mixer { - let mixer = Mixer::new(&format!("hw:{}", card.get_index()), - false).unwrap(); + let mixer = Mixer::new(&format!("hw:{}", card.get_index()), false).unwrap(); return mixer; } @@ -35,10 +34,11 @@ pub fn get_selems(mixer: &Mixer) -> Map Selem> { pub fn get_selem_by_name<'a>(mixer: &'a Mixer, name: String) -> Option { for selem in get_selems(mixer) { - let m_name = selem.get_id().get_name().map(|y| String::from(y)).ok(); - let retval = m_name.map_or(false, |n| { - return n == name; - }); + let m_name = selem.get_id() + .get_name() + .map(|y| String::from(y)) + .ok(); + let retval = m_name.map_or(false, |n| { return n == name; }); if retval { return Some(selem); @@ -67,4 +67,3 @@ pub fn get_selem(elem: Elem) -> Selem { // pub fn list_channels(card: Card, hctl: HCtl) -> [str] { // } - diff --git a/src/gui.rs b/src/gui.rs index edf54c87c..34070edd2 100644 --- a/src/gui.rs +++ b/src/gui.rs @@ -1,9 +1,58 @@ extern crate gtk; +extern crate gtk_sys; extern crate gdk; +extern crate gdk_sys; +extern crate glib; +extern crate ffi; +extern crate libc; use gtk::prelude::*; +use gdk::DeviceExt; +use gdk::{GrabOwnership, GrabStatus, BUTTON_PRESS_MASK, KEY_PRESS_MASK}; +use gdk_sys::GDK_CURRENT_TIME; -pub fn set_slider(vol_scale_adj: & gtk::Adjustment, scale: f64) { +pub fn set_slider(vol_scale_adj: >k::Adjustment, scale: f64) { vol_scale_adj.set_value(scale); } +pub fn grab_devices(window: >k::Window) { + let m_device = gtk::get_current_event_device(); + if m_device.is_none() { + warn!("Couldn't get current device"); + return; + } + + let device = m_device.unwrap(); + let gdk_window = window.get_window().unwrap(); + + /* Grab the mouse */ + let m_grab_status = + device.grab(&gdk_window, + GrabOwnership::None, + true, + BUTTON_PRESS_MASK, + None, + GDK_CURRENT_TIME as u32); + + if m_grab_status != GrabStatus::Success { + warn!("Could not grab {}", device.get_name().unwrap()); + } + + /* Grab the keyboard */ + let m_k_dev = device.get_associated_device(); + if m_k_dev.is_none() { + warn!("Couldn't get associated device"); + return; + } + let k_dev = m_k_dev.unwrap(); + + let k_grab_status = k_dev.grab(&gdk_window, + GrabOwnership::None, + true, + KEY_PRESS_MASK, + None, + GDK_CURRENT_TIME as u32); + if k_grab_status != GrabStatus::Success { + warn!("Could not grab {}", k_dev.get_name().unwrap()) + } +} diff --git a/src/main.rs b/src/main.rs index 2194af8b5..1230b2abf 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,15 +1,13 @@ +extern crate flexi_logger; +#[macro_use] +extern crate log; + extern crate gtk; +extern crate gtk_sys; extern crate gdk; extern crate gdk_sys; extern crate alsa; -// #[macro_use] -// extern crate lazy_static; - -// use gdk::EventButton; -// use gdk::EventType; - - // use std::ops::Deref; // use std::boxed::Box; @@ -18,9 +16,7 @@ extern crate alsa; use gtk::prelude::*; -use alsa::mixer::SelemChannelId::*; -use gdk::EventType; use gdk_sys::GDK_KEY_Escape; @@ -31,54 +27,66 @@ mod gui; fn main() { gtk::init().unwrap(); + flexi_logger::LogOptions::new() + .log_to_file(false) + // ... your configuration options go here ... + .init(Some("info".to_string())) + .unwrap_or_else(|e| panic!("Logger initialization failed with {}", e)); + 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 vol_scale: gtk::Scale = builder_popup.get_object("vol_scale").unwrap(); + let popup_window: gtk::Window = builder_popup.get_object("popup_window") + .unwrap(); + let vol_scale: gtk::Scale = builder_popup.get_object("vol_scale") + .unwrap(); - tray_icon.connect_activate(move |_| { - if popup_window.get_visible() { - popup_window.hide(); - } else { - popup_window.show_all(); - vol_scale.grab_focus(); - } - }); + tray_icon.connect_activate(move |_| if popup_window.get_visible() { + popup_window.hide(); + } else { + popup_window.show_now(); + vol_scale.grab_focus(); + gui::grab_devices(&popup_window); + }); } - { - let popup_window: gtk::Window = builder_popup.get_object("popup_window").unwrap(); - let vol_scale_adj: gtk::Adjustment = builder_popup.get_object("vol_scale_adj").unwrap(); + let popup_window: gtk::Window = builder_popup.get_object("popup_window") + .unwrap(); + let vol_scale_adj: gtk::Adjustment = builder_popup.get_object("vol_scale_adj") + .unwrap(); popup_window.connect_show(move |_| { let alsa_card = audio::get_default_alsa_card(); let mixer = audio::get_mixer(alsa_card); - let selem = audio::get_selem_by_name(&mixer, String::from("Master")).unwrap(); + let selem = audio::get_selem_by_name(&mixer, + String::from("Master")) + .unwrap(); gui::set_slider(&vol_scale_adj, audio::get_vol(selem).unwrap()) }); } { - let popup_window: gtk::Window = builder_popup.get_object("popup_window").unwrap(); + let popup_window: gtk::Window = builder_popup.get_object("popup_window") + .unwrap(); popup_window.connect_event(move |w, e| { match gdk::Event::get_event_type(e) { gdk::EventType::GrabBroken => w.hide(), gdk::EventType::KeyPress => { - println!("BLAH"); let key: gdk::EventKey = e.clone().downcast().unwrap(); if key.get_keyval() == (GDK_KEY_Escape as u32) { w.hide(); } - }, + } gdk::EventType::ButtonPress => { - unsafe { - let device = gtk::functions::get_current_event_device(); - let (_, x, y) = gdk::Device::get_window_at_position(device); - }; - }, + let device = gtk::get_current_event_device().unwrap(); + let (window, _, _) = + gdk::DeviceExt::get_window_at_position(&device); + if window.is_none() { + w.hide(); + } + } _ => (), } @@ -86,22 +94,7 @@ fn main() { }); } - // let alsa_card = audio::get_default_alsa_card(); - // let mixer = audio::get_mixer(alsa_card); - // let elem = audio::get_selem_by_name(&mixer, String::from("Master")).unwrap(); - - // for s in audio::get_selems(&mixer) { - // println!("Name: {}", s.get_id().get_name().unwrap()); - // } - - // println!("Range: {:?}", channel.get_playback_volume_range()); - // println!("Name: {}", elem.get_id().get_name().unwrap()); - // println!("Channel: {}", channel.get_playback_volume(FrontRight).unwrap()); - // println!("Volume: {}", audio::get_vol(elem).unwrap()); - tray_icon.set_visible(true); gtk::main(); } - -