81 Commits

Author SHA1 Message Date
a951e61a6c Update libnotify deps 2017-09-02 01:00:43 +02:00
d830a339e1 Update libnotify-sys deps 2017-09-02 00:59:43 +02:00
843fb0c731 Fix build against latest glib 2017-07-19 19:47:08 +02:00
afcf7a7581 Fix build against latest gtk-rs 2017-07-14 00:47:21 +02:00
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
8e955a6e08 Add badges to libnotify-sys 2017-07-13 11:35:04 +02:00
a3d579d750 Fix LICENSE link 2017-07-13 11:24:15 +02:00
6536667a4d Reorder bagdes, add download count badge 2017-07-13 11:20:23 +02:00
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
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
437f2cc756 Rename new_notification() to new() 2017-07-10 01:09:21 +02:00
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
172cbd5143 Add lifetime specifiers to &self 2017-07-09 21:46:44 +02:00
8c16ab53b5 Update travis secret 2017-07-09 19:52:57 +02:00
f351cc15e2 Add Notification::close() 2017-07-09 19:33:53 +02:00
b77584e0a0 Add Notification::clear_hints() 2017-07-09 19:33:32 +02:00
c3897b7c0e Add Notification::set_image_from_pixbuf() 2017-07-09 19:33:13 +02:00
6166c861e4 Add Notification::set_urgency() 2017-07-09 19:31:25 +02:00
c2efdd0842 Add Notification::set_category() 2017-07-09 19:30:49 +02:00
a52c50a318 Add Author 2017-07-09 14:38:55 +02:00
34880d2117 Bump version to 0.5.0 2017-07-09 14:34:45 +02:00
73eb0cc68d Cosmetics 2017-07-09 14:25:30 +02:00
95263c33f8 Add Notification::set_hint() 2017-07-09 14:23:37 +02:00
cdc4af3be1 Add Notification::update() 2017-07-09 14:22:36 +02:00
8c66220a4e Add Notification::set_notification_timeout() 2017-07-09 14:22:06 +02:00
923c801814 Fix gtypes version constraint 2017-07-09 14:20:11 +02:00
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
bf90bccef8 Undeprecate 2017-07-09 13:52:54 +02:00
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
Mika Attila
d23eabffea Version bump 2015-09-19 09:42:31 +02:00
Mika Attila
ffd99b67e2 Depend on gtypes 2015-09-19 09:42:17 +02:00
Mika Attila
72df2c0adb Version bump 2015-03-27 08:34:00 +01:00
Mika Attila
dac1075025 Update to new crate naming rules 2015-03-25 19:04:43 +01:00
Mika Attila
d3ad5323fb Update doc example 2015-03-10 19:18:44 +01:00
Mika Attila
445f0b6d13 Implement std::fmt::Display for the error types 2015-03-10 19:14:18 +01:00
Mika Attila
a0955acabd Add example to the documentation 2015-03-10 08:46:54 +01:00
Mika Attila
e9665b08c2 Version bump 2015-03-09 21:18:05 +01:00
Mika Attila
c66aec1c86 Add documentation link 2015-03-09 21:17:41 +01:00
20 changed files with 847 additions and 135 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,14 +1,24 @@
[package]
name = "libnotify"
version = "0.0.1"
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"
keywords = ["libnotify", "notification"]
repository = "https://github.com/hasufell/rust-libnotify"
version = "1.0.2"
[dependencies]
libnotify-sys = "*"
glib-2_0-sys = "*"
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,9 +1,17 @@
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();
// 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

Submodule gir added at ac9a8dadb6

1
gir-files Submodule

Submodule gir-files added at 1f01de0ff0

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

@@ -1,131 +1,52 @@
extern crate "libnotify-sys" as sys;
extern crate "glib-2_0-sys" as glib;
//! Rustic bindings to [libnotify](https://developer.gnome.org/libnotify/)
//!
//! ```rust
//! extern crate libnotify;
//!
//! fn main() {
//! // 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();
//! }
//!
//! ```
use std::ffi::CString;
use std::marker::PhantomData;
#![warn(missing_docs)]
use glib::types::{
TRUE,
FALSE
};
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;
/// Error that can happen on context creation
#[derive(Debug)]
pub enum ContextCreationError {
/// Context already exists
AlreadyExists,
InitFailure,
NulError
}
#[derive(Debug)]
pub enum NotificationCreationError {
NulError,
Unknown
}
pub use enums::*;
pub use functions::*;
pub use notification::*;
/// 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})
macro_rules! assert_initialized_libnotify {
() => {
use functions::*;
if !is_initted() {
panic!("Notify system not initialized, invalid call of function");
}
}
}
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(()),
}
}
}
}