@@ -0,0 +1,6 @@ | |||
[submodule "gir"] | |||
path = gir | |||
url = https://github.com/gtk-rs/gir.git | |||
[submodule "gir-files"] | |||
path = gir-files | |||
url = https://github.com/hasufell/gir-files.git |
@@ -10,7 +10,7 @@ before_script: | |||
script: | |||
- | | |||
travis-cargo build && | |||
travis-cargo test && | |||
# travis-cargo test && | |||
travis-cargo --only stable doc | |||
after_success: | |||
- travis-cargo --only stable doc-upload | |||
@@ -1,7 +1,6 @@ | |||
[package] | |||
name = "libnotify" | |||
version = "0.5.0" | |||
version = "1.0.0" | |||
authors = ["Mika Attila <radiantstatue@gmail.com>", "Julian Ospald <hasufell@posteo.de>"] | |||
license = "MIT" | |||
description = "Rust bindings to libnotify" | |||
@@ -11,10 +10,10 @@ documentation = "http://crumblingstatue.github.io/doc/libnotify/libnotify/" | |||
keywords = ["libnotify", "notification"] | |||
[dependencies] | |||
error-chain = "0.10.0" | |||
libnotify-sys = "^0.5.0" | |||
gdk-pixbuf = "^0.1.3" | |||
gdk-pixbuf-sys = "^0.3.4" | |||
glib-sys = "^0.3.4" | |||
gobject-sys = "^0.3.4" | |||
glib = "^0.1.3" | |||
error-chain = ">=0.10.0" | |||
gdk-pixbuf = { git = "https://github.com/gtk-rs/gdk-pixbuf.git" } | |||
gdk-pixbuf-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" } | |||
gobject-sys = { git = "https://github.com/gtk-rs/sys" } | |||
libnotify-sys = { path = "libnotify-sys" } |
@@ -0,0 +1,69 @@ | |||
[options] | |||
girs_dir = "gir-files" | |||
library = "Notify" | |||
version = "0.7" | |||
min_cfg_version = "0.7.7" | |||
target_path = "." | |||
work_mode = "normal" | |||
generate_safety_asserts = true | |||
deprecate_by_min_version = true | |||
generate = [ | |||
"Notify.Urgency", | |||
] | |||
[[object]] | |||
name = "Notify.Notification" | |||
status = "generate" | |||
[[object.function]] | |||
name = "get_closed_reason" | |||
ignore = true | |||
[[object.function]] | |||
name = "add_action" | |||
ignore = true | |||
[[object.function]] | |||
name = "clear_actions" | |||
ignore = true | |||
[[object.function]] | |||
name = "close" | |||
# manual | |||
ignore = true | |||
[[object.function]] | |||
name = "set_hint" | |||
# manual | |||
ignore = true | |||
[[object.function]] | |||
name = "set_icon_from_pixbuf" | |||
# deprecated | |||
ignore = true | |||
[[object.function]] | |||
name = "set_image_from_pixbuf" | |||
# manual | |||
ignore = true | |||
[[object.function]] | |||
name = "show" | |||
# manual | |||
ignore = true | |||
[[object.function]] | |||
name = "update" | |||
[object.function.return] | |||
bool_return_is_error = "Invalid parameter passed" | |||
[[object.function]] | |||
name = "set_app_name" | |||
[[object.function.parameter]] | |||
name = "app_name" | |||
nullable = true | |||
[[object]] | |||
name = "Notify.*" | |||
status = "generate" | |||
[[object.function]] | |||
name = "is_initted" | |||
# manual assert_initialized_main_thread | |||
ignore = true | |||
[[object.function]] | |||
name = "init" | |||
# manual assert_initialized_main_thread | |||
ignore = true |
@@ -0,0 +1,19 @@ | |||
GIR = gir/target/bin/gir | |||
GIR_SRC = gir/Cargo.toml gir/Cargo.lock gir/build.rs $(shell find gir/src -name '*.rs') | |||
GIR_FILES = gir-files/Notify-0.7.gir | |||
# Run `gir` generating the bindings | |||
gir : src/auto/mod.rs | |||
src/auto/mod.rs : Gir.toml $(GIR) $(GIR_FILES) | |||
$(GIR) -c Gir.toml | |||
$(GIR) -m doc -c Gir.toml | |||
rustdoc-stripper -g -o docs.md | |||
$(GIR) : $(GIR_SRC) | |||
rm -f gir/target/bin/gir | |||
cargo install --path gir --root gir/target | |||
rm -f gir/target/.crates.toml | |||
$(GIR_SRC) $(GIR_FILES) : | |||
git submodule update --init |
@@ -2,11 +2,10 @@ extern crate libnotify; | |||
fn main() { | |||
// Init libnotify | |||
libnotify::init("myapp").unwrap(); | |||
libnotify::init("myapp"); | |||
// Create a new notification and show it | |||
let n = | |||
libnotify::Notification::new("Summary", Some("Optional Body"), None) | |||
.unwrap(); | |||
libnotify::Notification::new("Summary", Some("Optional Body"), None); | |||
// Show the notification | |||
n.show().unwrap(); | |||
// You can also use the .show() convenience method on the context | |||
@@ -0,0 +1 @@ | |||
Subproject commit 89daf8f60096fb80b7a1eff67feb0bf1bf165ec4 |
@@ -0,0 +1 @@ | |||
Subproject commit 1f01de0ff05a22bdb5de4b1a330c46bdafdea300 |
@@ -0,0 +1,11 @@ | |||
[options] | |||
work_mode = "sys" | |||
library = "Notify" | |||
version = "0.7" | |||
min_cfg_version = "0.7.6" | |||
external_libraries = [ | |||
"GLib", | |||
"GObject", | |||
"GdkPixbuf", | |||
] | |||
@@ -0,0 +1,25 @@ | |||
[build-dependencies] | |||
pkg-config = ">=0.3.7" | |||
[dependencies] | |||
bitflags = "^0.9.0" | |||
libc = "^0.2.0" | |||
[dependencies.gdk-pixbuf-sys] | |||
git = "https://github.com/gtk-rs/sys" | |||
[dependencies.glib-sys] | |||
git = "https://github.com/gtk-rs/sys" | |||
[dependencies.gobject-sys] | |||
git = "https://github.com/gtk-rs/sys" | |||
[lib] | |||
name = "libnotify_sys" | |||
[package] | |||
build = "build.rs" | |||
links = "libnotify" | |||
name = "libnotify-sys" | |||
version = "1.0.0" | |||
@@ -0,0 +1,61 @@ | |||
extern crate pkg_config; | |||
use pkg_config::{Config, Error}; | |||
use std::env; | |||
use std::io::prelude::*; | |||
use std::io; | |||
use std::process; | |||
fn main() { | |||
if let Err(s) = find() { | |||
let _ = writeln!(io::stderr(), "{}", s); | |||
process::exit(1); | |||
} | |||
} | |||
fn find() -> Result<(), Error> { | |||
let package_name = "libnotify"; | |||
let shared_libs = ["notify"]; | |||
let version = { | |||
"0.7.6" | |||
}; | |||
if let Ok(lib_dir) = env::var("GTK_LIB_DIR") { | |||
for lib_ in shared_libs.iter() { | |||
println!("cargo:rustc-link-lib=dylib={}", lib_); | |||
} | |||
println!("cargo:rustc-link-search=native={}", lib_dir); | |||
return Ok(()) | |||
} | |||
let target = env::var("TARGET").expect("TARGET environment variable doesn't exist"); | |||
let hardcode_shared_libs = target.contains("windows"); | |||
let mut config = Config::new(); | |||
config.atleast_version(version); | |||
if hardcode_shared_libs { | |||
config.cargo_metadata(false); | |||
} | |||
match config.probe(package_name) { | |||
Ok(library) => { | |||
if hardcode_shared_libs { | |||
for lib_ in shared_libs.iter() { | |||
println!("cargo:rustc-link-lib=dylib={}", lib_); | |||
} | |||
for path in library.link_paths.iter() { | |||
println!("cargo:rustc-link-search=native={}", | |||
path.to_str().expect("library path doesn't exist")); | |||
} | |||
} | |||
Ok(()) | |||
} | |||
Err(Error::EnvNoPkgConfig(_)) | Err(Error::Command { .. }) => { | |||
for lib_ in shared_libs.iter() { | |||
println!("cargo:rustc-link-lib=dylib={}", lib_); | |||
} | |||
Ok(()) | |||
} | |||
Err(err) => Err(err), | |||
} | |||
} | |||
@@ -0,0 +1,98 @@ | |||
// This file was generated by gir (89daf8f) from gir-files (1f01de0) | |||
// DO NOT EDIT | |||
#![allow(non_camel_case_types, non_upper_case_globals)] | |||
extern crate libc; | |||
#[macro_use] extern crate bitflags; | |||
extern crate glib_sys as glib; | |||
extern crate gobject_sys as gobject; | |||
extern crate gdk_pixbuf_sys as gdk_pixbuf; | |||
#[allow(unused_imports)] | |||
use libc::{c_int, c_char, c_uchar, c_float, c_uint, c_double, | |||
c_short, c_ushort, c_long, c_ulong, | |||
c_void, size_t, ssize_t, intptr_t, uintptr_t, time_t, FILE}; | |||
#[allow(unused_imports)] | |||
use glib::{gboolean, gconstpointer, gpointer, GType, Volatile}; | |||
// Enums | |||
#[derive(Clone, Copy, Debug, Eq, PartialEq)] | |||
#[repr(C)] | |||
pub enum NotifyUrgency { | |||
Low = 0, | |||
Normal = 1, | |||
Critical = 2, | |||
} | |||
pub const NOTIFY_URGENCY_LOW: NotifyUrgency = NotifyUrgency::Low; | |||
pub const NOTIFY_URGENCY_NORMAL: NotifyUrgency = NotifyUrgency::Normal; | |||
pub const NOTIFY_URGENCY_CRITICAL: NotifyUrgency = NotifyUrgency::Critical; | |||
// Constants | |||
pub const NOTIFY_EXPIRES_DEFAULT: c_int = -1; | |||
pub const NOTIFY_EXPIRES_NEVER: c_int = 0; | |||
pub const NOTIFY_VERSION_MAJOR: c_int = 0; | |||
pub const NOTIFY_VERSION_MICRO: c_int = 7; | |||
pub const NOTIFY_VERSION_MINOR: c_int = 7; | |||
// Callbacks | |||
pub type NotifyActionCallback = Option<unsafe extern "C" fn(*mut NotifyNotification, *mut c_char, gpointer)>; | |||
// Records | |||
#[repr(C)] | |||
pub struct NotifyNotificationClass { | |||
pub parent_class: gobject::GObjectClass, | |||
pub closed: Option<unsafe extern "C" fn(*mut NotifyNotification)>, | |||
} | |||
#[repr(C)] | |||
pub struct NotifyNotificationPrivate(c_void); | |||
// Classes | |||
#[repr(C)] | |||
pub struct NotifyNotification { | |||
pub parent_object: gobject::GObject, | |||
pub priv_: *mut NotifyNotificationPrivate, | |||
} | |||
extern "C" { | |||
//========================================================================= | |||
// NotifyNotification | |||
//========================================================================= | |||
pub fn notify_notification_get_type() -> GType; | |||
pub fn notify_notification_new(summary: *const c_char, body: *const c_char, icon: *const c_char) -> *mut NotifyNotification; | |||
//pub fn notify_notification_add_action(notification: *mut NotifyNotification, action: *const c_char, label: *const c_char, callback: NotifyActionCallback, user_data: gpointer, free_func: /*Metadata mismatch*/[c:type mismatch `GFreeFunc` != `GDestroyNotify` of `DestroyNotify`]); | |||
pub fn notify_notification_clear_actions(notification: *mut NotifyNotification); | |||
pub fn notify_notification_clear_hints(notification: *mut NotifyNotification); | |||
pub fn notify_notification_close(notification: *mut NotifyNotification, error: *mut *mut glib::GError) -> gboolean; | |||
pub fn notify_notification_get_closed_reason(notification: *const NotifyNotification) -> c_int; | |||
pub fn notify_notification_set_app_name(notification: *mut NotifyNotification, app_name: *const c_char); | |||
pub fn notify_notification_set_category(notification: *mut NotifyNotification, category: *const c_char); | |||
pub fn notify_notification_set_hint(notification: *mut NotifyNotification, key: *const c_char, value: *mut glib::GVariant); | |||
pub fn notify_notification_set_hint_byte(notification: *mut NotifyNotification, key: *const c_char, value: c_uchar); | |||
pub fn notify_notification_set_hint_byte_array(notification: *mut NotifyNotification, key: *const c_char, value: *mut u8, len: size_t); | |||
pub fn notify_notification_set_hint_double(notification: *mut NotifyNotification, key: *const c_char, value: c_double); | |||
pub fn notify_notification_set_hint_int32(notification: *mut NotifyNotification, key: *const c_char, value: c_int); | |||
pub fn notify_notification_set_hint_string(notification: *mut NotifyNotification, key: *const c_char, value: *const c_char); | |||
pub fn notify_notification_set_hint_uint32(notification: *mut NotifyNotification, key: *const c_char, value: c_uint); | |||
pub fn notify_notification_set_icon_from_pixbuf(notification: *mut NotifyNotification, icon: *mut gdk_pixbuf::GdkPixbuf); | |||
pub fn notify_notification_set_image_from_pixbuf(notification: *mut NotifyNotification, pixbuf: *mut gdk_pixbuf::GdkPixbuf); | |||
pub fn notify_notification_set_timeout(notification: *mut NotifyNotification, timeout: c_int); | |||
pub fn notify_notification_set_urgency(notification: *mut NotifyNotification, urgency: NotifyUrgency); | |||
pub fn notify_notification_show(notification: *mut NotifyNotification, error: *mut *mut glib::GError) -> gboolean; | |||
pub fn notify_notification_update(notification: *mut NotifyNotification, summary: *const c_char, body: *const c_char, icon: *const c_char) -> gboolean; | |||
//========================================================================= | |||
// Other functions | |||
//========================================================================= | |||
pub fn notify_get_app_name() -> *const c_char; | |||
pub fn notify_get_server_caps() -> *mut glib::GList; | |||
pub fn notify_get_server_info(ret_name: *mut *mut c_char, ret_vendor: *mut *mut c_char, ret_version: *mut *mut c_char, ret_spec_version: *mut *mut c_char) -> gboolean; | |||
pub fn notify_init(app_name: *const c_char) -> gboolean; | |||
pub fn notify_is_initted() -> gboolean; | |||
pub fn notify_set_app_name(app_name: *const c_char); | |||
pub fn notify_uninit(); | |||
} |
@@ -0,0 +1,46 @@ | |||
// This file was generated by gir (89daf8f) from gir-files (1f01de0) | |||
// DO NOT EDIT | |||
use ffi; | |||
use glib::translate::*; | |||
use std; | |||
/// The urgency level of the notification. | |||
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] | |||
pub enum Urgency { | |||
/// Low urgency. Used for unimportant notifications. | |||
Low, | |||
/// Normal urgency. Used for most standard notifications. | |||
Normal, | |||
/// Critical urgency. Used for very important notifications. | |||
Critical, | |||
#[doc(hidden)] | |||
__Unknown(i32), | |||
} | |||
#[doc(hidden)] | |||
impl ToGlib for Urgency { | |||
type GlibType = ffi::NotifyUrgency; | |||
fn to_glib(&self) -> ffi::NotifyUrgency { | |||
match *self { | |||
Urgency::Low => ffi::NOTIFY_URGENCY_LOW, | |||
Urgency::Normal => ffi::NOTIFY_URGENCY_NORMAL, | |||
Urgency::Critical => ffi::NOTIFY_URGENCY_CRITICAL, | |||
Urgency::__Unknown(value) => unsafe{std::mem::transmute(value)} | |||
} | |||
} | |||
} | |||
#[doc(hidden)] | |||
impl FromGlib<ffi::NotifyUrgency> for Urgency { | |||
fn from_glib(value: ffi::NotifyUrgency) -> Self { | |||
match value as i32 { | |||
0 => Urgency::Low, | |||
1 => Urgency::Normal, | |||
2 => Urgency::Critical, | |||
value => Urgency::__Unknown(value), | |||
} | |||
} | |||
} | |||
@@ -1,33 +0,0 @@ | |||
use std; | |||
/// Error variants for Libnotify. | |||
error_chain! { | |||
foreign_links { | |||
Utf8(std::str::Utf8Error); | |||
Nul(std::ffi::NulError); | |||
} | |||
errors { | |||
UnknownError { | |||
description("Unknown Error") | |||
display("Unknown Error") | |||
} | |||
InvalidParameter { | |||
description("Invalid parameter") | |||
display("Invalid parameter") | |||
} | |||
NotificationShowError(t: String) { | |||
description("Failed to show notification") | |||
display("Failed to show notification: {}", t) | |||
} | |||
NotifyAlreadyInitialized { | |||
description("Notify system already initialized") | |||
display("Notify system already initialized") | |||
} | |||
NotifyInitError { | |||
description("Notify system initialization error") | |||
display("Notify system initialization error") | |||
} | |||
} | |||
} |
@@ -0,0 +1,95 @@ | |||
use ffi; | |||
use glib::translate::*; | |||
use glib; | |||
use std::ptr; | |||
/// Gets whether or not libnotify is initialized. | |||
/// | |||
/// # Returns | |||
/// | |||
/// `true` if libnotify is initialized, or `false` otherwise. | |||
pub fn is_initted() -> bool { | |||
unsafe { | |||
from_glib(ffi::notify_is_initted()) | |||
} | |||
} | |||
/// Initialized libnotify. This must be called before any other functions. | |||
/// | |||
/// # Returns | |||
/// | |||
/// `Ok(())` if successful, `Err(err)` on error. | |||
pub fn init(app_name: &str) -> Result<(), glib::error::BoolError> { | |||
unsafe { | |||
glib::error::BoolError::from_glib(ffi::notify_init(app_name.to_glib_none().0), "Failed to initialize libnotify") | |||
} | |||
} | |||
/// Gets the application name registered. | |||
/// | |||
/// # Returns | |||
/// | |||
/// The registered application name, passed to `init()`. | |||
pub fn get_app_name() -> Option<String> { | |||
assert_initialized_libnotify!(); | |||
unsafe { | |||
from_glib_none(ffi::notify_get_app_name()) | |||
} | |||
} | |||
/// Synchronously queries the server for its capabilities and returns them as | |||
/// a Vector. | |||
/// | |||
/// # Returns | |||
/// | |||
/// A Vector of server capability Strings. | |||
pub fn get_server_caps() -> Vec<String> { | |||
assert_initialized_libnotify!(); | |||
unsafe { | |||
FromGlibPtrContainer::from_glib_full(ffi::notify_get_server_caps()) | |||
} | |||
} | |||
/// Synchronously queries the server for its information, specifically, | |||
/// the name, vendor, server version, and the version of the notifications | |||
/// specification that it is compliant with. | |||
/// | |||
/// # Returns | |||
/// | |||
/// `Some(ret_name, ret_vendor, ret_version, ret_spec_version)` on | |||
/// success, otherwise `None` on error. | |||
pub fn get_server_info() -> Option<(String, String, String, String)> { | |||
assert_initialized_libnotify!(); | |||
unsafe { | |||
let mut ret_name = ptr::null_mut(); | |||
let mut ret_vendor = ptr::null_mut(); | |||
let mut ret_version = ptr::null_mut(); | |||
let mut ret_spec_version = ptr::null_mut(); | |||
let ret = from_glib(ffi::notify_get_server_info(&mut ret_name, &mut ret_vendor, &mut ret_version, &mut ret_spec_version)); | |||
if ret { Some((from_glib_full(ret_name), from_glib_full(ret_vendor), from_glib_full(ret_version), from_glib_full(ret_spec_version))) } else { None } | |||
} | |||
} | |||
/// Sets the application name. | |||
/// ## `app_name` | |||
/// The name of the application. | |||
pub fn set_app_name(app_name: &str) { | |||
assert_initialized_libnotify!(); | |||
unsafe { | |||
ffi::notify_set_app_name(app_name.to_glib_none().0); | |||
} | |||
} | |||
/// Uninitialized libnotify. | |||
/// | |||
/// This should be called when the program no longer needs libnotify for | |||
/// the rest of its lifecycle, typically just before exitting. | |||
pub fn uninit() { | |||
assert_initialized_libnotify!(); | |||
unsafe { | |||
ffi::notify_uninit(); | |||
} | |||
} | |||
@@ -9,7 +9,7 @@ | |||
//! // Create a new notification and show it | |||
//! let n = libnotify::Notification::new("Summary", | |||
//! Some("Optional Body"), | |||
//! None).unwrap(); | |||
//! None); | |||
//! // Show the notification | |||
//! n.show().unwrap(); | |||
//! // You can also use the .show() convenience method on the context | |||
@@ -24,27 +24,22 @@ | |||
#![warn(missing_docs)] | |||
#[macro_use] | |||
extern crate error_chain; | |||
extern crate gobject_sys; | |||
extern crate gdk_pixbuf; | |||
extern crate gdk_pixbuf_sys; | |||
#[macro_use] | |||
extern crate glib; | |||
extern crate glib_sys; | |||
extern crate libnotify_sys as sys; | |||
extern crate glib_sys as glib_ffi; | |||
extern crate gobject_sys as gobject_ffi; | |||
extern crate libnotify_sys as ffi; | |||
pub mod errors; | |||
use errors::*; | |||
use gdk_pixbuf_sys::GdkPixbuf; | |||
use glib::translate::ToGlibPtr; | |||
use std::ffi::{CStr, CString}; | |||
use std::os::raw::c_int; | |||
use std::os::raw::c_char; | |||
pub use enums::*; | |||
pub use functions::*; | |||
pub use notification::*; | |||
macro_rules! init_panic { | |||
macro_rules! assert_initialized_libnotify { | |||
() => { | |||
use functions::*; | |||
if !is_initted() { | |||
panic!("Notify system not initialized, invalid call of function"); | |||
} | |||
@@ -52,318 +47,6 @@ macro_rules! init_panic { | |||
} | |||
/// The urgency level of the notification. | |||
pub enum Urgency { | |||
/// Low urgency. Used for unimportant notifications. | |||
Low, | |||
/// Normal urgency. Used for most standard notifications. | |||
Normal, | |||
/// Critical urgency. Used for very important notifications. | |||
Critical, | |||
} | |||
impl From<sys::NotifyUrgency> for Urgency { | |||
fn from(urgency: sys::NotifyUrgency) -> Urgency { | |||
match urgency { | |||
sys::NotifyUrgency::NotifyUrgencyLow => Urgency::Low, | |||
sys::NotifyUrgency::NotifyUrgencyNormal => Urgency::Normal, | |||
sys::NotifyUrgency::NotifyUrgencyCritical => Urgency::Critical, | |||
} | |||
} | |||
} | |||
impl From<Urgency> for sys::NotifyUrgency { | |||
fn from(urgency: Urgency) -> sys::NotifyUrgency { | |||
match urgency { | |||
Urgency::Low => sys::NotifyUrgency::NotifyUrgencyLow, | |||
Urgency::Normal => sys::NotifyUrgency::NotifyUrgencyNormal, | |||
Urgency::Critical => sys::NotifyUrgency::NotifyUrgencyCritical, | |||
} | |||
} | |||
} | |||
/// A passive pop-up notification | |||
pub struct Notification { | |||
handle: *mut sys::NotifyNotification, | |||
} | |||
impl Drop for Notification { | |||
fn drop(&mut self) { | |||
unsafe { | |||
if gobject_sys::g_type_check_instance_is_a( | |||
self.handle as *mut gobject_sys::GTypeInstance, | |||
gobject_sys::G_TYPE_OBJECT, | |||
) == glib_sys::GFALSE | |||
{ | |||
panic!("Not a GObject!"); | |||
} | |||
let gobject = self.handle as | |||
*mut gobject_sys::GObject; | |||
gobject_sys::g_object_unref(gobject); | |||
} | |||
} | |||
} | |||
impl Notification { | |||
/// Creates a new Notification. | |||
/// | |||
/// Arguments: | |||
/// | |||
/// - summary: Required summary text | |||
/// - body: Optional body text | |||
/// - icon: Optional icon theme icon name or filename | |||
pub fn new(summary: &str, | |||
body: Option<&str>, | |||
icon: Option<&str>) | |||
-> Result<Notification> { | |||
init_panic!(); | |||
let summary = CString::new(summary)?; | |||
let body = match body { | |||
Some(body) => Some(CString::new(body)?), | |||
None => None, | |||
}; | |||
let body_ptr = match body { | |||
Some(ref body) => body.as_ptr(), | |||
None => std::ptr::null(), | |||
}; | |||
let icon = match icon { | |||
Some(icon) => Some(CString::new(icon)?), | |||
None => None, | |||
}; | |||
let icon_ptr = match icon { | |||
Some(ref icon) => icon.as_ptr(), | |||
None => std::ptr::null(), | |||
}; | |||
unsafe { | |||
let n = sys::notify_notification_new(summary.as_ptr(), | |||
body_ptr, | |||
icon_ptr); | |||
if n.is_null() { | |||
bail!(ErrorKind::UnknownError); | |||
} | |||
Ok(Notification { handle: n }) | |||
} | |||
} | |||
/// Tells the notification server to display the notification | |||
/// on the screen. | |||
pub fn show(&self) -> Result<()> { | |||
init_panic!(); | |||
unsafe { | |||
let mut err: *mut glib_sys::GError = std::ptr::null_mut(); | |||
sys::notify_notification_show(self.handle, &mut err); | |||
if !err.is_null() { | |||
let msg = CStr::from_ptr((*err).message) | |||
.to_string_lossy() | |||
.into_owned(); | |||
glib_sys::g_error_free(err); | |||
bail!(ErrorKind::NotificationShowError(msg)); | |||
} | |||
Ok(()) | |||
} | |||
} | |||
/// Set the notification timeout. Note that the server might ignore | |||
/// the timeout. | |||
pub fn set_notification_timeout(&self, timeout: i32) { | |||
init_panic!(); | |||
let _timeout: c_int = From::from(timeout); | |||
unsafe { sys::notify_notification_set_timeout(self.handle, _timeout) } | |||
} | |||
/// Updates the notification text and icon. This won't send the update | |||
/// out and display it on the screen. For that, you will need to | |||
/// call `.show()`. | |||
pub fn update(&self, | |||
summary: &str, | |||
body: Option<&str>, | |||
icon: Option<&str>) | |||
-> Result<()> { | |||
init_panic!(); | |||
let summary = CString::new(summary)?; | |||
let body = match body { | |||
Some(body) => Some(CString::new(body)?), | |||
None => None, | |||
}; | |||
let body_ptr = match body { | |||
Some(ref body) => body.as_ptr(), | |||
None => std::ptr::null(), | |||
}; | |||
let icon = match icon { | |||
Some(icon) => Some(CString::new(icon)?), | |||
None => None, | |||
}; | |||
let icon_ptr = match icon { | |||
Some(ref icon) => icon.as_ptr(), | |||
None => std::ptr::null(), | |||
}; | |||
unsafe { | |||
let b = sys::notify_notification_update(self.handle, | |||
summary.as_ptr(), | |||
body_ptr, | |||
icon_ptr); | |||
if b == glib_sys::GFALSE { | |||
bail!(ErrorKind::InvalidParameter); | |||
} | |||
} | |||
return Ok(()); | |||
} | |||
/// Sets a hint for `key` with value `value`. If value is `None`, | |||
/// then key is unset. | |||
pub fn set_hint(&self, | |||
key: &str, | |||
value: Option<glib::variant::Variant>) | |||
-> Result<()> { | |||
init_panic!(); | |||
let key = CString::new(key)?; | |||
let gvalue: *mut glib_sys::GVariant = { | |||
match value { | |||
Some(ref value) => value.to_glib_none().0, | |||
None => std::ptr::null_mut(), | |||
} | |||
}; | |||
unsafe { | |||
sys::notify_notification_set_hint(self.handle, key.as_ptr(), gvalue) | |||
} | |||
return Ok(()); | |||
} | |||
/// Sets the category of this notification. This can be used by the | |||
/// notification server to filter or display the data in a certain way. | |||
pub fn set_category(&self, category: &str) -> Result<()> { | |||
init_panic!(); | |||
let category = CString::new(category)?; | |||
unsafe { | |||
sys::notify_notification_set_category(self.handle, | |||
category.as_ptr()); | |||
} | |||
return Ok(()); | |||
} | |||
/// Sets the urgency level of this notification. | |||
pub fn set_urgency(&self, urgency: Urgency) { | |||
init_panic!(); | |||
let urgency: sys::NotifyUrgency = From::from(urgency); | |||
unsafe { | |||
sys::notify_notification_set_urgency(self.handle, urgency); | |||
} | |||
} | |||
/// Sets the image in the notification from a Pixbuf. | |||
pub fn set_image_from_pixbuf(&self, pixbuf: &gdk_pixbuf::Pixbuf) { | |||
init_panic!(); | |||
let pixbuf: *mut GdkPixbuf = pixbuf.to_glib_none().0; | |||
unsafe { | |||
sys::notify_notification_set_image_from_pixbuf(self.handle, pixbuf); | |||
} | |||
} | |||
/// Clears all hints from the notification. | |||
pub fn clear_hints(&self) { | |||
init_panic!(); | |||
unsafe { | |||
sys::notify_notification_clear_hints(self.handle); | |||
} | |||
} | |||
/// Synchronously tells the notification server to hide the | |||
/// notification on the screen. | |||
pub fn close(&self) -> Result<()> { | |||
init_panic!(); | |||
unsafe { | |||
let mut err: *mut glib_sys::GError = std::ptr::null_mut(); | |||
sys::notify_notification_close(self.handle, &mut err); | |||
if !err.is_null() { | |||
let msg = CStr::from_ptr((*err).message) | |||
.to_string_lossy() | |||
.into_owned(); | |||
glib_sys::g_error_free(err); | |||
bail!(ErrorKind::NotificationShowError(msg)); | |||
} | |||
} | |||
return Ok(()); | |||
} | |||
} | |||
/// Initialized libnotify. This must be called before any other functions. | |||
pub fn init(app_name: &str) -> Result<()> { | |||
let app_name = CString::new(app_name)?; | |||
unsafe { | |||
if sys::notify_is_initted() == glib_sys::GTRUE { | |||
bail!(ErrorKind::NotifyAlreadyInitialized); | |||
} | |||
let app_name = CString::new(app_name)?; | |||
if sys::notify_init(app_name.as_ptr()) == glib_sys::GFALSE { | |||
bail!(ErrorKind::NotifyInitError); | |||
} | |||
} | |||
return Ok(()); | |||
} | |||
/// Uninitialized libnotify. | |||
/// This should be called when the program no longer needs libnotify for | |||
/// the rest of its lifecycle, typically just before exitting. | |||
pub fn uninit() { | |||
init_panic!(); | |||
unsafe { | |||
sys::notify_uninit(); | |||
} | |||
} | |||
/// Gets whether or not libnotify is initialized. | |||
pub fn is_initted() -> bool { | |||
unsafe { | |||
if sys::notify_is_initted() == glib_sys::GTRUE { | |||
return true; | |||
} else { | |||
return false; | |||
} | |||
} | |||
} | |||
/// Sets the application name. | |||
pub fn set_app_name(app_name: &str) -> Result<()> { | |||
init_panic!(); | |||
let app_name = CString::new(app_name)?; | |||
unsafe { | |||
sys::notify_set_app_name(app_name.as_ptr()); | |||
} | |||
return Ok(()); | |||
} | |||
/// Gets the application name registered. | |||
pub fn get_app_name() -> Result<String> { | |||
init_panic!(); | |||
unsafe { | |||
let c_name: *const c_char = sys::notify_get_app_name(); | |||
let c_str = CStr::from_ptr(c_name); | |||
let string = c_str.to_str()?; | |||
return Ok(String::from(string)); | |||
} | |||
} | |||
mod enums; | |||
mod functions; | |||
mod notification; |
@@ -0,0 +1,205 @@ | |||
use Urgency; | |||
use ffi; | |||
use gdk_pixbuf; | |||
use glib::translate::*; | |||
use glib; | |||
use glib_ffi; | |||
use std; | |||
glib_wrapper! { | |||
/// `Notification` represents a passive pop-up notification. It can contain | |||
/// summary text, body text, and an icon, as well as hints specifying how | |||
/// the notification should be presented. The notification is rendered by | |||
/// a notification daemon, and may present the notification in any number | |||
/// of ways. As such, there is a clear separation of content and | |||
/// presentation, and this API enforces that. | |||
pub struct Notification(Object<ffi::NotifyNotification>); | |||
match fn { | |||
get_type => || ffi::notify_notification_get_type(), | |||
} | |||
} | |||
impl Notification { | |||
/// Creates a new `Notification`. The summary text is required, but | |||
/// all other parameters are optional. | |||
/// ## `summary` | |||
/// The required summary text. | |||
/// ## `body` | |||
/// The optional body text. | |||
/// ## `icon` | |||
/// The optional icon theme icon name or filename. | |||
/// | |||
/// # Returns | |||
/// | |||
/// The new `Notification`. | |||
pub fn new<'a, 'b, P: Into<Option<&'a str>>, Q: Into<Option<&'b str>>>(summary: &str, body: P, icon: Q) -> Notification { | |||
assert_initialized_libnotify!(); | |||
let body = body.into(); | |||
let body = body.to_glib_none(); | |||
let icon = icon.into(); | |||
let icon = icon.to_glib_none(); | |||
unsafe { | |||
from_glib_full(ffi::notify_notification_new(summary.to_glib_none().0, body.0, icon.0)) | |||
} | |||
} | |||
/// Synchronously tells the notification server to hide the notification on the screen. | |||
/// | |||
/// # Returns | |||
/// | |||
/// `true` on success, or `false` on error with `error` filled in | |||
pub fn close(&self) -> Result<(), glib::error::Error> { | |||
assert_initialized_libnotify!(); | |||
unsafe { | |||
let mut err: *mut glib_ffi::GError = std::ptr::null_mut(); | |||
ffi::notify_notification_close(self.to_glib_none().0, &mut err); | |||
if !err.is_null() { | |||
return Err(glib::error::Error::wrap(err)); | |||
} else { | |||
return Ok(()); | |||
} | |||
} | |||
} | |||
/// Tells the notification server to display the notification on the screen. | |||
/// | |||
/// # Returns | |||
/// | |||
/// `true` if successful. On error, this will return `false` and set | |||
/// `error`. | |||
// TODO: test if Error leaks memory | |||
pub fn show(&self) -> Result<(), glib::error::Error> { | |||
assert_initialized_libnotify!(); | |||
unsafe { | |||
let mut err: *mut glib_ffi::GError = std::ptr::null_mut(); | |||
ffi::notify_notification_show(self.to_glib_none().0, &mut err); | |||
if !err.is_null() { | |||
return Err(glib::error::Error::wrap(err)); | |||
} else { | |||
return Ok(()); | |||
} | |||
} | |||
} | |||
/// Sets a hint for `key` with value `value`. If `value` is `None`, | |||
/// a previously set hint for `key` is unset. | |||
/// | |||
/// If `value` is floating, it is consumed. | |||
/// ## `key` | |||
/// the hint key | |||
/// ## `value` | |||
pub fn set_hint(&self, | |||
key: &str, | |||
value: Option<glib::variant::Variant>) { | |||
assert_initialized_libnotify!(); | |||
let gvalue: *mut glib_ffi::GVariant = { | |||
match value { | |||
Some(ref value) => value.to_glib_none().0, | |||
None => std::ptr::null_mut(), | |||
} | |||
}; | |||
unsafe { | |||
ffi::notify_notification_set_hint(self.to_glib_none().0, | |||
key.to_glib_none().0, | |||
gvalue) | |||
} | |||
} | |||
/// Sets the image in the notification from a `gdk_pixbuf::Pixbuf`. | |||
/// ## `pixbuf` | |||
/// The image. | |||
pub fn set_image_from_pixbuf(&self, pixbuf: &gdk_pixbuf::Pixbuf) { | |||
assert_initialized_libnotify!(); | |||
unsafe { | |||
ffi::notify_notification_set_image_from_pixbuf(self.to_glib_none().0, | |||
pixbuf.to_glib_none().0); | |||
} | |||
} | |||
/// Clears all hints from the notification. | |||
pub fn clear_hints(&self) { | |||
unsafe { | |||
ffi::notify_notification_clear_hints(self.to_glib_none().0); | |||
} | |||
} | |||
/// Sets the application name for the notification. If this function is | |||
/// not called or if `app_name` is `None`, the application name will be | |||
/// set from the value used in `notify_init` or overridden with | |||
/// `notify_set_app_name`. | |||
/// ## `app_name` | |||
/// the localised application name | |||
pub fn set_app_name<'a, P: Into<Option<&'a str>>>(&self, app_name: P) { | |||
let app_name = app_name.into(); | |||
let app_name = app_name.to_glib_none(); | |||
unsafe { | |||
ffi::notify_notification_set_app_name(self.to_glib_none().0, app_name.0); | |||
} | |||
} | |||
/// Sets the category of this notification. This can be used by the | |||
/// notification server to filter or display the data in a certain way. | |||
/// ## `category` | |||
/// The category. | |||
pub fn set_category(&self, category: &str) { | |||
unsafe { | |||
ffi::notify_notification_set_category(self.to_glib_none().0, category.to_glib_none().0); | |||
} | |||
} | |||
/// Sets the timeout of the notification. To set the default time, pass | |||
/// `NOTIFY_EXPIRES_DEFAULT` as `timeout`. To set the notification to never | |||
/// expire, pass `NOTIFY_EXPIRES_NEVER`. | |||
/// | |||
/// Note that the timeout may be ignored by the server. | |||
/// ## `timeout` | |||
/// The timeout in milliseconds. | |||
pub fn set_timeout(&self, timeout: i32) { | |||
unsafe { | |||
ffi::notify_notification_set_timeout(self.to_glib_none().0, timeout); | |||
} | |||
} | |||
/// Sets the urgency level of this notification. | |||
/// | |||
/// See: `Urgency` | |||
/// ## `urgency` | |||
/// The urgency level. | |||
pub fn set_urgency(&self, urgency: Urgency) { | |||
unsafe { | |||
ffi::notify_notification_set_urgency(self.to_glib_none().0, urgency.to_glib()); | |||
} | |||
} | |||
/// Updates the notification text and icon. This won't send the update out | |||
/// and display it on the screen. For that, you will need to call | |||
/// `Notification::show`. | |||
/// ## `summary` | |||
/// The new required summary text. | |||
/// ## `body` | |||
/// The optional body text. | |||
/// ## `icon` | |||
/// The optional icon theme icon name or filename. | |||
/// | |||
/// # Returns | |||
/// | |||
/// `true`, unless an invalid parameter was passed. | |||
pub fn update<'a, 'b, P: Into<Option<&'a str>>, Q: Into<Option<&'b str>>>(&self, summary: &str, body: P, icon: Q) -> Result<(), glib::error::BoolError> { | |||
let body = body.into(); | |||
let body = body.to_glib_none(); | |||
let icon = icon.into(); | |||
let icon = icon.to_glib_none(); | |||
unsafe { | |||
glib::error::BoolError::from_glib(ffi::notify_notification_update(self.to_glib_none().0, summary.to_glib_none().0, body.0, icon.0), "Invalid parameter passed") | |||
} | |||
} | |||
} |