Compare commits

...

72 Commits

Author SHA1 Message Date
Julian Ospald a951e61a6c
Update libnotify deps 2017-09-02 01:00:43 +02:00
Julian Ospald d830a339e1
Update libnotify-sys deps 2017-09-02 00:59:43 +02:00
Julian Ospald 843fb0c731
Fix build against latest glib 2017-07-19 19:47:08 +02:00
Julian Ospald afcf7a7581
Fix build against latest gtk-rs 2017-07-14 00:47:21 +02:00
Julian Ospald 831b761b02 Explicitly add LICENSE to libnotify-sys subdir
So we also make sure it ends up in the cargo crate.
2017-07-13 11:41:45 +02:00
Julian Ospald 8e955a6e08 Add badges to libnotify-sys 2017-07-13 11:35:04 +02:00
Julian Ospald a3d579d750 Fix LICENSE link 2017-07-13 11:24:15 +02:00
Julian Ospald 6536667a4d Reorder bagdes, add download count badge 2017-07-13 11:20:23 +02:00
Julian Ospald f954a77778 Add documentation badges 2017-07-13 11:12:44 +02:00
Ospald, Julian fc8ca1af63 Fix documentation 2017-07-11 16:33:31 +02:00
Ospald, Julian f28b8bc052 Bump to 1.0.1 2017-07-11 15:59:55 +02:00
Ospald, Julian 49f09df64a Remove obsolete dependency 2017-07-11 15:59:24 +02:00
Ospald, Julian a8b22fa6ef Cosmetic README fix 2017-07-11 15:53:01 +02:00
Ospald, Julian 5f551cf664 Add README.md to libnotify-sys 2017-07-11 15:53:01 +02:00
Ospald, Julian 08d77ee4ff Update metadata 2017-07-11 15:53:01 +02:00
Ospald, Julian 03059f79c6 Remove git dependencies 2017-07-11 15:53:01 +02:00
Ospald, Julian 091ee97b70 Remove BoolError occurences
Because currently depends on unpublished glib binding.
2017-07-11 15:53:01 +02:00
Ospald, Julian d939bee7ea Cargo fmt 2017-07-11 15:24:10 +02:00
Ospald, Julian 557ebbc93f Fix examples 2017-07-11 15:18:40 +02:00
Ospald, Julian b50ff703ad Update README 2017-07-11 15:06:27 +02:00
Ospald, Julian a75ae6a1fe Fix documentation 2017-07-11 14:48:23 +02:00
Ospald, Julian d2a17eba0b Fix compiler warnings 2017-07-11 14:48:17 +02:00
Ospald, Julian e789326c83 Update .gitignore 2017-07-11 14:36:45 +02:00
Ospald, Julian 6a96044a68 Fix examples 2017-07-11 14:36:21 +02:00
Ospald, Julian cee315cf36 Fix travis secret 2017-07-11 14:11:04 +02:00
Ospald, Julian ac0502b16c Merge branch 'gir' 2017-07-11 13:58:52 +02:00
Ospald, Julian fb42397f55 Fix README 2017-07-11 13:58:06 +02:00
Ospald, Julian 69f5fe66f1 Fix travis 2017-07-11 13:58:06 +02:00
Julian Ospald 13850652a7 Switch to gir 2017-07-11 13:58:06 +02:00
Ospald, Julian 965a64aa55 Drop use of gtypes 2017-07-10 11:57:41 +02:00
Ospald, Julian 9f6e3f5d31 Add Drop impl for Notification
The notification is now unrefed via the GObject system.
2017-07-10 11:53:22 +02:00
Julian Ospald 437f2cc756
Rename new_notification() to new() 2017-07-10 01:09:21 +02:00
Julian Ospald fe4d803efe
Small rewrite:
* Use error-chain for errors and expose them
* Don't use Context object, since the lifetimes get us in trouble
  when used with gtk-rs, which has callback closures with static
  lifetime. Instead we just expose notify_init()/notify_uninit() and
  panic when functions are called before notify_init().
