2015-03-10 07:46:54 +00:00
|
|
|
//! Rustic bindings to [libnotify](https://developer.gnome.org/libnotify/)
|
|
|
|
//!
|
|
|
|
//! ```rust
|
|
|
|
//! extern crate libnotify;
|
|
|
|
//!
|
|
|
|
//! fn main() {
|
|
|
|
//! let notify = libnotify::Context::new("hello").unwrap();
|
|
|
|
//! let n = notify.new_notification("This is the summary.",
|
|
|
|
//! Some("This is the optional body text."),
|
|
|
|
//! None).unwrap();
|
|
|
|
//! n.show().unwrap();
|
|
|
|
//! }
|
|
|
|
//! ```
|
|
|
|
|
2015-03-07 12:55:19 +00:00
|
|
|
extern crate "libnotify-sys" as sys;
|
|
|
|
extern crate "glib-2_0-sys" as glib;
|
|
|
|
|
|
|
|
use std::ffi::CString;
|
2015-03-07 13:21:17 +00:00
|
|
|
use std::marker::PhantomData;
|
2015-03-10 18:14:18 +00:00
|
|
|
use std::fmt;
|
2015-03-07 12:55:19 +00:00
|
|
|
|
|
|
|
use glib::types::{
|
|
|
|
TRUE,
|
|
|
|
FALSE
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Error that can happen on context creation
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub enum ContextCreationError {
|
|
|
|
/// Context already exists
|
|
|
|
AlreadyExists,
|
|
|
|
InitFailure,
|
|
|
|
NulError
|
|
|
|
}
|
|
|
|
|
2015-03-10 18:14:18 +00:00
|
|
|
impl fmt::Display for ContextCreationError {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
|
|
|
use ContextCreationError::*;
|
|
|
|
match *self {
|
|
|
|
AlreadyExists => write!(f, "A Libnotify context already exists."),
|
|
|
|
InitFailure => write!(f, "Failed to initialize libnotify."),
|
|
|
|
NulError => write!(f, "Argument contains a nul character.")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-07 12:55:19 +00:00
|
|
|
#[derive(Debug)]
|
|
|
|
pub enum NotificationCreationError {
|
|
|
|
NulError,
|
|
|
|
Unknown
|
|
|
|
}
|
|
|
|
|
2015-03-10 18:14:18 +00:00
|
|
|
impl fmt::Display for NotificationCreationError {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
|
|
|
use NotificationCreationError::*;
|
|
|
|
match *self {
|
|
|
|
NulError => write!(f, "Argument contains a nul character."),
|
|
|
|
Unknown => write!(f, "Unknown error")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-08 16:11:44 +00:00
|
|
|
/// The context which within libnotify operates.
|
|
|
|
///
|
|
|
|
/// Only one context can exist at a time.
|
2015-03-07 12:55:19 +00:00
|
|
|
pub struct Context;
|
|
|
|
|
|
|
|
impl Context {
|
2015-03-08 16:07:50 +00:00
|
|
|
/// Create a new context
|
|
|
|
///
|
|
|
|
/// Arguments:
|
|
|
|
///
|
|
|
|
/// - app_name: The name of the application using the context
|
2015-03-07 12:55:19 +00:00
|
|
|
pub fn new(app_name: &str) -> Result<Context, ContextCreationError> {
|
|
|
|
unsafe {
|
|
|
|
if sys::notify_is_initted() == TRUE {
|
|
|
|
return Err(ContextCreationError::AlreadyExists);
|
|
|
|
}
|
|
|
|
let app_name = match CString::new(app_name) {
|
|
|
|
Ok(name) => name,
|
|
|
|
Err(_) => return Err(ContextCreationError::NulError)
|
|
|
|
};
|
|
|
|
if sys::notify_init(app_name.as_ptr()) == FALSE {
|
|
|
|
return Err(ContextCreationError::InitFailure);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(Context)
|
|
|
|
}
|
2015-03-08 16:07:50 +00:00
|
|
|
/// Creates a new Notification.
|
|
|
|
///
|
|
|
|
/// Arguments:
|
|
|
|
///
|
|
|
|
/// - summary: Required summary text
|
|
|
|
/// - body: Optional body text
|
|
|
|
/// - icon: Optional icon theme icon name or filename
|
2015-03-08 15:59:15 +00:00
|
|
|
pub fn new_notification(&self, summary: &str,
|
|
|
|
body: Option<&str>,
|
|
|
|
icon: Option<&str>)
|
2015-03-07 12:55:19 +00:00
|
|
|
-> Result<Notification, NotificationCreationError> {
|
|
|
|
let summary = match CString::new(summary) {
|
|
|
|
Ok(cstr) => cstr,
|
|
|
|
Err(_) => return Err(NotificationCreationError::NulError)
|
|
|
|
};
|
2015-03-08 15:59:15 +00:00
|
|
|
let body = match body {
|
|
|
|
Some(body) => match CString::new(body) {
|
|
|
|
Ok(cstr) => Some(cstr),
|
|
|
|
Err(_) => return Err(NotificationCreationError::NulError)
|
|
|
|
},
|
|
|
|
None => None
|
|
|
|
};
|
|
|
|
let body_ptr = match body {
|
|
|
|
Some(body) => body.as_ptr(),
|
|
|
|
None => std::ptr::null()
|
|
|
|
};
|
|
|
|
let icon = match icon {
|
|
|
|
Some(icon) => match CString::new(icon) {
|
|
|
|
Ok(cstr) => Some(cstr),
|
|
|
|
Err(_) => return Err(NotificationCreationError::NulError)
|
|
|
|
},
|
|
|
|
None => None
|
|
|
|
};
|
|
|
|
let icon_ptr = match icon {
|
|
|
|
Some(icon) => icon.as_ptr(),
|
|
|
|
None => std::ptr::null()
|
2015-03-07 12:55:19 +00:00
|
|
|
};
|
|
|
|
unsafe {
|
|
|
|
let n = sys::notify_notification_new(summary.as_ptr(),
|
2015-03-08 15:59:15 +00:00
|
|
|
body_ptr,
|
|
|
|
icon_ptr);
|
2015-03-07 12:55:19 +00:00
|
|
|
if n.is_null() {
|
|
|
|
return Err(NotificationCreationError::Unknown);
|
|
|
|
}
|
|
|
|
|
2015-03-07 13:21:17 +00:00
|
|
|
Ok(Notification{handle: n, _phantom: PhantomData})
|
2015-03-07 12:55:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Drop for Context {
|
|
|
|
fn drop(&mut self) {
|
|
|
|
unsafe {
|
|
|
|
sys::notify_uninit();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-08 16:07:50 +00:00
|
|
|
/// A passive pop-up notification
|
2015-03-07 13:21:17 +00:00
|
|
|
pub struct Notification<'a> {
|
|
|
|
handle: *mut sys::NotifyNotification,
|
|
|
|
_phantom: PhantomData<&'a Context>
|
2015-03-07 12:55:19 +00:00
|
|
|
}
|
|
|
|
|
2015-03-07 13:21:17 +00:00
|
|
|
impl<'a> Notification<'a> {
|
2015-03-08 16:07:50 +00:00
|
|
|
/// Tells the notification server to display the notification
|
|
|
|
/// on the screen.
|
2015-03-07 13:21:17 +00:00
|
|
|
pub fn show(&'a self) -> Result<(), ()> {
|
2015-03-07 12:55:19 +00:00
|
|
|
unsafe {
|
|
|
|
let mut err: *mut glib::GError = std::ptr::null_mut();
|
|
|
|
sys::notify_notification_show(self.handle, &mut err);
|
|
|
|
if !err.is_null() {
|
|
|
|
glib::g_error_free(err);
|
|
|
|
return Err(())
|
|
|
|
}
|
|
|
|
return Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|