2017-06-27 22:23:12 +00:00
|
|
|
use app_state::*;
|
2017-07-03 21:38:39 +00:00
|
|
|
use audio::*;
|
2017-06-27 22:23:12 +00:00
|
|
|
use errors::*;
|
2017-06-29 12:55:07 +00:00
|
|
|
use gdk::DeviceExt;
|
|
|
|
use gdk::{GrabOwnership, GrabStatus, BUTTON_PRESS_MASK, KEY_PRESS_MASK};
|
2017-06-29 12:25:40 +00:00
|
|
|
use gdk;
|
2017-06-29 12:55:07 +00:00
|
|
|
use gdk_sys::{GDK_KEY_Escape, GDK_CURRENT_TIME};
|
2017-06-30 15:24:26 +00:00
|
|
|
use glib;
|
2017-06-29 12:25:40 +00:00
|
|
|
use gtk::prelude::*;
|
|
|
|
use gtk;
|
2017-06-28 12:55:38 +00:00
|
|
|
use std::rc::Rc;
|
2017-06-27 22:23:12 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
2017-06-30 15:24:26 +00:00
|
|
|
pub fn init_popup_window(appstate: Rc<AppS>) {
|
|
|
|
let mut toggle_signal = 0;
|
|
|
|
|
|
|
|
/* mute_check.connect_toggled */
|
2017-06-27 22:23:12 +00:00
|
|
|
{
|
2017-06-30 15:24:26 +00:00
|
|
|
let _appstate = appstate.clone();
|
2017-07-06 14:53:19 +00:00
|
|
|
let mute_check = &appstate.clone().gui.popup_window.mute_check;
|
|
|
|
toggle_signal = mute_check.connect_toggled(
|
|
|
|
move |_| on_mute_check_toggled(&_appstate),
|
|
|
|
);
|
2017-06-27 22:23:12 +00:00
|
|
|
}
|
|
|
|
|
2017-06-30 15:24:26 +00:00
|
|
|
/* popup_window.connect_show */
|
2017-06-28 15:53:19 +00:00
|
|
|
{
|
2017-06-30 15:24:26 +00:00
|
|
|
let _appstate = appstate.clone();
|
2017-07-06 14:53:19 +00:00
|
|
|
let popup_window = &appstate.clone().gui.popup_window.popup_window;
|
|
|
|
popup_window.connect_show(
|
|
|
|
move |w| on_popup_window_show(w, &_appstate, toggle_signal),
|
|
|
|
);
|
2017-06-28 15:53:19 +00:00
|
|
|
}
|
|
|
|
|
2017-06-30 15:24:26 +00:00
|
|
|
/* vol_scale_adj.connect_value_changed */
|
2017-06-27 22:23:12 +00:00
|
|
|
{
|
2017-06-30 15:24:26 +00:00
|
|
|
let _appstate = appstate.clone();
|
2017-07-06 14:53:19 +00:00
|
|
|
let vol_scale_adj = &appstate.clone().gui.popup_window.vol_scale_adj;
|
2017-06-30 15:24:26 +00:00
|
|
|
vol_scale_adj.connect_value_changed(
|
|
|
|
move |_| on_vol_scale_value_changed(&_appstate),
|
|
|
|
);
|
2017-06-27 22:23:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* popup_window.connect_event */
|
|
|
|
{
|
2017-06-30 15:24:26 +00:00
|
|
|
let _appstate = appstate.clone();
|
2017-07-06 14:53:19 +00:00
|
|
|
let popup_window = &appstate.clone().gui.popup_window.popup_window;
|
2017-06-27 22:23:12 +00:00
|
|
|
popup_window.connect_event(move |w, e| {
|
2017-07-06 14:53:19 +00:00
|
|
|
on_popup_window_event(w, e, &_appstate)
|
|
|
|
});
|
2017-06-27 22:23:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-29 12:55:07 +00:00
|
|
|
|
2017-07-06 14:53:19 +00:00
|
|
|
fn on_popup_window_show(
|
|
|
|
window: >k::Window,
|
|
|
|
appstate: &AppS,
|
|
|
|
toggle_signal: u64,
|
|
|
|
) {
|
2017-07-01 22:03:21 +00:00
|
|
|
let audio = &appstate.audio;
|
2017-06-30 15:24:26 +00:00
|
|
|
let popup_window = &appstate.gui.popup_window;
|
|
|
|
|
2017-07-01 22:03:21 +00:00
|
|
|
let cur_vol = try_w!(audio.vol());
|
2017-06-30 15:24:26 +00:00
|
|
|
set_slider(&popup_window.vol_scale_adj, cur_vol);
|
|
|
|
|
2017-07-01 22:03:21 +00:00
|
|
|
let muted = audio.get_mute();
|
2017-06-30 15:24:26 +00:00
|
|
|
update_mute_check(&appstate, toggle_signal, muted);
|
|
|
|
|
|
|
|
popup_window.vol_scale.grab_focus();
|
2017-06-30 19:10:33 +00:00
|
|
|
try_w!(grab_devices(window));
|
2017-06-30 15:24:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-07-06 14:53:19 +00:00
|
|
|
fn on_popup_window_event(
|
|
|
|
w: >k::Window,
|
|
|
|
e: &gdk::Event,
|
|
|
|
appstate: &AppS,
|
|
|
|
) -> gtk::Inhibit {
|
2017-06-30 15:24:26 +00:00
|
|
|
match gdk::Event::get_event_type(e) {
|
|
|
|
gdk::EventType::GrabBroken => w.hide(),
|
|
|
|
gdk::EventType::KeyPress => {
|
|
|
|
let key: gdk::EventKey = e.clone().downcast().unwrap();
|
|
|
|
if key.get_keyval() == (GDK_KEY_Escape as u32) {
|
|
|
|
w.hide();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
gdk::EventType::ButtonPress => {
|
|
|
|
let device = try_wr!(
|
|
|
|
gtk::get_current_event_device().ok_or(
|
|
|
|
"No current event device!",
|
|
|
|
),
|
|
|
|
Inhibit(false)
|
|
|
|
);
|
|
|
|
let (window, _, _) =
|
|
|
|
gdk::DeviceExt::get_window_at_position(&device);
|
|
|
|
if window.is_none() {
|
|
|
|
w.hide();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_ => (),
|
|
|
|
}
|
|
|
|
|
|
|
|
return Inhibit(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn on_vol_scale_value_changed(appstate: &AppS) {
|
2017-07-01 22:03:21 +00:00
|
|
|
let audio = &appstate.audio;
|
2017-06-30 15:24:26 +00:00
|
|
|
|
2017-07-06 14:53:19 +00:00
|
|
|
let val = appstate.gui.popup_window.vol_scale.get_value();
|
2017-06-30 15:24:26 +00:00
|
|
|
|
2017-07-03 21:38:39 +00:00
|
|
|
try_w!(audio.set_vol(val, AudioUser::Popup));
|
2017-06-30 15:24:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn on_mute_check_toggled(appstate: &AppS) {
|
2017-07-01 22:03:21 +00:00
|
|
|
let audio = &appstate.audio;
|
2017-07-03 21:52:41 +00:00
|
|
|
try_w!(audio.toggle_mute(AudioUser::Popup))
|
2017-06-30 15:24:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-07-06 14:53:19 +00:00
|
|
|
pub fn update_mute_check(
|
|
|
|
appstate: &AppS,
|
|
|
|
toggle_signal: u64,
|
|
|
|
muted: Result<bool>,
|
|
|
|
) {
|
2017-06-30 15:24:26 +00:00
|
|
|
let check_button = &appstate.gui.popup_window.mute_check;
|
|
|
|
|
|
|
|
glib::signal_handler_block(check_button, toggle_signal);
|
|
|
|
|
2017-06-27 22:23:12 +00:00
|
|
|
match muted {
|
|
|
|
Ok(val) => {
|
|
|
|
check_button.set_active(val);
|
|
|
|
check_button.set_tooltip_text("");
|
2017-06-28 12:55:38 +00:00
|
|
|
}
|
2017-06-27 22:23:12 +00:00
|
|
|
Err(_) => {
|
|
|
|
/* can't figure out whether channel is muted, grey out */
|
|
|
|
check_button.set_active(true);
|
|
|
|
check_button.set_sensitive(false);
|
|
|
|
check_button.set_tooltip_text("Soundcard has no mute switch");
|
|
|
|
}
|
|
|
|
}
|
2017-06-30 15:24:26 +00:00
|
|
|
|
|
|
|
glib::signal_handler_unblock(check_button, toggle_signal);
|
2017-06-27 22:23:12 +00:00
|
|
|
}
|
2017-06-29 12:55:07 +00:00
|
|
|
|
|
|
|
|
2017-06-30 19:10:33 +00:00
|
|
|
pub fn set_slider(vol_scale_adj: >k::Adjustment, scale: f64) {
|
2017-06-29 12:55:07 +00:00
|
|
|
vol_scale_adj.set_value(scale);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn grab_devices(window: >k::Window) -> Result<()> {
|
|
|
|
let device = gtk::get_current_event_device().ok_or("No current device")?;
|
|
|
|
|
|
|
|
let gdk_window = window.get_window().ok_or("No window?!")?;
|
|
|
|
|
|
|
|
/* Grab the mouse */
|
2017-07-06 14:53:19 +00:00
|
|
|
let m_grab_status = device.grab(
|
|
|
|
&gdk_window,
|
|
|
|
GrabOwnership::None,
|
|
|
|
true,
|
|
|
|
BUTTON_PRESS_MASK,
|
|
|
|
None,
|
|
|
|
GDK_CURRENT_TIME as u32,
|
|
|
|
);
|
2017-06-29 12:55:07 +00:00
|
|
|
|
|
|
|
if m_grab_status != GrabStatus::Success {
|
2017-07-06 14:53:19 +00:00
|
|
|
warn!(
|
|
|
|
"Could not grab {}",
|
|
|
|
device.get_name().unwrap_or(String::from("UNKNOWN DEVICE"))
|
|
|
|
);
|
2017-06-29 12:55:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Grab the keyboard */
|
2017-07-06 14:53:19 +00:00
|
|
|
let k_dev = device.get_associated_device().ok_or(
|
|
|
|
"Couldn't get associated device",
|
|
|
|
)?;
|
|
|
|
|
|
|
|
let k_grab_status = k_dev.grab(
|
|
|
|
&gdk_window,
|
|
|
|
GrabOwnership::None,
|
|
|
|
true,
|
|
|
|
KEY_PRESS_MASK,
|
|
|
|
None,
|
|
|
|
GDK_CURRENT_TIME as u32,
|
|
|
|
);
|
2017-06-29 12:55:07 +00:00
|
|
|
if k_grab_status != GrabStatus::Success {
|
2017-07-06 14:53:19 +00:00
|
|
|
warn!(
|
|
|
|
"Could not grab {}",
|
|
|
|
k_dev.get_name().unwrap_or(String::from("UNKNOWN DEVICE"))
|
|
|
|
);
|
2017-06-29 12:55:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return Ok(());
|
|
|
|
}
|