2017-07-10 01:01:36 +02:00
Julian Ospald 172cbd5143
Add lifetime specifiers to &self 2017-07-09 21:46:44 +02:00
Julian Ospald 8c16ab53b5
Update travis secret 2017-07-09 19:52:57 +02:00
Julian Ospald f351cc15e2
Add Notification::close() 2017-07-09 19:33:53 +02:00
Julian Ospald b77584e0a0
Add Notification::clear_hints() 2017-07-09 19:33:32 +02:00
Julian Ospald c3897b7c0e
Add Notification::set_image_from_pixbuf() 2017-07-09 19:33:13 +02:00
Julian Ospald 6166c861e4
Add Notification::set_urgency() 2017-07-09 19:31:25 +02:00
Julian Ospald c2efdd0842
Add Notification::set_category() 2017-07-09 19:30:49 +02:00
Julian Ospald a52c50a318
Add Author 2017-07-09 14:38:55 +02:00
Julian Ospald 34880d2117
Bump version to 0.5.0 2017-07-09 14:34:45 +02:00
Julian Ospald 73eb0cc68d
Cosmetics 2017-07-09 14:25:30 +02:00
Julian Ospald 95263c33f8
Add Notification::set_hint() 2017-07-09 14:23:37 +02:00
Julian Ospald cdc4af3be1
Add Notification::update() 2017-07-09 14:22:36 +02:00
Julian Ospald 8c66220a4e
Add Notification::set_notification_timeout() 2017-07-09 14:22:06 +02:00
Julian Ospald 923c801814
Fix gtypes version constraint 2017-07-09 14:20:11 +02:00
Julian Ospald 6e5a9ab5d4
Switch to using glib-sys
We need GVariant and to_glib_none() later,
which must be from the crate glib_sys.
2017-07-09 14:19:48 +02:00
Julian Ospald bf90bccef8
Undeprecate 2017-07-09 13:52:54 +02:00
Julian Ospald 7d80600657
Fix body/icon pointing to garbage
The pattern matching moves 'body' and drops it after
creation of the pointer. We must avoid the move, by using 'ref'.
2017-07-09 12:51:55 +02:00
Mika Attila 5ab8f64e88 Deprecate in favor of notify-rust 2017-04-01 17:55:11 +02:00
Mika Attila a61230b012 Update dependencies 2016-01-27 23:11:38 +01:00
Mika Attila a74f4c9888 Add convenience method to context for showing a notification 2015-11-03 10:06:33 +01:00
Mika Attila 69a2d18218 Version bump 2015-11-03 09:19:13 +01:00
Mika Attila c698097ffd Remove unnecessary return statement 2015-11-03 09:17:20 +01:00
Mika Attila 8daef60a03 Implement From<ffi::NulError> for error types that have this variant 2015-11-03 09:15:16 +01:00
Mika Attila d282d2cd50 Add remaining missing documentation 2015-11-03 01:04:22 +01:00
Mika Attila 6251e0ad5c Expose ffi::NulError in nul errors 2015-11-03 01:01:49 +01:00
Mika Attila db2578ea92 Use fmt::Result 2015-11-03 00:55:09 +01:00
Mika Attila ba947a35f8 Rename InitFailure to InitError and add documentation 2015-11-03 00:54:03 +01:00
Mika Attila 503eee4441 Warn about missing documentation 2015-11-03 00:51:20 +01:00
Mika Attila 4b0aaab709 Update doc example 2015-11-03 00:50:27 +01:00
Mika Attila 94bb46164f Add NotificationShowError 2015-11-03 00:49:12 +01:00
Mika Attila 3dfc03aebd Format source code with rustfmt 2015-11-02 23:55:35 +01:00
Mika Attila 7bc56e4974 Let's try this again, shall we? 2015-11-01 22:07:39 +01:00
Mika Attila d42152428f Remove some unnecessary stuff from .travis.yml 2015-11-01 22:05:12 +01:00
Mika Attila 619409ffc4 Add travis badge 2015-11-01 22:03:36 +01:00
Mika Attila 8e7b939a78 Add .travis.yml 2015-11-01 22:01:07 +01:00
Mika Attila d19aadb4d2 Version bump 2015-10-24 14:55:05 +02:00
Mika Attila 7556615e78 Specify exact versions of dependencies 2015-10-24 14:54:47 +02:00
Mika Attila 1636812abc Merge pull request #1 from mzabaluev/rename-glib-sys
Renaming of glib packages
2015-10-23 22:51:28 +02:00
Mikhail Zabaluev d979d8a2d1 Renamed glib packages
I'm going to normalize the package names in gi-rust, while also switching
to generated code that provides nearly all of the library API. This
package is one of the few that depends on the current name.
2015-10-23 23:34:09 +03:00
20 changed files with 841 additions and 176 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
Cargo.lock
target/
.cargo/
docs.md

6
.gitmodules vendored Normal file
View File

@ -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

30
.travis.yml Normal file
View File

@ -0,0 +1,30 @@
dist: trusty
sudo: false
language: rust
rust:
- nightly
- beta
- stable
addons:
apt:
packages:
- libgdk-pixbuf2.0-common
- libgdk-pixbuf2.0-dev
- libglib2.0-data
- libglib2.0-dev
- libnotify-dev
before_script:
- |
pip install 'travis-cargo<0.2' --user &&
export PATH=$HOME/.local/bin:$PATH
script:
- |
travis-cargo build &&
# travis-cargo test &&
travis-cargo --only stable doc
after_success:
- travis-cargo --only stable doc-upload
env:
global:
- TRAVIS_CARGO_NIGHTLY_FEATURE=""
- secure: B9+n+ikrYqSxK1SYOHIvjtYi58IvdVC0HYJxyDiJnzIcEtos/aDiGbMZU1pIvC+qIAibdltIqzZ1afVC1msfsxeaov2e4VPKfTJV0gwLLq6tzuuaOeujtM9YUUWrdr8QQXk3LEPIl8HD5jm6VTLcl2TqPeiiyn96rk67nA5jeS8=

View File

@ -1,16 +1,24 @@
[package]
name = "libnotify"
version = "0.0.4"
authors = ["Mika Attila <radiantstatue@gmail.com>"]
license = "MIT"
authors = [
"Mika Attila <radiantstatue@gmail.com>",
"Julian Ospald <hasufell@posteo.de>",
]
description = "Rust bindings to libnotify"
documentation = "https://hasufell.github.io/rust-libnotify/libnotify/"
keywords = [
"libnotify",
"notification",
]
license = "MIT"
name = "libnotify"
readme = "README.md"
repository = "https://github.com/crumblingstatue/rust-libnotify"
documentation = "http://crumblingstatue.github.io/doc/libnotify/libnotify/"
keywords = ["libnotify", "notification"]
repository = "https://github.com/hasufell/rust-libnotify"
version = "1.0.2"
[dependencies]
libnotify-sys = "*"
glib-2_0-sys = "*"
gtypes = "*"
gdk-pixbuf = "^0.2.0"
gdk-pixbuf-sys = "^0.4.0"
glib = "^0.3.1"
glib-sys = "^0.4.0"
gobject-sys = "^0.4.0"
libnotify-sys = "^1.0.1"

69
Gir.toml Normal file
View File

@ -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

19
Makefile Normal file
View File

@ -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

View File

@ -1,2 +1,12 @@
# libnotify-rs
Rust binding to libnotify
[![Latest Version](https://img.shields.io/crates/v/libnotify.svg)](https://crates.io/crates/libnotify)
[![License](https://img.shields.io/github/license/hasufell/rust-libnotify.svg)](LICENSE)
[![Crate download count](https://img.shields.io/crates/d/libnotify.svg)](https://crates.io/crates/libnotify)
[![Documentation (crates.io)](https://img.shields.io/badge/documentation-docs.rs-df3600.svg)](https://docs.rs/libnotify)
[![Documentation (master)](https://img.shields.io/badge/documentation-master-yellow.svg)](https://hasufell.github.io/rust-libnotify/)
[![Build Status](https://travis-ci.org/hasufell/rust-libnotify.svg)](https://travis-ci.org/hasufell/rust-libnotify)
[![Join the chat at https://gitter.im/hasufell/rust-libnotify](https://badges.gitter.im/hasufell/rust-libnotify.svg)](https://gitter.im/hasufell/rust-libnotify?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
# rust-libnotify
Rust binding to libnotify.

View File

@ -1,12 +1,17 @@
extern crate libnotify;
fn main() {
let notify = libnotify::Context::new("hello").unwrap_or_else(|e| {
panic!("{}", e);
});
let body_text = Some("This is the optional body text.");
let n = notify.new_notification("This is the summary.",
body_text,
None).unwrap_or_else(|e| panic!("{}", e));
n.show().ok().expect("Failed to show notification");
// Init libnotify
libnotify::init("myapp");
// Create a new notification (doesn't show it yet)
let n =
libnotify::Notification::new("Summary", Some("Optional Body"), None);
// Show the notification
n.show().unwrap();
// Update the existent notification
n.update("I am another notification", None, None).unwrap();
// Show the updated notification
n.show().unwrap();
// We are done, deinit
libnotify::uninit();
}

1
gir Submodule

@ -0,0 +1 @@
Subproject commit ac9a8dadb62d003af9f0c6ed46e82ff0971125e5

1
gir-files Submodule

@ -0,0 +1 @@
Subproject commit 1f01de0ff05a22bdb5de4b1a330c46bdafdea300

11
gir-libnotify.toml Normal file
View File

@ -0,0 +1,11 @@
[options]
work_mode = "sys"
library = "Notify"
version = "0.7"
min_cfg_version = "0.7.6"
external_libraries = [
"GLib",
"GObject",
"GdkPixbuf",
]

30
libnotify-sys/Cargo.toml Normal file
View File

@ -0,0 +1,30 @@
[package]
authors = [
"Mika Attila <radiantstatue@gmail.com>",
"Julian Ospald <hasufell@posteo.de>",
]
build = "build.rs"
description = "FFI bindings to libnotify"
keywords = [
"libnotify",
"notification",
]
license = "MIT"
links = "libnotify"
name = "libnotify-sys"
readme = "README.md"
repository = "https://github.com/hasufell/rust-libnotify"
version = "1.0.1"
[build-dependencies]
pkg-config = ">=0.3.9"
[dependencies]
bitflags = "^0.9.1"
gdk-pixbuf-sys = "^0.4.0"
glib-sys = "^0.4.0"
gobject-sys = "^0.4.0"
libc = "^0.2.30"
[lib]
name = "libnotify_sys"

21
libnotify-sys/LICENSE Normal file
View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2015 Mika Attila
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

7
libnotify-sys/README.md Normal file
View File

@ -0,0 +1,7 @@
[![Latest Version](https://img.shields.io/crates/v/libnotify-sys.svg)](https://crates.io/crates/libnotify-sys)
[![License](https://img.shields.io/github/license/hasufell/rust-libnotify.svg)](LICENSE)
[![Crate download count](https://img.shields.io/crates/d/libnotify-sys.svg)](https://crates.io/crates/libnotify-sys)
# rust-libnotify-sys
Rust FFI declarations for libnotify

61
libnotify-sys/build.rs Normal file
View File

@ -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),
}
}

98
libnotify-sys/src/lib.rs Normal file
View File

@ -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;
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();
}

45
src/enums.rs Normal file
View File

@ -0,0 +1,45 @@
// 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),
}
}
}

112
src/functions.rs Normal file
View File

@ -0,0 +1,112 @@
use ffi;
use glib::translate::*;
use glib_ffi;
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(str)` on error.
// TODO: switch back to BoolError when it hits stable glib
pub fn init(app_name: &str) -> Result<(), String> {
unsafe {
let b = ffi::notify_init(app_name.to_glib_none().0);
match b {
glib_ffi::GFALSE => Err(
String::from("Failed to initialize libnotify"),
),
_ => Ok(()),
}
}
}
/// 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();
}
}

View File

@ -4,170 +4,49 @@
//! extern crate libnotify;
//!
//! fn main() {
//! let notify = libnotify::Context::new("hello").unwrap_or_else(|e| {
//! panic!("{}", e);
//! });
//! let body_text = Some("This is the optional body text.");
//! let n = notify.new_notification("This is the summary.",
//! body_text,
//! None).unwrap_or_else(|e| {
//! panic!("{}", e);
//! });
//! n.show().ok().expect("Failed to show notification");
//! // Init libnotify
//! libnotify::init("myapp").unwrap();
//! // Create a new notification (doesn't show it yet)
//! let n = libnotify::Notification::new("Summary",
//! Some("Optional Body"),
//! None);
//! // Show the notification
//! n.show().unwrap();
//! // Update the existent notification
//! n.update("I am another notification", None, None).unwrap();
//! // Show the updated notification
//! n.show().unwrap();
//! // We are done, deinit
//! libnotify::uninit();
//! }
//!
//! ```
extern crate libnotify_sys as sys;
extern crate glib_2_0_sys as glib;
extern crate gtypes;
#![warn(missing_docs)]
use std::ffi::CString;
use std::marker::PhantomData;
use std::fmt;
extern crate gdk_pixbuf;
#[macro_use]
extern crate glib;
extern crate glib_sys as glib_ffi;
extern crate gobject_sys as gobject_ffi;
extern crate libnotify_sys as ffi;
use gtypes::{
TRUE,
FALSE
};
/// Error that can happen on context creation
#[derive(Debug)]
pub enum ContextCreationError {
/// Context already exists
AlreadyExists,
InitFailure,
NulError
}
pub use enums::*;
pub use functions::*;
pub use notification::*;
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.")
macro_rules! assert_initialized_libnotify {
() => {
use functions::*;
if !is_initted() {
panic!("Notify system not initialized, invalid call of function");
}
}
}
#[derive(Debug)]
pub enum NotificationCreationError {
NulError,
Unknown
}
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")
}
}
}
/// The context which within libnotify operates.
///
/// Only one context can exist at a time.
pub struct Context;
impl Context {
/// Create a new context
///
/// Arguments:
///
/// - app_name: The name of the application using the context
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)
}
/// Creates a new Notification.
///
/// Arguments:
///
/// - summary: Required summary text
/// - body: Optional body text
/// - icon: Optional icon theme icon name or filename
pub fn new_notification(&self, summary: &str,
body: Option<&str>,
icon: Option<&str>)
-> Result<Notification, NotificationCreationError> {
let summary = match CString::new(summary) {
Ok(cstr) => cstr,
Err(_) => return Err(NotificationCreationError::NulError)
};
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()
};
unsafe {
let n = sys::notify_notification_new(summary.as_ptr(),
body_ptr,
icon_ptr);
if n.is_null() {
return Err(NotificationCreationError::Unknown);
}
Ok(Notification{handle: n, _phantom: PhantomData})
}
}
}
impl Drop for Context {
fn drop(&mut self) {
unsafe {
sys::notify_uninit();
}
}
}
/// A passive pop-up notification
pub struct Notification<'a> {
handle: *mut sys::NotifyNotification,
_phantom: PhantomData<&'a Context>
}
impl<'a> Notification<'a> {
/// Tells the notification server to display the notification
/// on the screen.
pub fn show(&'a self) -> Result<(), ()> {
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(())
}
}
}
mod enums;
mod functions;
mod notification;

251
src/notification.rs Normal file
View File

@ -0,0 +1,251 @@
use Urgency;
use ffi;
use gdk_pixbuf;
use glib::translate::*;
use glib;
use glib_ffi;
use gobject_ffi;
use std::mem;
use std::ptr;
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
///
/// `Ok(())` on success, or `Err(err)` on error
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
///
/// `Ok(())` on success, or `Err(err)` on 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
///
/// `Ok(())` on success, or `Err(str)` if an invalid parameter was passed
// TODO: switch back to BoolError when it hits stable glib
pub fn update<
'a,
'b,
P: Into<Option<&'a str>>,
Q: Into<Option<&'b str>>,
>(
&self,
summary: &str,
body: P,
icon: Q,
) -> Result<(), String> {
let body = body.into();
let body = body.to_glib_none();
let icon = icon.into();
let icon = icon.to_glib_none();
unsafe {
let b = ffi::notify_notification_update(
self.to_glib_none().0,
summary.to_glib_none().0,
body.0,
icon.0,
);
match b {
glib_ffi::GFALSE => Err(
String::from("Invalid parameter passed"),
),
_ => Ok(()),
}
}
}
}