Move libnotify-ng to libnotify.

This commit is contained in:
Christian Hammond 2006-01-11 07:48:56 +00:00
commit f74c4465ce
32 changed files with 2819 additions and 2003 deletions

10
AUTHORS
View File

@ -1,7 +1,3 @@
Main developers: Christian Hammond <chipx86@chipx86.com>
Christian Hammond <chipx86@chipx86.com> Mike Hearn <mike@navi.cx>
Mike Hearn <mike@navi.cx> John (J5) Palmieri <johnp@redhat.com>
Patch contributors:
Richard Hughes
Duarte Henriques

214
ChangeLog
View File

@ -1,179 +1,101 @@
Wed Nov 09 00:50:23 PST 2005 Christian Hammond <chipx86@chipx86.com> Tue Jan 10 23:33:47 PST 2006 Christian Hammond <chipx86@chipx86.com>
* configure.ac:
- Require D-BUS 0.36+.
Tue Jan 10 22:55:35 PST 2006 Christian Hammond <chipx86@chipx86.com>
* tests/test-default-action.c:
* tools/notify-send.c: * tools/notify-send.c:
- Call notify_icon_new_from_uri() and not notify_icon_new(), - Fix some C99 usage.
since notify_icon_new() doesn't actually take parameters.
- Fix the help for --type.
Sun Nov 06 16:33:30 PST 2005 Christian Hammond <chipx86@chipx86.com> Tue Jan 10 16:20:27 MST 2006 David Trowbridge <trowbrds@gmail.com>
* tests/Makefile.am: * libnotify/Makefile.am:
- Add applet-critical.png to EXTRA_DIST. - Make sure marshal files actually get built
==================== 0.2.2 ==================== Mon Jan 09 11:13:15 PST 2006 Christian Hammond <chipx86@chipx86.com>
Wed Aug 10 01:59:26 PDT 2005 Christian Hammond <chipx86@chipx86.com> * libnotify/Makefile.am:
* libnotify/Makefile.in:
* NEWS: A libnotify/notify-marshal.list:
D libnotify/notifymarshal.c:
D libnotify/notifymarshal.h:
* libnotify/notifynotification.c:
* configure.ac: * configure.ac:
- Bump to version 0.2.2 and prepare for release. - Generate the marshal files automatically. We shouldn't be doing it
by hand.
Wed Aug 10 01:13:56 PDT 2005 Christian Hammond <chipx86@chipx86.com> Mon Jan 09 10:15:57 PST 2006 Christian Hammond <chipx86@chipx86.com>
D tools/test-replace.c:
* tools/notify-send.c:
- Simplify notify-send a little, and nuke tools/test-replace. It
doesn't belong there.
Wed Aug 10 01:12:55 PDT 2005 Christian Hammond <chipx86@chipx86.com>
* NEWS:
* configure.ac:
- Bump to version 0.2.1.90.
Mon Jul 25 22:50:08 PDT 2005 Christian Hammond <chipx86@gnupdate.org>
* NEWS:
* configure.ac:
- Bump to version 0.2.1.
Mon Jul 25 22:47:02 PDT 2005 Christian Hammond <chipx86@gnupdate.org>
* libnotify/Makefile.in:
* libnotify/notify.c: * libnotify/notify.c:
* tests/test-xy.c: * libnotify/notifynotification.c:
- Use a variant type for the hint dictionary values. This let's us
actually use various data types in D-BUS 0.3x.
Thu Jul 28 01:54:27 PDT 2005 Christian Hammond <chipx86@chipx86.com>
* docs/notification-spec.xml:
- Bump to version 0.7, and add the x, y hint info.
* NEWS:
* configure.ac:
- Bump to version 0.2.0.
Thu Jul 28 01:52:03 PDT 2005 Christian Hammond <chipx86@chipx86.com>
* libnotify/notify.c:
* libnotify/notify.h:
- Don't send all hint values as strings. Send as integers, booleans,
or strings, depending on what the user set.
Wed Jul 27 23:08:43 PDT 2005 Christian Hammond <chipx86@chipx86.com>
* libnotify/notify.c:
* libnotify/notify.h:
- Support setting boolean hints.
Mon Jul 25 18:03:12 PDT 2005 Christian Hammond <chipx86@gnupdate.org>
* libnotify/notify.c:
- Disable animation support on D-BUS 0.3x, since arrays of arrays
of a type seems broken.
Mon Jul 25 18:00:12 PDT 2005 Christian Hammond <chipx86@gnupdate.org>
* libnotify/notify.c:
* tests/test-animation.c:
- Flush the D-BUS connection queue on uninit so that messages go
through and so we don't trigger this ugly little warning on
D-BUS 0.3x.
- Fix a compiler warning on gcc4.
Wed Jul 27 02:12:31 PDT 2005 Christian Hammond <chipx86@chipx86.com>
* libnotify/notify.c:
- Actually set the expires flag in the notification handle so we
don't just kill off all notifications as soon as we create them
and exit.
Wed Jul 27 01:47:25 PDT 2005 Christian Hammond <chipx86@chipx86.com>
* libnotify/notify.c:
- Handle SIGINT and SIGTERM When raised, we call notify_uninit.
notify_uninit now checks if there are any non-expiring notifications
and closes them. This is a best-effort to preventing stale
notifications from a dead process from displaying on the screen. Of
course, we can't handle SIGKILL, so we're stuck there.
Wed Jul 27 01:13:12 PDT 2005 Christian Hammond <chipx86@chipx86.com>
* libnotify/notify.c:
- Patch (bug #3050) by Duarte Henriques to prevent closing
notifications we don't own.
Wed Jul 27 01:08:56 PDT 2005 Christian Hammond <chipx86@chipx86.com>
* libnotify/notify.c:
* libnotify/notify.h:
* tests/test-default-action.c: * tests/test-default-action.c:
* tests/test-image.c: * tests/test-image.c:
* tests/test-multi-actions.c: * tests/test-multi-actions.c:
- Patch (bug #3734) by Duarte Henriques to provide a convenient way * tests/test-replace-widget.c:
of integrating libnotify with the glib mainloop. Modifications by
me to make it even easier.
Wed Jul 27 00:51:58 PDT 2005 Christian Hammond <chipx86@chipx86.com>
* tests/test-animation.c:
* tests/test-basic.c:
* tests/test-error.c:
* tests/test-image.c:
* tests/test-markup.c:
* tests/test-xy.c:
* tests/test-xy-stress.c: * tests/test-xy-stress.c:
- Actually support our own spec and use the number of seconds until - Clean up lots of warnings.
expiration instead of current time + number of seconds. That was
creating all kinds of problems.
Wed Jul 27 00:31:47 PDT 2005 Christian Hammond <chipx86@chipx86.com> ========================= 0.3.0 =========================
* libnotify/dbus-compat.h: Tue Dec 13 2005 John (J5) Palmieri <johnp@redhat.com>
- Compile under D-BUS 0.2x again.
* Release 0.3.0
Wed Jul 27 00:18:16 PDT 2005 Christian Hammond <chipx86@chipx86.com> * tests/Makefile.am, tools/Makefile.am: patch from Rodney
Dawes <dobey at novell.com> fixing make distcheck
* libnotify/notify.c: * tools/notify-send.c: use show_and_forget
- If the handle given in ActionInvoked is not found in the local
table of handles, return from the ActionInvoked handler. Otherwise,
every program using libnotify will crash when a notification is
clicked. Oops!
Sat Jul 16 02:53:06 PDT 2005 Christian Hammond <chipx86@gnupdate.org> Fri Dec 09 2005 John (J5) Palmieri <johnp@redhat.com>
* libnotify/notify.c: * libnotify/notifymarshal.[c|h]: new files where GLib callback
- Fix the key type for the dictionary for hints on D-BUS 0.3x. The marshalers are added
notification-daemon side is still broken in this regard.
Sat Jul 16 02:51:42 PDT 2005 Christian Hammond <chipx86@gnupdate.org> * libnotify/notifynotification.c (notify_notifiaction_init): Add a
marshaller for signals with uint, string parameters
(_gslist_to_string_array): new internal method that coverts
a GSList to a NULL terminated array of strings
(_notify_notification_show_internal): send the actions list as an
array of strings, not a GSList which does not work with the bindings
* libnotify/Makefile.am: notifymarshal.[c|h] added
* libnotify/dbus-compat.h: * tests/test-multi-actions.c: working example of using actions
* libnotify/notify.c:
- Fixed a couple of D-BUS 0.3x bugs. Several remain though.
Tue Jul 12 12:29:08 PDT 2005 Christian Hammond <chipx86@chipx86.com> Fri Dec 02 2005 John (J5) Palmieri <johnp@redhat.com>
* AUTHORS: * libnotify/notifynotification.c (notify_notification_add_action):
- Update the AUTHORs file with our current contributors. implement adding actions
(_action_signal_handler): handle actions coming from the server
(notify_notifcation_clear_actions): new method for clearning out
the actions list and hash
Tue Jul 12 12:28:16 PDT 2005 Christian Hammond <chipx86@chipx86.com> Fri Dec 02 2005 John (J5) Palmieri <johnp@redhat.com>
* tests/Makefile.am: * libnotify/notifynotification.c (notify_notification_show_and_forget):
* tools/Makefile.am: new method that shows and then unrefs the NotifyNotification object.
* libnotify.spec.in: use this if you just want to fire off a quick notification.
- Patch by Richard Hughes to fix make distcheck, and to provide a
Fedora Core 4 RPM spec file.
Sun Jul 10 16:46:57 PDT 2005 Christian Hammond <chipx86@chipx86.com> * various compiler warning cleanups
* tests/test-replace.c: Fri Dec 02 2005 John (J5) Palmieri <johnp@redhat.com>
- Decrease the wait time for the replacement notification.
Sat Jul 9 18:30:41 2005 Duarte Henriques <maxcow@users.sourceforge.net> * libnotify/notifynotification.c (SIGNAL_TYPE_CLOSED): "closed" glib
signal added
(notify_notification_clear_hints): New API for clearing out the
hints hash
(notify_notification_ref, notify_notification_unref): removed - use
g_object_ref/unref
* libnotify/notify.c: * tests/*: Various changes to the test binaries
- Fill in handle->user_data in notify_send_notification_varg
Thu Nov 10 14:00:00 EST 2005 John (J5) Palmieri <johnp@redhat.com>
* Complete rewrite and first import to libnotify-ng module in SVN
Mon Jul 04 02:13:56 PDT 2005 Christian Hammond <chipx86@chipx86.com> Mon Jul 04 02:13:56 PDT 2005 Christian Hammond <chipx86@chipx86.com>

13
NEWS
View File

@ -1,11 +1,4 @@
version 0.2.3: libnotify 0.3.0
* Fix notify-send to work with icon parameters (bug #4308) ===
version 0.2.2 (10-August-2005): * First release of the new GObject based API and simpler wire protocol
* Fixed many run-time issues with PPC and AMD64 (Martin Pitt)
version 0.2.1 (28-July-2005):
* Fixed hint support for D-BUS 0.3x.
version 0.2.0 (28-July-2005):
* Initial public release.

View File

@ -3,18 +3,18 @@ dnl Process this file with autoconf to create configure.
dnl ################################################################ dnl ################################################################
dnl # Initialize autoconf dnl # Initialize autoconf
dnl ################################################################ dnl ################################################################
AC_INIT(libnotify, 0.2.2, chipx86@chipx86.com) AC_INIT(libnotify, 0.3.0, chipx86@gnupdate.org)
AC_PREREQ(2.50) AC_PREREQ(2.50)
AC_CONFIG_SRCDIR(config.h.in) AC_CONFIG_SRCDIR(config.h.in)
AC_COPYRIGHT([Copyright 2004-2005 Christian Hammond]) AC_COPYRIGHT([Copyright 2004 Christian Hammond])
dnl ################################################################ dnl ################################################################
dnl # Version information dnl # Version information
dnl ################################################################ dnl ################################################################
LIBGALAGO_MAJOR_VERSION=0 LIBGALAGO_MAJOR_VERSION=0
LIBGALAGO_MINOR_VERSION=2 LIBGALAGO_MINOR_VERSION=3
LIBGALAGO_MICRO_VERSION=2 LIBGALAGO_MICRO_VERSION=0
LIBGALAGO_DEVEL_VERSION=0 LIBGALAGO_DEVEL_VERSION=0
LIBGALAGO_VERSION=$LIBGALAGO_MAJOR_VERSION.$LIBGALAGO_MINOR_VERSION.$LIBGALAGO_MICRO_VERSION LIBGALAGO_VERSION=$LIBGALAGO_MAJOR_VERSION.$LIBGALAGO_MINOR_VERSION.$LIBGALAGO_MICRO_VERSION
@ -89,7 +89,8 @@ AM_PROG_LIBTOOL
AC_CHECK_LIB([popt], [poptGetArg], , AC_MSG_ERROR([Popt is required])) AC_CHECK_LIB([popt], [poptGetArg], , AC_MSG_ERROR([Popt is required]))
pkg_modules="glib-2.0 >= 2.2.2, dbus-1 >= 0.23, dbus-glib-1 >= 0.23" REQ_DBUS_VERSION=0.36
pkg_modules="gtk+-2.0 >= 2.2.2 glib-2.0 >= 2.2.2, dbus-1 >= $REQ_DBUS_VERSION, dbus-glib-1 >= $REQ_DBUS_VERSION"
PKG_CHECK_MODULES(PACKAGE, [$pkg_modules]) PKG_CHECK_MODULES(PACKAGE, [$pkg_modules])
AC_SUBST(PACKAGE_CFLAGS) AC_SUBST(PACKAGE_CFLAGS)
AC_SUBST(PACKAGE_LIBS) AC_SUBST(PACKAGE_LIBS)
@ -107,6 +108,9 @@ AM_CONDITIONAL(HAVE_GDK, test "x$have_gdk" = "xyes")
AC_SUBST(GDK_CFLAGS) AC_SUBST(GDK_CFLAGS)
AC_SUBST(GDK_LIBS) AC_SUBST(GDK_LIBS)
GLIB_GENMARSHAL=`pkg-config --variable=glib_genmarshal glib-2.0`
AC_SUBST(GLIB_GENMARSHAL)
dnl dnl
dnl Check the D-BUS version. dnl Check the D-BUS version.
dnl dnl

View File

@ -1,10 +1,3 @@
Mon Jul 25 22:48:54 PDT 2005 Christian Hammond <chipx86@gnupdate.org>
* notification-spec.xml:
- Bump to version 0.7.
- Mention the x, y hints.
- Talk about variants as the dictionary values for hints.
Fri Apr 01 09:11:38 PST 2005 Christian Hammond <chipx86@gnupdate.org> Fri Apr 01 09:11:38 PST 2005 Christian Hammond <chipx86@gnupdate.org>
* notification-spec.xml: * notification-spec.xml:

File diff suppressed because it is too large Load Diff

View File

@ -6,8 +6,8 @@
<article id="index"> <article id="index">
<articleinfo> <articleinfo>
<title>Desktop Notifications Specification</title> <title>Desktop Notifications Specification</title>
<releaseinfo>Version 0.7</releaseinfo> <releaseinfo>Version 0.5</releaseinfo>
<date>28 July 2005</date> <date>2 October 2004</date>
<authorgroup> <authorgroup>
<author> <author>
<firstname>Mike</firstname> <firstname>Mike</firstname>
@ -29,14 +29,6 @@
</author> </author>
</authorgroup> </authorgroup>
<revhistory> <revhistory>
<revision>
<revnumber>0.7</revnumber>
<date>28 July 2005</date>
<authorinitials>cdh</authorinitials>
<revremark>
Added "x" and "y" hints. Talk about the variant type for hint values.
</revremark>
</revision>
<revision> <revision>
<revnumber>0.6</revnumber> <revnumber>0.6</revnumber>
<date>1 April 2005</date> <date>1 April 2005</date>
@ -702,13 +694,6 @@
consensus is reached, the hint name should be in the form of consensus is reached, the hint name should be in the form of
<literal>"x-<replaceable>vendor</replaceable>-<replaceable>name</replaceable>."</literal> <literal>"x-<replaceable>vendor</replaceable>-<replaceable>name</replaceable>."</literal>
</para> </para>
<para>
The value type for the hint dictionary in D-BUS is of the
<literal>DBUS_TYPE_VARIANT</literal> container type. This allows different
data types (string, integer, boolean, etc.) to be used for hints. When
adding a dictionary of hints, this type must be used, rather than putting
the actual hint value in as the dictionary value.
</para>
<para> <para>
The following table lists the standard hints as defined by this The following table lists the standard hints as defined by this
specification. Future hints may be proposed and added to this list specification. Future hints may be proposed and added to this list
@ -741,22 +726,6 @@
play its own sound. play its own sound.
</entry> </entry>
</row> </row>
<row>
<entry><literal>"x"</literal></entry>
<entry>int</entry>
<entry>
Specifies the X location on the screen that the notification should
point to. The <literal>"y"</literal> hint must also be specified.
</entry>
</row>
<row>
<entry><literal>"y"</literal></entry>
<entry>int</entry>
<entry>
Specifies the Y location on the screen that the notification should
point to. The <literal>"x"</literal> hint must also be specified.
</entry>
</row>
</tbody> </tbody>
</tgroup> </tgroup>
</table> </table>

View File

@ -1,7 +1,7 @@
prefix=@prefix@ prefix=@prefix@
exec_prefix=${prefix} exec_prefix=@exec_prefix@
libdir=${exec_prefix}/lib libdir=@libdir@
includedir=${prefix}/include includedir=@includedir@
Name: libnotify Name: libnotify
Description: Notifications Library Description: Notifications Library

View File

@ -1,53 +0,0 @@
Summary: Desktop notifications library
Name: libnotify
Version: @VERSION@
Release: 1%{?dist}
License: GPL
Group: Applications/System
Source: http://www.galago.info/files/releases/source/libnotify-%{version}.tar.gz
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
URL: http://svn.galago.info/trunk/libnotify
BuildPrereq: dbus-devel >= 0.30
Requires: dbus >= 0.30
%description
A library that sends desktop notifications to a notification daemon, as
defined in the Desktop Notifications spec. These notifications can be
used to inform the user about an event or display some form of
information without getting in the user's way.
%prep
%setup -q
%build
%configure
make
%install
rm -rf $RPM_BUILD_ROOT
%makeinstall
%clean
rm -rf $RPM_BUILD_ROOT
%post
/sbin/ldconfig
%postun
/sbin/ldconfig
%files
%defattr(-,root,root)
%doc AUTHORS ChangeLog COPYING README
%{_bindir}/*
%{_libdir}/lib*.a
%{_libdir}/lib*.so
%{_libdir}/lib*.la
%{_libdir}/lib*.so.*
%{_libdir}/pkgconfig/*
%{_includedir}/*
%changelog
* Mon Jul 12 2005 Richard Hughes <richard@hughsie.com> 0.0.1-1
- initial packaging of 0.0.1

View File

@ -1,13 +1,23 @@
notifyincdir = $(includedir)/libnotify notifyincdir = $(includedir)/libnotify
MARSHAL_PREFIX = notify_marshal
MARSHAL_FILE = notify-marshal
lib_LTLIBRARIES = libnotify.la lib_LTLIBRARIES = libnotify.la
notifyinc_HEADERS = \ notifyinc_HEADERS = \
notify.h notify.h \
notifynotification.h \
notifycommon.h
libnotify_la_SOURCES = \ noinst_HEADERS = \
dbus-compat.h \ notify-marshal.h
notify.c
libnotify_la_SOURCES = \
dbus-compat.h \
notify.c \
notifynotification.c \
notify-marshal.c
libnotify_la_LIBADD = \ libnotify_la_LIBADD = \
$(PACKAGE_LIBS) $(PACKAGE_LIBS)
@ -15,5 +25,24 @@ libnotify_la_LIBADD = \
libnotify_la_LDFLAGS = \ libnotify_la_LDFLAGS = \
-version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
BUILT_SOURCES = \
notify-marshal.c \
notify-marshal.h
notify-marshal.h: notify-marshal.list
$(GLIB_GENMARSHAL) --prefix=$(MARSHAL_PREFIX) notify-marshal.list \
--header > notify-marshal.h
notify-marshal.c: notify-marshal.list
$(GLIB_GENMARSHAL) --prefix=$(MARSHAL_PREFIX) notify-marshal.list \
--body > notify-marshal.c
EXTRA_DIST = \
notify-marshal.list
CLEANFILES = \
notify-marshal.c \
notify-marshal.h
INCLUDES = \ INCLUDES = \
$(PACKAGE_CFLAGS) $(PACKAGE_CFLAGS)

View File

@ -40,59 +40,20 @@
dbus_message_iter_append_basic((iter), DBUS_TYPE_DOUBLE, &(val)) dbus_message_iter_append_basic((iter), DBUS_TYPE_DOUBLE, &(val))
# define _notify_dbus_message_iter_append_byte_array(iter, data, len) \ # define _notify_dbus_message_iter_append_byte_array(iter, data, len) \
{ \ dbus_message_iter_append_fixed_array((iter), DBUS_TYPE_BYTE, &(data), \
DBusMessageIter array_iter; \ (len))
dbus_message_iter_open_container((iter), DBUS_TYPE_ARRAY, \
DBUS_TYPE_BYTE_AS_STRING, \
&array_iter); \
dbus_message_iter_append_fixed_array(&array_iter, DBUS_TYPE_BYTE, \
&(data), (len)); \
dbus_message_iter_close_container((iter), &array_iter); \
}
# define _notify_dbus_message_iter_append_boolean_array(iter, data, len) \ # define _notify_dbus_message_iter_append_boolean_array(iter, data, len) \
{ \ dbus_message_iter_append_fixed_array((iter), DBUS_TYPE_BOOLEAN, &(data), \
DBusMessageIter array_iter; \ (len))
dbus_message_iter_open_container((iter), DBUS_TYPE_ARRAY, \
DBUS_TYPE_BOOLEAN_AS_STRING, \
&array_iter); \
dbus_message_iter_append_fixed_array(&array_iter, DBUS_TYPE_BOOLEAN, \
&(data), (len)); \
dbus_message_iter_close_container((iter), &array_iter); \
}
# define _notify_dbus_message_iter_append_int32_array(iter, data, len) \ # define _notify_dbus_message_iter_append_int32_array(iter, data, len) \
{ \ dbus_message_iter_append_fixed_array((iter), DBUS_TYPE_INT32, &(data), \
DBusMessageIter array_iter; \ (len))
dbus_message_iter_open_container((iter), DBUS_TYPE_ARRAY, \
DBUS_TYPE_INT32_AS_STRING, \
&array_iter); \
dbus_message_iter_append_fixed_array(&array_iter, DBUS_TYPE_INT32, \
&(data), (len)); \
dbus_message_iter_close_container((iter), &array_iter); \
}
# define _notify_dbus_message_iter_append_uint32_array(iter, data, len) \ # define _notify_dbus_message_iter_append_uint32_array(iter, data, len) \
{ \ dbus_message_iter_append_fixed_array((iter), DBUS_TYPE_UINT32, &(data), \
DBusMessageIter array_iter; \ (len))
dbus_message_iter_open_container((iter), DBUS_TYPE_ARRAY, \
DBUS_TYPE_UINT32_AS_STRING, \
&array_iter); \
dbus_message_iter_append_fixed_array(&array_iter, DBUS_TYPE_UINT32, \
&(data), (len)); \
dbus_message_iter_close_container((iter), &array_iter); \
}
# define _notify_dbus_message_iter_append_string_array(iter, data, len) \ # define _notify_dbus_message_iter_append_string_array(iter, data, len) \
{ \ dbus_message_iter_append_fixed_array((iter), DBUS_TYPE_STRING, \
DBusMessageIter array_iter; \ &(data), (len))
int i; \
dbus_message_iter_open_container((iter), DBUS_TYPE_ARRAY, \
DBUS_TYPE_STRING_AS_STRING, \
&array_iter); \
for (i = 0; i < len; i++) \
{ \
dbus_message_iter_append_basic(&array_iter, DBUS_TYPE_STRING, \
&((char **)data)[i]); \
} \
dbus_message_iter_close_container((iter), &array_iter); \
}
# define _notify_dbus_message_iter_get_byte(iter, retvar) \ # define _notify_dbus_message_iter_get_byte(iter, retvar) \
dbus_message_iter_get_basic((iter), &(retvar)) dbus_message_iter_get_basic((iter), &(retvar))
@ -107,21 +68,16 @@
# define _notify_dbus_message_iter_get_double(iter, retvar) \ # define _notify_dbus_message_iter_get_double(iter, retvar) \
dbus_message_iter_get_basic((iter), &(retvar)) dbus_message_iter_get_basic((iter), &(retvar))
# define _notify_dbus_message_iter_get_fixed_array(iter, data, len) \ # define _notify_dbus_message_iter_get_byte_array \
{ \ dbus_message_iter_get_fixed_array
DBusMessageIter array_iter; \ # define _notify_dbus_message_iter_get_boolean_array \
dbus_message_iter_recurse((iter), &array_iter); \ dbus_message_iter_get_fixed_array
dbus_message_iter_get_fixed_array(&array_iter, (data), (len)); \ # define _notify_dbus_message_iter_get_int32_array \
} dbus_message_iter_get_fixed_array
# define _notify_dbus_message_iter_get_uint32_array \
# define _notify_dbus_message_iter_get_byte_array(iter, data, len) \ dbus_message_iter_get_fixed_array
_notify_dbus_message_iter_get_fixed_array((iter), (data), (len)) # define _notify_dbus_message_iter_get_string_array(iter, array, num_items) \
# define _notify_dbus_message_iter_get_boolean_array(iter, data, len) \ dbus_message_iter_get_fixed_array((iter), (array), (num_items))
_notify_dbus_message_iter_get_fixed_array((iter), (data), (len))
# define _notify_dbus_message_iter_get_int32_array(iter, data, len) \
_notify_dbus_message_iter_get_fixed_array((iter), (data), (len))
# define _notify_dbus_message_iter_get_uint32_array(iter, data, len) \
_notify_dbus_message_iter_get_fixed_array((iter), (data), (len))
#else /* D-BUS < 0.30 */ #else /* D-BUS < 0.30 */
# define DBUS_INTERFACE_DBUS DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS # define DBUS_INTERFACE_DBUS DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS
@ -129,14 +85,13 @@
# define DBUS_PATH_DBUS DBUS_PATH_ORG_FREEDESKTOP_DBUS # define DBUS_PATH_DBUS DBUS_PATH_ORG_FREEDESKTOP_DBUS
# define DBUS_ERROR_SERVICE_UNKNOWN DBUS_ERROR_SERVICE_DOES_NOT_EXIST # define DBUS_ERROR_SERVICE_UNKNOWN DBUS_ERROR_SERVICE_DOES_NOT_EXIST
# define dbus_message_iter_init_append(msg, iter) \ # define dbus_bus_start_service_by_name dbus_bus_activate_service
dbus_message_iter_init(msg, iter)
# define dbus_bus_start_service_by_name(conn, service, flags, result, error) \
dbus_bus_activate_service((conn), (service), (flags), (result), (error))
# define dbus_message_iter_close_container(iter, container_iter) # define dbus_message_iter_close_container(iter, container_iter)
# define dbus_message_iter_init_append(msg, iter) \
dbus_message_iter_init(msg, iter)
# define _notify_dbus_message_iter_append_byte(iter, val) \ # define _notify_dbus_message_iter_append_byte(iter, val) \
dbus_message_iter_append_byte((iter), (val)) dbus_message_iter_append_byte((iter), (val))
# define _notify_dbus_message_iter_append_boolean(iter, val) \ # define _notify_dbus_message_iter_append_boolean(iter, val) \
@ -182,6 +137,8 @@
dbus_message_iter_get_int32_array((iter), (data), (len)) dbus_message_iter_get_int32_array((iter), (data), (len))
# define _notify_dbus_message_iter_get_uint32_array(iter, data, len) \ # define _notify_dbus_message_iter_get_uint32_array(iter, data, len) \
dbus_message_iter_get_uint32_array((iter), (data), (len)) dbus_message_iter_get_uint32_array((iter), (data), (len))
# define _notify_dbus_message_iter_get_string_array(iter, data, len) \
dbus_message_iter_get_string_array((iter), (data), (len))
#endif #endif
#endif /* NOTIFY_DBUS_COMPAT_H_ */ #endif /* NOTIFY_DBUS_COMPAT_H_ */

View File

@ -0,0 +1 @@
VOID:UINT,STRING

File diff suppressed because it is too large Load Diff

View File

@ -20,6 +20,7 @@
* Boston, MA 02111-1307, USA. * Boston, MA 02111-1307, USA.
* *
* @todo We talk about URIs, but they are actually file paths not URIs * @todo We talk about URIs, but they are actually file paths not URIs
* @todo Un-glibify?
*/ */
#ifndef _LIBNOTIFY_NOTIFY_H_ #ifndef _LIBNOTIFY_NOTIFY_H_
@ -28,22 +29,8 @@
#include <glib.h> #include <glib.h>
#include <time.h> #include <time.h>
/** #include "notifycommon.h"
* Notification urgency levels. #include "notifynotification.h"
*/
typedef enum
{
NOTIFY_URGENCY_LOW, /**< Low urgency. */
NOTIFY_URGENCY_NORMAL, /**< Normal urgency. */
NOTIFY_URGENCY_CRITICAL, /**< Critical urgency. */
} NotifyUrgency;
typedef struct _NotifyHandle NotifyHandle;
typedef struct _NotifyIcon NotifyIcon;
typedef struct _NotifyHints NotifyHints;
typedef void (*NotifyCallback)(NotifyHandle *, guint32, gpointer);
/**************************************************************************/ /**************************************************************************/
/** @name libnotify Base API */ /** @name libnotify Base API */
@ -60,18 +47,6 @@ typedef void (*NotifyCallback)(NotifyHandle *, guint32, gpointer);
*/ */
gboolean notify_init(const char *app_name); gboolean notify_init(const char *app_name);
/**
* Initializes the notifications library and sets it up with the
* glib mainloop.
*
* @param app_name The application name.
* @param context The mainloop context, or NULL for the default.
*
* @return TRUE if the library initialized properly and a connection to a
* notification server was made.
*/
gboolean notify_glib_init(const char *app_name, GMainContext *context);
/** /**
* Uninitializes the notifications library. * Uninitializes the notifications library.
* *
@ -86,248 +61,8 @@ void notify_uninit(void);
*/ */
gboolean notify_is_initted(void); gboolean notify_is_initted(void);
/** const gchar *_notify_get_app_name(void);
* Sets up libnotify with the glib mainloop.
*
* This is usually best done by simply calling notify_glib_init(). However,
* there's no harm in calling this yourself.
*
* @param context the #GMainContext or NULL for default context
*/
void notify_setup_with_g_main(GMainContext *context);
/**
* Manually closes a notification.
*
* @param handle The notification handle.
*/
void notify_close(NotifyHandle *handle);
/**
* Returns the server information.
*
* The strings returned must be freed.
*
* @param ret_name The returned product name of the server.
* @param ret_vendor The returned vendor.
* @param ret_version The returned specification version supported.
*
* @return TRUE if the call succeeded, or FALSE if there were errors.
*/
gboolean notify_get_server_info(char **ret_name, char **ret_vendor,
char **ret_version);
/**
* Returns the server's capabilities.
*
* The returned list and the strings inside must all be freed.
*
* @return The list of capabilities, or NULL on error.
*/
GList *notify_get_server_caps(void);
/*@}*/ /*@}*/
/**************************************************************************/
/** @name Hints API */
/**************************************************************************/
/*@{*/
/**
* Creates a hints table.
*
* @return A hints table.
*/
NotifyHints *notify_hints_new(void);
/**
* Adds a string value to the hints table.
*
* @param hints The hints table.
* @param key The key.
* @param value The value.
*/
void notify_hints_set_string(NotifyHints *hints, const char *key,
const char *value);
/**
* Adds an integer value to the hints table.
*
* @param hints The hints table.
* @param key The key.
* @param value The value.
*/
void notify_hints_set_int(NotifyHints *hints, const char *key, int value);
/**
* Adds a boolean value to the hints table.
*
* @param hints The hints table.
* @param key The key.
* @param value The value.
*/
void notify_hints_set_bool(NotifyHints *hints, const char *key, gboolean value);
/*@}*/
/**************************************************************************/
/** @name NotifyIcon API */
/**************************************************************************/
/*@{*/
/**
* Creates an empty (invalid) icon. You must add at least one frame,
* otherwise the icon will be rejected. The first add_frame function
* you call determines if this is a raw data or URI based icon.
*
* This function is useful when adding data from a loop.
*
* @return A new invalid icon.
*/
NotifyIcon *notify_icon_new();
/**
* Creates an icon with the specified icon URI as the first frame.
* You can then add more frames by calling notify_icon_add_frame_from_uri.
* Note that you can't mix raw data and file URIs in the same icon.
*
* @param icon_uri The icon URI.
*
* @return The icon.
*/
NotifyIcon *notify_icon_new_from_uri(const char *icon_uri);
/**
* Creates an icon with the specified icon data as the first frame.
* You can then add more frames by calling notify_icon_add_frame_from_data.
* Note that you can't mix raw data and file URIs in the same icon.
*
* @param icon_len The icon data length.
* @param icon_data The icon data.
*
* @return The icon.
*/
NotifyIcon *notify_icon_new_from_data(size_t icon_len,
const guchar *icon_data);
/**
* Adds a frame from raw data (a png file) to the icons animation.
*
* @param icon The icon to add the frame to
* @param icon_len The frame data length
* @param icon_data The frame data
*
* @return TRUE if was successful, FALSE if this icon isn't a raw data
* icon or there was a bad parameter.
*/
gboolean notify_icon_add_frame_from_data(NotifyIcon *icon,
size_t icon_len,
const guchar *icon_data);
/**
* Adds a frame from a URI to the icons animation.
*
* @param icon The icon to add the frame to
* @param icon_uri The URI of the icon file for the frame
*
* @return TRUE if was successful, FALSE if this icon isn't a file URI
* icon or there was a bad parameter.
*/
gboolean notify_icon_add_frame_from_uri(NotifyIcon *icon,
const char *icon_uri);
/**
* Destroys an icon.
*
* @param icon The icon to destroy.
*/
void notify_icon_destroy(NotifyIcon *icon);
/*@}*/
/**************************************************************************/
/** @name Notifications API */
/**************************************************************************/
/*@{*/
/**
* Sends a notification.
*
* A callback has the following prototype:
*
* @code
* void callback(NotifyHandle *handle, guint32 action_id, void *user_data);
* @endcode
*
* @param replaces The ID of the notification to atomically replace
* @param type The optional notification type.
* @param urgency The urgency level.
* @param summary The summary of the notification.
* @param body The optional body.
* @param icon The optional icon.
* @param expires TRUE if the notification should automatically expire,,
* or FALSE to keep it open until manually closed.
* @param timeout The optional timeout to automatically close the
* notification, or 0 for the daemon's default.
* @param hints A hashtable of hints.
* @param user_data User-specified data to send to a callback.
* @param action_count The number of actions.
* @param ... The actions in uint32/string/callback sets.
*
* @return A unique ID for the notification.
*/
NotifyHandle *notify_send_notification(NotifyHandle *replaces,
const char *type,
NotifyUrgency urgency,
const char *summary,
const char *body,
const NotifyIcon *icon,
gboolean expires, time_t timeout,
NotifyHints *hints,
gpointer user_data,
size_t action_count, ...);
/**
* Sends a notification, taking a va_list for the actions.
*
* A callback has the following prototype:
*
* @code
* void callback(NotifyHandle *handle, guint32 action, void *user_data);
* @endcode
*
* @param replaces The handle of the notification to atomically replace
* @param type The optional notification type.
* @param urgency The urgency level.
* @param summary The summary of the notification.
* @param detailed The optional body.
* @param icon The optional icon.
* @param expires TRUE if the notification should automatically expire,
* or FALSE to keep it open until manually closed.
* @param timeout The optional timeout to automatically close the
* notification, or 0 for the daemon's default.
* @param hints A hashtable of hints.
* @param user_data User-specified data to send to a callback.
* @param action_count The number of actions.
* @param actions The actions in string/callback pairs.
*
* @return A unique ID for the notification.
*/
NotifyHandle *notify_send_notification_varg(NotifyHandle *replaces,
const char *type,
NotifyUrgency urgency,
const char *summary,
const char *detailed,
const NotifyIcon *icon,
gboolean expires,
time_t timeout,
NotifyHints *hints,
gpointer user_data,
size_t action_count,
va_list actions);
/*@}*/
#endif /* _LIBNOTIFY_NOTIFY_H_ */ #endif /* _LIBNOTIFY_NOTIFY_H_ */

23
libnotify/notifycommon.h Normal file
View File

@ -0,0 +1,23 @@
#ifndef _LIBNOTIFY_NOTIFY_COMMON_H_
#define _LIBNOTIFY_NOTIFY_COMMON_H_
#include <glib.h>
#define NOTIFY_TIMEOUT_DEFAULT -1
#define NOTIFY_TIMEOUT_NEVER 0
#define NOTIFY_DBUS_NAME "org.freedesktop.Notifications"
#define NOTIFY_DBUS_CORE_INTERFACE "org.freedesktop.Notifications"
#define NOTIFY_DBUS_CORE_OBJECT "/org/freedesktop/Notifications"
/**
* Notification urgency levels.
*/
typedef enum
{
NOTIFY_URGENCY_LOW, /**< Low urgency. */
NOTIFY_URGENCY_NORMAL, /**< Normal urgency. */
NOTIFY_URGENCY_CRITICAL, /**< Critical urgency. */
} NotifyUrgency;
#endif /* _LIBNOTIFY_NOTIFY_H_ */

View File

@ -0,0 +1,934 @@
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with main.c; if not, write to:
* The Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include "config.h"
#include <dbus/dbus.h>
#include <dbus/dbus-glib.h>
#include "notify.h"
#include "notifynotification.h"
#include "notify-marshal.h"
static void notify_notification_class_init (NotifyNotificationClass * klass);
static void notify_notification_init (NotifyNotification * sp);
static void notify_notification_finalize (GObject * object);
static void _close_signal_handler (DBusGProxy *proxy,
guint32 id,
NotifyNotification *notification);
static void _action_signal_handler (DBusGProxy *proxy,
guint32 id,
gchar *action,
NotifyNotification *notification);
struct NotifyNotificationPrivate
{
guint32 id;
gchar *summary;
gchar *message;
/*NULL to use icon data
anything else to have server lookup icon */
gchar *icon_name;
/*-1 = use server default
0 = never timeout
>0 = Number of milliseconds before we timeout
*/
gint timeout;
GSList *actions;
GHashTable *action_map;
GHashTable *hints;
GtkWidget *attached_widget;
gint widget_old_x;
gint widget_old_y;
gpointer user_data;
GDestroyNotify user_data_free_func;
gboolean updates_pending;
DBusGProxy *proxy;
};
typedef enum
{
SIGNAL_TYPE_CLOSED,
LAST_SIGNAL
} NotifyNotificationSignalType;
typedef struct
{
NotifyNotification *object;
} NotifyNotificationSignal;
static guint notify_notification_signals[LAST_SIGNAL] = { 0 };
static GObjectClass *parent_class = NULL;
GType
notify_notification_get_type ()
{
static GType type = 0;
if (type == 0)
{
static const GTypeInfo our_info = {
sizeof (NotifyNotificationClass),
NULL,
NULL,
(GClassInitFunc) notify_notification_class_init,
NULL,
NULL,
sizeof (NotifyNotification),
0,
(GInstanceInitFunc) notify_notification_init,
};
type = g_type_register_static (G_TYPE_OBJECT,
"NotifyNotification", &our_info, 0);
}
return type;
}
static void
notify_notification_class_init (NotifyNotificationClass * klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
object_class->finalize = notify_notification_finalize;
/* Create signals here: */
notify_notification_signals[SIGNAL_TYPE_CLOSED] =
g_signal_new ("closed",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (NotifyNotificationClass, closed),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE,
0);
dbus_g_object_register_marshaller (notify_marshal_VOID__UINT_STRING,
G_TYPE_NONE,
G_TYPE_UINT,
G_TYPE_STRING,
G_TYPE_INVALID);
}
static void
_g_value_free (GValue * value)
{
g_value_unset (value);
g_free (value);
}
static void
notify_notification_init (NotifyNotification * obj)
{
obj->priv = g_new0 (NotifyNotificationPrivate, 1);
obj->priv->id = 0;
obj->priv->summary = NULL;
obj->priv->message = NULL;
obj->priv->icon_name = NULL;
obj->priv->timeout = NOTIFY_TIMEOUT_DEFAULT;
obj->priv->actions = NULL;
obj->priv->hints = g_hash_table_new_full (g_str_hash,
g_str_equal,
g_free,
(GDestroyNotify) _g_value_free);
obj->priv->action_map = g_hash_table_new_full (g_str_hash,
g_str_equal,
g_free,
NULL);
obj->priv->attached_widget = NULL;
obj->priv->user_data = NULL;
obj->priv->user_data_free_func = NULL;
obj->priv->updates_pending = FALSE;
obj->priv->widget_old_x = 0;
obj->priv->widget_old_y = 0;
obj->priv->proxy = NULL;
}
static void
notify_notification_finalize (GObject * object)
{
NotifyNotification *obj;
NotifyNotificationPrivate *priv;
obj = NOTIFY_NOTIFICATION (object);
priv = obj->priv;
g_free (priv->summary);
g_free (priv->message);
g_free (priv->icon_name);
if (priv->actions != NULL)
{
g_slist_foreach (priv->actions, (GFunc) g_free, NULL);
g_slist_free (priv->actions);
}
if (priv->action_map != NULL)
g_hash_table_destroy (priv->action_map);
if (priv->hints != NULL)
g_hash_table_destroy (priv->hints);
if (priv->attached_widget != NULL)
gtk_widget_unref (priv->attached_widget);
if (priv->user_data_free_func != NULL)
priv->user_data_free_func (priv->user_data);
dbus_g_proxy_disconnect_signal (priv->proxy, "NotificationClosed",
(GCallback) _close_signal_handler,
object);
dbus_g_proxy_disconnect_signal (priv->proxy, "ActionInvoked",
(GCallback) _action_signal_handler,
object);
g_free (obj->priv);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static gboolean
_notify_notification_update_applet_hints (NotifyNotification * n)
{
NotifyNotificationPrivate *priv;
gboolean update_pending;
update_pending = FALSE;
priv = n->priv;
if (priv->attached_widget != NULL)
{
gint x, y, h, w;
GtkWidget *widget;
GtkRequisition requisition;
widget = priv->attached_widget;
gtk_widget_size_request (widget, &requisition);
w = requisition.width;
h = requisition.height;
gdk_window_get_origin (widget->window, &x, &y);
if (GTK_WIDGET_NO_WINDOW (widget))
{
x += widget->allocation.x;
y += widget->allocation.y;
}
x += widget->allocation.width / 2;
y += widget->allocation.height / 2;
if (x != priv->widget_old_x)
{
notify_notification_set_hint_int32 (n, "x", x);
priv->widget_old_x = x;
update_pending = TRUE;
}
if (y != priv->widget_old_y)
{
notify_notification_set_hint_int32 (n, "y", y);
priv->widget_old_y = y;
update_pending = TRUE;
}
}
return update_pending;
}
#if 0
/* This is left here just incase we revisit autoupdating
One thought would be to check for updates every time the icon
is redrawn but we still have to deal with the race conditions
that could occure between the server and the client so we will
leave this alone for now.
*/
static gboolean
_idle_check_updates (void *user_data)
{
NotifyNotification *n;
NotifyNotificationPrivate *priv;
n = NOTIFY_NOTIFICATION (user_data);
priv = n->priv;
if (priv->is_visible)
{
priv->updates_pending = _notify_notification_update_applet_hints (n);
if (priv->updates_pending)
{
/* Try again if we fail on next idle */
priv->updates_pending = !notify_notification_show (n, NULL);
}
}
else
{
priv->updates_pending = FALSE;
}
n = NOTIFY_NOTIFICATION (user_data);
priv = n->priv;
return TRUE;
}
#endif
GdkFilterReturn
_catch (GdkXEvent * xevent, GdkEvent * event, gpointer data)
{
static int i = 1;
printf ("here, %i\n", i);
i++;
return GDK_FILTER_CONTINUE;
}
NotifyNotification *
notify_notification_new (const gchar * summary,
const gchar * message,
const gchar * icon, GtkWidget * attach)
{
NotifyNotification *obj;
g_assert (summary != NULL);
g_assert (message != NULL);
obj = NOTIFY_NOTIFICATION (g_object_new (NOTIFY_TYPE_NOTIFICATION, NULL));
obj->priv->summary = g_strdup (summary);
obj->priv->message = g_strdup (message);
obj->priv->icon_name = g_strdup (icon);
if (attach != NULL)
{
gtk_widget_ref (attach);
obj->priv->attached_widget = attach;
}
return obj;
}
gboolean
notify_notification_update (NotifyNotification * notification,
const gchar * summary,
const gchar * message, const gchar * icon)
{
NotifyNotificationPrivate *priv;
priv = notification->priv;
g_free (priv->summary);
g_free (priv->message);
g_free (priv->icon_name);
priv->summary = g_strdup (summary);
priv->message = g_strdup (message);
priv->icon_name = g_strdup (icon);
priv->updates_pending = TRUE;
/*TODO: return false on OOM */
return TRUE;
}
void
notify_notification_attach_to_widget (NotifyNotification * notification,
GtkWidget * attach)
{
NotifyNotificationPrivate *priv;
priv = notification->priv;
if (priv->attached_widget != NULL)
gtk_widget_unref (priv->attached_widget);
if (attach != NULL)
priv->attached_widget = gtk_widget_ref (attach);
else
priv->attached_widget = NULL;
}
gboolean
notify_notification_set_user_data (NotifyNotification * notification,
void *user_data, GFreeFunc free_func)
{
NotifyNotificationPrivate *priv;
priv = notification->priv;
if (priv->user_data)
if (priv->user_data_free_func)
priv->user_data_free_func (priv->user_data);
priv->user_data = user_data;
priv->user_data_free_func = priv->user_data;
/* TODO: return FALSE on OOM */
return TRUE;
}
static void
_close_signal_handler (DBusGProxy *proxy,
guint32 id,
NotifyNotification *notification)
{
printf ("Got the NotificationClosed signal (id = %i, notification->id = %i)\n"
, id, notification->priv->id);
if (id == notification->priv->id)
g_signal_emit (notification,
notify_notification_signals[SIGNAL_TYPE_CLOSED],
0);
}
static void
_action_signal_handler (DBusGProxy *proxy,
guint32 id,
gchar *action,
NotifyNotification *notification)
{
g_assert (NOTIFY_IS_NOTIFICATION (notification));
if (id == notification->priv->id)
{
NotifyActionCallback callback;
callback = (NotifyActionCallback) g_hash_table_lookup (notification->priv->action_map,
action);
if (callback == NULL)
g_warning ("Recieved unknown action %s", action);
else
callback (notification, action);
}
}
static gchar **
_gslist_to_string_array (GSList *list)
{
GSList *element;
GArray *a;
gsize len;
gchar **result;
len = g_slist_length (list);
a = g_array_sized_new (TRUE, FALSE, sizeof (gchar *), len);
element = list;
while (element != NULL)
{
g_array_append_val (a, element->data);
element = g_slist_next (element);
}
result = (gchar **)g_array_free (a, FALSE);
return result;
}
static gboolean
_notify_notification_show_internal (NotifyNotification *notification,
GError **error,
gboolean ignore_reply)
{
NotifyNotificationPrivate *priv;
GError *tmp_error;
gchar **action_array;
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
priv = notification->priv;
tmp_error = NULL;
if (priv->proxy == NULL)
{
DBusGConnection *bus;
bus = dbus_g_bus_get (DBUS_BUS_SESSION, &tmp_error);
if (tmp_error != NULL)
{
g_propagate_error (error, tmp_error);
return FALSE;
}
priv->proxy = dbus_g_proxy_new_for_name (bus,
NOTIFY_DBUS_NAME,
NOTIFY_DBUS_CORE_OBJECT,
NOTIFY_DBUS_CORE_INTERFACE);
dbus_g_proxy_add_signal (priv->proxy, "NotificationClosed",
G_TYPE_UINT, G_TYPE_INVALID);
dbus_g_proxy_connect_signal (priv->proxy, "NotificationClosed",
(GCallback) _close_signal_handler,
notification, NULL);
dbus_g_proxy_add_signal (priv->proxy, "ActionInvoked",
G_TYPE_UINT, G_TYPE_STRING, G_TYPE_INVALID);
dbus_g_proxy_connect_signal (priv->proxy, "ActionInvoked",
(GCallback) _action_signal_handler,
notification, NULL);
dbus_g_connection_unref (bus);
}
/*if attached to a widget modify x and y in hints */
_notify_notification_update_applet_hints (notification);
action_array = _gslist_to_string_array (priv->actions);
/*TODO: make this nonblocking */
if (!ignore_reply)
dbus_g_proxy_call (priv->proxy, "Notify", &tmp_error,
G_TYPE_STRING, _notify_get_app_name (),
G_TYPE_STRING,
(priv->icon_name != NULL) ? priv->icon_name : "",
G_TYPE_UINT, priv->id, G_TYPE_STRING, priv->summary,
G_TYPE_STRING, priv->message,
G_TYPE_STRV,
action_array, dbus_g_type_get_map ("GHashTable",
G_TYPE_STRING,
G_TYPE_VALUE),
priv->hints, G_TYPE_INT, priv->timeout, G_TYPE_INVALID,
G_TYPE_UINT, &priv->id, G_TYPE_INVALID);
else
dbus_g_proxy_call_no_reply (priv->proxy, "Notify",
G_TYPE_STRING, _notify_get_app_name (),
G_TYPE_STRING,
(priv->icon_name != NULL) ? priv->icon_name : "",
G_TYPE_UINT, priv->id, G_TYPE_STRING, priv->summary,
G_TYPE_STRING, priv->message,
G_TYPE_STRV,
action_array, dbus_g_type_get_map ("GHashTable",
G_TYPE_STRING,
G_TYPE_VALUE),
priv->hints, G_TYPE_INT, priv->timeout, G_TYPE_INVALID);
/*don't free the elements because they are owned by priv->actions */
g_free (action_array);
if (tmp_error != NULL)
{
g_propagate_error (error, tmp_error);
return FALSE;
}
return TRUE;
}
gboolean
notify_notification_show (NotifyNotification *notification, GError **error)
{
return _notify_notification_show_internal (notification, error, FALSE);
}
gboolean
notify_notification_show_and_forget (NotifyNotification *notification, GError **error)
{
gboolean result;
result = _notify_notification_show_internal (notification, error, TRUE);
g_object_unref (G_OBJECT (notification));
return result;
}
void
notify_notification_set_timeout (NotifyNotification * notification,
gint timeout)
{
notification->priv->timeout = timeout;
}
gboolean
notify_notification_set_category (NotifyNotification * notification,
const char *category)
{
return notify_notification_set_hint_string (notification,
"category", category);
}
gboolean
notify_notification_set_urgency (NotifyNotification * notification,
NotifyUrgency l)
{
return notify_notification_set_hint_byte (notification,
"urgency", (guchar) l);
}
static gboolean
_gvalue_array_append_int (GValueArray * array, gint i)
{
GValue *value;
value = g_new0 (GValue, 1);
if (!value)
return FALSE;
g_value_init (value, G_TYPE_INT);
g_value_set_int (value, i);
g_value_array_append (array, value);
return TRUE;
}
static gboolean
_gvalue_array_append_bool (GValueArray * array, gboolean b)
{
GValue *value;
value = g_new0 (GValue, 1);
if (!value)
return FALSE;
g_value_init (value, G_TYPE_BOOLEAN);
g_value_set_boolean (value, b);
g_value_array_append (array, value);
return TRUE;
}
static gboolean
_gvalue_array_append_byte_array (GValueArray * array,
guchar * bytes, gsize len)
{
GArray *byte_array;
GValue *value;
byte_array = g_array_sized_new (FALSE, FALSE, sizeof (guchar), len);
if (!byte_array)
return FALSE;
byte_array = g_array_append_vals (byte_array, bytes, len);
value = g_new0 (GValue, 1);
if (!value)
{
g_array_free (byte_array, TRUE);
return FALSE;
}
g_value_init (value, dbus_g_type_get_collection ("GArray", G_TYPE_UCHAR));
g_value_set_boxed_take_ownership (value, byte_array);
g_value_array_append (array, value);
return TRUE;
}
gboolean
notify_notification_set_icon_data_from_pixbuf (NotifyNotification *
notification, GdkPixbuf * icon)
{
gint width;
gint height;
gint rowstride;
gboolean alpha;
gint bits_per_sample;
gint n_channels;
guchar *image;
gsize image_len;
gchar *key_dup;
GValueArray *image_struct;
GValue *value;
NotifyNotificationPrivate *priv;
priv = notification->priv;
width = gdk_pixbuf_get_width (icon);
height = gdk_pixbuf_get_height (icon);
rowstride = gdk_pixbuf_get_rowstride (icon);
n_channels = gdk_pixbuf_get_n_channels (icon);
bits_per_sample = gdk_pixbuf_get_bits_per_sample (icon);
alpha = gdk_pixbuf_get_has_alpha (icon);
image_len =
(height - 1) * rowstride +
width * ((n_channels * bits_per_sample + 7) / 8);
image = gdk_pixbuf_get_pixels (icon);
image_struct = g_value_array_new (8);
if (!image_struct)
goto fail;
_gvalue_array_append_int (image_struct, width);
_gvalue_array_append_int (image_struct, height);
_gvalue_array_append_int (image_struct, rowstride);
_gvalue_array_append_bool (image_struct, alpha);
_gvalue_array_append_int (image_struct, bits_per_sample);
_gvalue_array_append_int (image_struct, n_channels);
_gvalue_array_append_byte_array (image_struct, image, image_len);
value = g_new0 (GValue, 1);
if (!value)
goto fail;
g_value_init (value, G_TYPE_VALUE_ARRAY);
g_value_set_boxed (value, image_struct);
key_dup = g_strdup ("icon_data");
if (!key_dup)
goto fail;
g_hash_table_insert (priv->hints, key_dup, value);
return TRUE;
fail:
if (image_struct != NULL)
g_value_array_free (image_struct);
return FALSE;
}
gboolean
notify_notification_set_hint_int32 (NotifyNotification * notification,
const gchar * key, gint value)
{
NotifyNotificationPrivate *priv;
GValue *hint_value;
gchar *key_dup;
priv = notification->priv;
hint_value = g_new0 (GValue, 1);
g_value_init (hint_value, G_TYPE_INT);
g_value_set_int (hint_value, value);
key_dup = g_strdup (key);
g_hash_table_insert (priv->hints, key_dup, hint_value);
/* TODO: return FALSE on OOM */
return TRUE;
}
gboolean
notify_notification_set_hint_double (NotifyNotification * notification,
const gchar * key, gdouble value)
{
NotifyNotificationPrivate *priv;
GValue *hint_value;
gchar *key_dup;
priv = notification->priv;
hint_value = g_new0 (GValue, 1);
g_value_init (hint_value, G_TYPE_FLOAT);
g_value_set_float (hint_value, value);
key_dup = g_strdup (key);
g_hash_table_insert (priv->hints, key_dup, hint_value);
/* TODO: return FALSE on OOM */
return TRUE;
}
gboolean
notify_notification_set_hint_byte (NotifyNotification * notification,
const gchar * key, guchar value)
{
NotifyNotificationPrivate *priv;
GValue *hint_value;
gchar *key_dup;
priv = notification->priv;
hint_value = g_new0 (GValue, 1);
g_value_init (hint_value, G_TYPE_UCHAR);
g_value_set_uchar (hint_value, value);
key_dup = g_strdup (key);
g_hash_table_insert (priv->hints, key_dup, hint_value);
/* TODO: return FALSE on OOM */
return TRUE;
}
gboolean
notify_notification_set_hint_byte_array (NotifyNotification * notification,
const gchar * key,
const guchar * value, gsize len)
{
NotifyNotificationPrivate *priv;
GValue *hint_value;
gchar *key_dup;
GArray *byte_array;
priv = notification->priv;
byte_array = g_array_sized_new (FALSE, FALSE, sizeof (guchar), len);
byte_array = g_array_append_vals (byte_array, value, len);
hint_value = g_new0 (GValue, 1);
g_value_init (hint_value,
dbus_g_type_get_collection ("GArray", G_TYPE_UCHAR));
g_value_set_boxed_take_ownership (hint_value, byte_array);
key_dup = g_strdup (key);
g_hash_table_insert (priv->hints, key_dup, hint_value);
/* TODO: return FALSE on OOM */
return TRUE;
}
gboolean
notify_notification_set_hint_string (NotifyNotification * notification,
const gchar * key, const gchar * value)
{
NotifyNotificationPrivate *priv;
GValue *hint_value;
gchar *key_dup;
priv = notification->priv;
hint_value = g_new0 (GValue, 1);
g_value_init (hint_value, G_TYPE_STRING);
g_value_set_string (hint_value, value);
key_dup = g_strdup (key);
g_hash_table_insert (priv->hints, key_dup, hint_value);
/* TODO: return FALSE on OOM */
return TRUE;
}
static gboolean
_remove_all (void)
{
return TRUE;
}
void
notify_notification_clear_hints (NotifyNotification *notification)
{
g_hash_table_foreach_remove (notification->priv->hints,
(GHRFunc) _remove_all, NULL);
}
void
notify_notification_clear_actions (NotifyNotification *notification)
{
g_hash_table_foreach_remove (notification->priv->action_map, (GHRFunc) _remove_all, NULL);
if (notification->priv->actions != NULL)
{
g_slist_foreach (notification->priv->actions, (GFunc) g_free, NULL);
g_slist_free (notification->priv->actions);
}
notification->priv->actions = NULL;
}
gboolean
notify_notification_add_action (NotifyNotification *notification,
const char *action,
const char *label,
NotifyActionCallback callback)
{
NotifyNotificationPrivate *priv;
priv = notification->priv;
priv->actions = g_slist_append (priv->actions, g_strdup (action));
priv->actions = g_slist_append (priv->actions, g_strdup (label));
g_hash_table_insert (priv->action_map, g_strdup (action), callback);
return FALSE;
}
gboolean
notify_notification_close (NotifyNotification * notification, GError ** error)
{
NotifyNotificationPrivate *priv;
GError *tmp_error;
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
priv = notification->priv;
tmp_error = NULL;
if (priv->proxy == NULL)
{
DBusGConnection *bus;
bus = dbus_g_bus_get (DBUS_BUS_SESSION, &tmp_error);
if (tmp_error != NULL)
{
g_propagate_error (error, tmp_error);
return FALSE;
}
priv->proxy = dbus_g_proxy_new_for_name (bus,
NOTIFY_DBUS_NAME,
NOTIFY_DBUS_CORE_OBJECT,
NOTIFY_DBUS_CORE_INTERFACE);
dbus_g_connection_unref (bus);
}
dbus_g_proxy_call (priv->proxy, "CloseNotification", &tmp_error,
G_TYPE_UINT, priv->id, G_TYPE_INVALID, G_TYPE_INVALID);
if (tmp_error != NULL)
{
g_propagate_error (error, tmp_error);
return FALSE;
}
return TRUE;
}

View File

@ -0,0 +1,125 @@
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with main.c; if not, write to:
* The Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef NOTIFY_NOTIFICATION_H
#define NOTIFY_NOTIFICATION_H
#include "config.h"
#include <glib.h>
#include <glib-object.h>
#include <gtk/gtk.h>
#include "notifycommon.h"
G_BEGIN_DECLS
#define NOTIFY_TYPE_NOTIFICATION (notify_notification_get_type ())
#define NOTIFY_NOTIFICATION(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), NOTIFY_TYPE_NOTIFICATION, NotifyNotification))
#define NOTIFY_NOTIFICATION_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), NOTIFY_TYPE_NOTIFICATION, NotifyNotificationClass))
#define NOTIFY_IS_NOTIFICATION(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), NOTIFY_TYPE_NOTIFICATION))
#define NOTIFY_IS_NOTIFICATION_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), NOTIFY_TYPE_NOTIFICATION))
#define NOTIFY_NOTIFICATION_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), NOTIFY_TYPE_NOTIFICATION, NotifyNotificationClass))
typedef struct NotifyNotificationPrivate NotifyNotificationPrivate;
typedef struct {
GObject parent;
NotifyNotificationPrivate *priv;
} NotifyNotification;
typedef struct {
GObjectClass parent_class;
/* Add Signal Functions Here */
void (*closed) (void);
} NotifyNotificationClass;
typedef void (*NotifyActionCallback )(NotifyNotification *, gchar *);
GType notify_notification_get_type();
NotifyNotification *notify_notification_new (const gchar *summary,
const gchar *message,
const gchar *icon,
GtkWidget *attach);
gboolean notify_notification_update (NotifyNotification *notification,
const gchar *summary,
const gchar *message,
const gchar *icon);
void notify_notification_attach_to_widget (NotifyNotification *notification,
GtkWidget *attach);
gboolean notify_notification_set_user_data (NotifyNotification *notification,
void *user_data,
GFreeFunc free_func);
gboolean notify_notification_show (NotifyNotification *notification,
GError **error);
gboolean notify_notification_show_and_forget (NotifyNotification *notification,
GError **error);
void notify_notification_set_timeout (NotifyNotification *notification,
gint timeout);
gboolean notify_notification_set_category (NotifyNotification *notification,
const char *category);
gboolean notify_notification_set_urgency (NotifyNotification *notification,
NotifyUrgency l);
gboolean notify_notification_set_icon_data_from_pixbuf (NotifyNotification *notification,
GdkPixbuf *icon);
gboolean notify_notification_set_hint_int32 (NotifyNotification *notification,
const gchar *key,
gint value);
gboolean notify_notification_set_hint_double (NotifyNotification *notification,
const gchar *key,
gdouble value);
gboolean notify_notification_set_hint_string (NotifyNotification *notification,
const gchar *key,
const gchar *value);
gboolean notify_notification_set_hint_byte (NotifyNotification *notification,
const gchar *key,
guchar value);
gboolean notify_notification_set_hint_byte_array (
NotifyNotification *notification,
const gchar *key,
const guchar *value,
gsize len);
void notify_notification_clear_hints (NotifyNotification *notification);
gboolean notify_notification_add_action (NotifyNotification *notification,
const char *action,
const char *label,
NotifyActionCallback callback);
void notify_notification_clear_actions (NotifyNotification *notification);
gboolean notify_notification_close (NotifyNotification *notification,
GError **error);
NotifyNotification *notify_notification_ref (NotifyNotification *notification);
void notify_notification_unref (NotifyNotification *notification);
#endif /* NOTIFY_NOTIFICATION_H */

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8" ?>
<node name="/org/freedesktop/Notification">
<interface name="org.freedesktop.NotificationListener">
</interface>
</node>

View File

@ -1,9 +1,7 @@
if HAVE_GDK if HAVE_GDK
gdk_tests = \ gdk_tests = \
test-animation \
test-xy-stress test-xy-stress
test_animation_SOURCES = test-animation.c
test_xy_stress_SOURCES = test-xy-stress.c test_xy_stress_SOURCES = test-xy-stress.c
else else
gdk_tests = gdk_tests =
@ -11,6 +9,7 @@ endif
noinst_PROGRAMS = \ noinst_PROGRAMS = \
test-replace \ test-replace \
test-replace-widget \
test-default-action \ test-default-action \
test-multi-actions \ test-multi-actions \
test-image \ test-image \
@ -27,6 +26,8 @@ common_ldflags = \
test_replace_SOURCES = test-replace.c test_replace_SOURCES = test-replace.c
test_replace_LDADD = $(common_ldflags) test_replace_LDADD = $(common_ldflags)
test_replace_widget_SOURCES = test-replace-widget.c
test_replace_widget_LDADD = $(common_ldflags)
test_default_action_SOURCES = test-default-action.c test_default_action_SOURCES = test-default-action.c
test_default_action_LDADD = $(common_ldflags) test_default_action_LDADD = $(common_ldflags)
test_multi_actions_SOURCES = test-multi-actions.c test_multi_actions_SOURCES = test-multi-actions.c
@ -38,8 +39,6 @@ test_basic_LDADD = $(common_ldflags)
test_error_SOURCES = test-error.c test_error_SOURCES = test-error.c
test_error_LDADD = $(common_ldflags) test_error_LDADD = $(common_ldflags)
test_animation_LDADD = $(common_ldflags)
test_markup_SOURCES = test-markup.c test_markup_SOURCES = test-markup.c
test_markup_LDADD = $(common_ldflags) test_markup_LDADD = $(common_ldflags)
@ -48,6 +47,6 @@ test_xy_LDADD = $(common_ldflags)
test_xy_stress_LDADD = $(common_ldflags) test_xy_stress_LDADD = $(common_ldflags)
INCLUDES = $(PACKAGE_CFLAGS) $(GDK_CFLAGS) -I$(top_srcdir) INCLUDES = $(PACKAGE_CFLAGS) \
$(GDK_CFLAGS) \
EXTRA_DIST = applet-critical.png -I$(top_srcdir)

View File

@ -1,106 +0,0 @@
/*
* @file tests/test-animation.c Unit test: animated images
*
* @Copyright (C) 2004 Mike Hearn <mike@navi.cx>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include <libnotify/notify.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <math.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
/// WRITE ME! ///
const int frames = 10;
// returns array of pixbufs for a pulsing animation
GdkPixbuf **generate_animation()
{
int i;
GdkPixbuf *file = gdk_pixbuf_new_from_file("applet-critical.png", NULL);
double alpha = 1.0;
GdkPixbuf **array = g_malloc(sizeof(GdkPixbuf *) * frames);
for (i = 0; i < frames; i++)
{
GdkPixbuf *buf = gdk_pixbuf_copy(file);
alpha = sin(M_PI + ((M_PI / frames) * i)) + 1.0;
gdk_pixbuf_composite(file, buf, 0, 0,
gdk_pixbuf_get_width(buf),
gdk_pixbuf_get_height(buf),
0, 0, 1.0, 1.0, GDK_INTERP_NEAREST,
alpha);
array[i] = buf;
}
return array;
}
int main()
{
int i;
GdkPixbuf **buffers;
NotifyIcon *icon;
notify_init("Animations");
g_type_init();
buffers = generate_animation();
icon = notify_icon_new();
for (i = 0; i < frames; i++)
{
gchar *pngdata;
gsize size;
GError *error = NULL;
gdk_pixbuf_save_to_buffer(buffers[i], &pngdata, &size, "png",
&error, NULL);
g_assert(error == NULL);
notify_icon_add_frame_from_data(icon, size, (guchar *)pngdata);
}
NotifyHandle *n = notify_send_notification(NULL, // replaces nothing
NULL,
NOTIFY_URGENCY_NORMAL,
"Summary", "Content",
icon,
TRUE, 0,
NULL, // no hints
NULL, // no user data
0); // no actions
if (!n) {
fprintf(stderr, "failed to send notification\n");
return 1;
}
return 0;
}

View File

@ -24,19 +24,16 @@
#include <unistd.h> #include <unistd.h>
int main() { int main() {
NotifyNotification *n;
notify_init("Basics"); notify_init("Basics");
NotifyHandle *n = notify_send_notification(NULL, // replaces nothing n = notify_notification_new ("Summary",
NULL, "Content that is very long 8374983278r32j4 rhjjfh dw8f 43jhf 8ds7 ur2389f jdbjkt h8924yf jkdbjkt 892hjfiHER98HEJIF BDSJHF hjdhF JKLH 890YRHEJHFU 89HRJKSHdd dddd ddddd dddd ddddd dddd ddddd dddd dddd ddd ddd dddd Fdd d ddddd dddddddd ddddddddhjkewdkjsjfjk sdhkjf hdkj dadasdadsa adsd asd sd saasd fadskfkhsjf hsdkhfkshfjkhsd kjfhsjdkhfj ksdhfkjshkjfsd sadhfjkhaskd jfhsdajkfhkjs dhfkjsdhfkjs adhjkfhasdkj fhdsakjhfjk asdhkjkfhd akfjshjfsk afhjkasdhf jkhsdaj hf kjsdfahkfh sakjhfksdah kfdashkjf ksdahfj shdjdh",
NOTIFY_URGENCY_NORMAL, NULL, NULL);
"Summary", "Content", notify_notification_set_timeout (n, 3000); //3 seconds
NULL, // no icon
TRUE, 0,
NULL, // no hints
NULL, // no user data
0); // no actions
if (!n) { if (!notify_notification_show_and_forget (n, NULL)) {
fprintf(stderr, "failed to send notification\n"); fprintf(stderr, "failed to send notification\n");
return 1; return 1;
} }

View File

@ -24,8 +24,9 @@
#include <unistd.h> #include <unistd.h>
#include <stdlib.h> #include <stdlib.h>
#include <assert.h> #include <assert.h>
#include <string.h>
#define DBUS_API_SUBJECT_TO_CHANGE 1 #define DBUS_API_SUBJECT_TO_CHANGE
#include <glib.h> #include <glib.h>
#include <dbus/dbus.h> #include <dbus/dbus.h>
@ -33,13 +34,13 @@
#include <dbus/dbus-glib-lowlevel.h> #include <dbus/dbus-glib-lowlevel.h>
static GMainLoop *loop; static GMainLoop *loop;
static NotifyHandle *n;
static void callback(NotifyHandle *handle, guint32 uid, void *user_data) static void callback(NotifyNotification *n, const char *action, void *user_data)
{ {
assert( uid == 0 ); assert (action != NULL);
assert (strcmp ("default", action) == 0);
notify_close(n); notify_notification_close (n, NULL);
g_main_loop_quit(loop); g_main_loop_quit(loop);
} }
@ -47,23 +48,23 @@ static void callback(NotifyHandle *handle, guint32 uid, void *user_data)
int int
main() main()
{ {
NotifyNotification *n;
DBusConnection *conn;
if (!notify_init("Default Action Test")) exit(1);
conn = dbus_bus_get(DBUS_BUS_SESSION, NULL);
loop = g_main_loop_new(NULL, FALSE); loop = g_main_loop_new(NULL, FALSE);
if (!notify_glib_init("Default Action Test", NULL)) dbus_connection_setup_with_g_main(conn, NULL);
exit(1);
n = notify_send_notification(NULL, // replaces nothing n = notify_notification_new ("Matt is online", "", NULL, NULL);
"presence.online", notify_notification_set_timeout (n, NOTIFY_TIMEOUT_NEVER);
NOTIFY_URGENCY_NORMAL, notify_notification_add_action (n, "default", "Do Default Action",
"Matt is online", NULL, (NotifyActionCallback)callback);
NULL, // no icon notify_notification_set_category (n, "presence.online");
FALSE, 0, // does not expire
NULL, // no hints
NULL, // no user data
1,
0, "default", callback); // 1 action
if (!n) { if (!notify_notification_show (n, NULL)) {
fprintf(stderr, "failed to send notification\n"); fprintf(stderr, "failed to send notification\n");
return 1; return 1;
} }

View File

@ -24,26 +24,25 @@
#include <unistd.h> #include <unistd.h>
int main() { int main() {
NotifyNotification *n;
g_type_init ();
notify_init("Error Handling"); notify_init("Error Handling");
NotifyIcon *icon = notify_icon_new("/no-such"); n = notify_notification_new ("Summary",
"Content",
NULL, NULL);
notify_notification_set_timeout (n, 3000); //3 seconds
NotifyHandle *n = notify_send_notification(NULL, // replaces nothing /* TODO: Create an error condition */
NULL,
NOTIFY_URGENCY_NORMAL,
"Summary", "Content",
icon, // no icon
TRUE, 0,
NULL, // no hints
NULL, // no user data
0);
notify_icon_destroy(icon);
if (n) { if (!notify_notification_show (n, NULL)) {
fprintf(stderr, "failed to get an error ??\n"); fprintf(stderr, "failed to send notification\n");
return 1; return 1;
} }
return 0; return 0;
} }

View File

@ -1,12 +1,12 @@
/* /*
* @file tests/test-image.c Unit test: images * @file tests/test-image.c Unit test: images
* *
* @Copyright (C) 2004 Mike Hearn <mike@navi.cx> * @Copyright(C) 2004 Mike Hearn <mike@navi.cx>
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either * License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version. * version 2.1 of the License, or(at your option) any later version.
* *
* This library is distributed in the hope that it will be useful, * This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
@ -31,91 +31,89 @@
#include <unistd.h> #include <unistd.h>
#include <fcntl.h> #include <fcntl.h>
#define DBUS_API_SUBJECT_TO_CHANGE 1 #define DBUS_API_SUBJECT_TO_CHANGE
#include <glib.h> #include <glib.h>
#include <gtk/gtk.h>
#include <dbus/dbus.h> #include <dbus/dbus.h>
#include <dbus/dbus-glib.h> #include <dbus/dbus-glib.h>
#include <dbus/dbus-glib-lowlevel.h> #include <dbus/dbus-glib-lowlevel.h>
GMainLoop *loop; GMainLoop *loop;
NotifyHandle *n; NotifyNotification *n;
static void send(char *i, size_t rawlen, char *s, char *b)
{
NotifyIcon *icon;
if (rawlen > 0)
icon = notify_icon_new_from_data(rawlen, i);
else
icon = notify_icon_new_from_uri(i);
n = notify_send_notification(NULL, // replaces nothing
NULL,
NOTIFY_URGENCY_NORMAL,
s, b,
icon,
TRUE, 0,
NULL, // no hints
NULL, // no user data
0);
if (!n) {
fprintf(stderr, "failed to send notification\n");
exit(1);
}
notify_icon_destroy(icon);
}
int int
main(int argc, char **argv) main(int argc, char *argv[])
{ {
loop = g_main_loop_new(NULL, FALSE); char file[PATH_MAX];
int size;
char *uri;
GdkPixbuf *icon;
GtkWidget *helper;
if (!notify_glib_init("Images Test", NULL)) gtk_init(&argc, &argv);
if (!notify_init("Images Test"))
exit(1); exit(1);
/* n = notify_notification_new("Icon Test", "Testing stock icon",
* These images exist on fedora core 2 workstation profile. "stock_help", NULL);
* Might not on yours
*/
send("gnome-starthere", notify_notification_set_hint_int32(n, "x", 300);
0, notify_notification_set_hint_int32(n, "y", 24);
"Welcome to Linux!", notify_notification_set_timeout(n, NOTIFY_TIMEOUT_NEVER);
"This is your first login. To begin exploring the system, click on 'Start Here', 'Computer' or 'Applications'");
char file[1024]; if (!notify_notification_show(n, NULL))
readlink("/proc/self/exe", file, sizeof(file));
*strrchr(file, '/') = '\0';
strcat(file, "/../applet-critical.png");
printf("sending %s\n", file);
send(file,
0,
"Alert!",
"Warning!");
struct stat buf;
if (stat(file, &buf) == -1)
{ {
fprintf(stderr, "could not stat %s: %s", file, strerror(errno)); fprintf(stderr, "failed to send notification\n");
exit(1); return 1;
} }
int fd = open(file, O_RDONLY); g_usleep(5000000); // 5 seconds
void *pngbase = mmap(NULL, buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); size = readlink("/proc/self/cwd", file, PATH_MAX - 1);
file[size] = '\0';
uri = g_strdup_printf("file://%s/%s", file, "applet-critical.png");
close(fd); printf("sending %s\n", uri);
send(pngbase, notify_notification_update(n, "Alert!", "Testing URI icons", uri);
buf.st_size,
"Raw image test", if (!notify_notification_show(n, NULL))
"This is an image marshalling test"); {
fprintf(stderr, "failed to send notification\n");
return 1;
}
g_usleep(5000000); // 5 seconds
notify_notification_update(n, "Raw image test",
"Testing sending raw pixbufs", NULL);
/*
* This is just a hack to get a stock icon's pixbuf in a realworld app
* if you were sending bitmapped data you would know the file location
* and open it up with a method that could generate a bmp for you
*/
helper = gtk_button_new();
icon = gtk_widget_render_icon(helper,
GTK_STOCK_DIALOG_QUESTION,
GTK_ICON_SIZE_DIALOG,
"");
notify_notification_set_icon_data_from_pixbuf(n, icon);
if (!notify_notification_show(n, NULL))
{
fprintf(stderr, "failed to send notification\n");
return 1;
}
gtk_widget_destroy(helper);
g_object_unref(G_OBJECT(icon));
g_usleep(5000000); // 5 seconds
return 0; return 0;
} }

View File

@ -24,22 +24,17 @@
#include <unistd.h> #include <unistd.h>
int main() { int main() {
NotifyNotification *n;
notify_init("Markup"); notify_init("Markup");
NotifyHandle *n = notify_send_notification( n = notify_notification_new ("Summary",
NULL, // replaces nothing "Some <b>bold</b>, <u>underlined</u>, <i>italic</i>, "
NULL, "<a href='http://www.google.com'>linked</a> text",
NOTIFY_URGENCY_NORMAL, NULL, NULL);
"Summary", notify_notification_set_timeout (n, 3000); //3 seconds
"Some <b>bold</b>, <u>underlined</u>, <i>italic</i>, "
"<a href='http://www.google.com'>linked</a> text",
NULL, // no icon
TRUE, 0,
NULL, // no hints
NULL, // no user data
0); // no actions
if (!n) { if (!notify_notification_show (n, NULL)) {
fprintf(stderr, "failed to send notification\n"); fprintf(stderr, "failed to send notification\n");
return 1; return 1;
} }

View File

@ -1,12 +1,12 @@
/* /*
* @file tests/test-multi-actions.c Unit test: multiple actions * @file tests/test-multi-actions.c Unit test: multiple actions
* *
* @Copyright (C) 2004 Mike Hearn <mike@navi.cx> * @Copyright(C) 2004 Mike Hearn <mike@navi.cx>
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either * License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version. * version 2.1 of the License, or(at your option) any later version.
* *
* This library is distributed in the hope that it will be useful, * This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
@ -23,62 +23,86 @@
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
#include <stdlib.h> #include <stdlib.h>
#include <assert.h> #include <string.h>
#define DBUS_API_SUBJECT_TO_CHANGE 1 #define DBUS_API_SUBJECT_TO_CHANGE
#include <glib.h> #include <glib.h>
#include <dbus/dbus.h> #include <dbus/dbus.h>
#include <dbus/dbus-glib.h> #include <dbus/dbus-glib.h>
#include <dbus/dbus-glib-lowlevel.h> #include <dbus/dbus-glib-lowlevel.h>
GMainLoop *loop; static GMainLoop *loop;
NotifyHandle *n;
static void callback(NotifyHandle *handle, guint32 uid, void *user_data) static void
help_callback(NotifyNotification *n, const char *action)
{ {
char *s = NULL; g_assert(action != NULL);
g_assert(strcmp(action, "help") == 0);
assert( uid >= 0 && uid <= 2 ); printf("You clicked Help\n");
switch (uid) notify_notification_close(n, NULL);
{
case 0: s = "the notification"; break;
case 1: s = "Empty Trash"; break;
case 2: s = "Help Me"; break;
}
printf("You clicked %s\n", s);
notify_close(n);
g_main_loop_quit(loop); g_main_loop_quit(loop);
} }
static void
ignore_callback(NotifyNotification *n, const char *action)
{
g_assert(action != NULL);
g_assert(strcmp(action, "ignore") == 0);
printf("You clicked Ignore\n");
notify_notification_close(n, NULL);
g_main_loop_quit(loop);
}
static void
empty_callback(NotifyNotification *n, const char *action)
{
g_assert(action != NULL);
g_assert(strcmp(action, "empty") == 0);
printf("You clicked Empty Trash\n");
notify_notification_close(n, NULL);
g_main_loop_quit(loop);
}
int int
main(int argc, char **argv) main(int argc, char **argv)
{ {
loop = g_main_loop_new(NULL, FALSE); NotifyNotification *n;
DBusConnection *conn;
if (!notify_glib_init("Multi Action Test", NULL)) if (!notify_init("Multi Action Test"))
exit(1); exit(1);
n = notify_send_notification(NULL, // replaces nothing conn = dbus_bus_get(DBUS_BUS_SESSION, NULL);
"device", loop = g_main_loop_new(NULL, FALSE);
NOTIFY_URGENCY_NORMAL,
"Low disk space",
"You can free up some disk space by "
"emptying the trash can.",
NULL, // no icon
FALSE, 0, // does not expire
NULL, // no hints
NULL, // no user data
3, // 3 actions
0, "default", callback,
1, "Empty Trash", callback,
2, "Help Me", callback );
if (!n) { dbus_connection_setup_with_g_main(conn, NULL);
n = notify_notification_new("Low disk space",
"You can free up some disk space by "
"emptying the trash can.",
NULL, NULL);
notify_notification_set_timeout(n, NOTIFY_TIMEOUT_NEVER);
notify_notification_add_action(n, "help", "Help",
(NotifyActionCallback)help_callback);
notify_notification_add_action(n, "ignore", "Ignore",
(NotifyActionCallback)ignore_callback);
notify_notification_add_action(n, "empty", "Empty Trash",
(NotifyActionCallback)empty_callback);
notify_notification_set_category(n, "device");
if (!notify_notification_show(n, NULL))
{
fprintf(stderr, "failed to send notification\n"); fprintf(stderr, "failed to send notification\n");
return 1; return 1;
} }

View File

@ -0,0 +1,64 @@
#include <libnotify/notify.h>
#include <stdio.h>
#include <unistd.h>
#include <glib.h>
#include <gtk/gtk.h>
static int count = 0;
static void
on_exposed(GtkWidget *widget, GdkEventExpose *ev, void *user_data)
{
NotifyNotification *n = NOTIFY_NOTIFICATION(user_data);
g_signal_handlers_disconnect_by_func(widget, on_exposed, user_data);
notify_notification_show(n, NULL);
}
static void
on_clicked(GtkButton *button, void *user_data)
{
gchar *buf;
NotifyNotification *n = NOTIFY_NOTIFICATION(user_data);
count++;
buf = g_strdup_printf("You clicked the button %i times", count);
notify_notification_update(n, "Widget Attachment Test", buf, NULL);
g_free(buf);
notify_notification_show(n, NULL);
}
int
main(int argc, char *argv[])
{
NotifyNotification *n;
GtkWidget *window;
GtkWidget *button;
gtk_init(&argc, &argv);
notify_init("Replace Test");
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
button = gtk_button_new_with_label("click here to change notification");
gtk_container_add(GTK_CONTAINER(window), button);
gtk_widget_show_all(window);
n = notify_notification_new("Widget Attachment Test",
"Button has not been clicked yet",
NULL, //no icon
button); //attach to button
notify_notification_set_timeout(n, 0); //don't timeout
g_signal_connect(G_OBJECT(button), "clicked",
G_CALLBACK(on_clicked), n);
g_signal_connect_after(G_OBJECT(button), "expose-event",
G_CALLBACK(on_exposed), n);
gtk_main();
return 0;
}

View File

@ -1,52 +1,40 @@
/*
* @file tests/test-default-action.c Unit test: atomic replacements
*
* @Copyright (C) 2004 Mike Hearn <mike@navi.cx>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include <libnotify/notify.h> #include <libnotify/notify.h>
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
#include <glib.h>
int main() { int main() {
notify_init("Replace Test"); NotifyNotification *n;
GError *error;
error = NULL;
NotifyHandle *n = notify_send_notification(NULL, // replaces nothing g_type_init ();
NULL,
NOTIFY_URGENCY_NORMAL,
"Summary", "Content",
NULL, // no icon
FALSE, 0, // does not expire
NULL, // no hints
NULL, // no user data
0); // no actions
if (!n) { notify_init("Replace Test");
fprintf(stderr, "failed to send notification\n");
return 1; n = notify_notification_new ("Summary", "First message",
} NULL, //no icon
NULL); //don't attach to widget
notify_notification_set_timeout (n, 0); //don't timeout
if (!notify_notification_show (n, &error)) {
fprintf(stderr, "failed to send notification: %s\n", error->message);
g_error_free (error);
return 1;
}
sleep(5); sleep(3);
notify_send_notification(n, NULL, NOTIFY_URGENCY_NORMAL, notify_notification_update (n, "Second Summary",
"Second Summary", "Second Content", "First mesage was replaced", NULL);
NULL, TRUE, 5, NULL, NULL, 0);
return 0; if (!notify_notification_show (n, &error)) {
fprintf(stderr, "failed to send notification: %s\n", error->message);
g_error_free (error);
return 1;
}
return 0;
} }

View File

@ -1,12 +1,12 @@
/* /*
* @file tests/test-xy.c Unit test: X, Y hints * @file tests/test-xy.c Unit test: X, Y hints
* *
* @Copyright (C) 2005 Christian Hammond <chipx86@chipx86.com> * @Copyright(C) 2005 Christian Hammond <chipx86@chipx86.com>
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either * License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version. * version 2.1 of the License, or(at your option) any later version.
* *
* This library is distributed in the hope that it will be useful, * This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
@ -24,62 +24,77 @@
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
#include <dbus/dbus.h>
#include <dbus/dbus-glib.h>
#include <dbus/dbus-glib-lowlevel.h>
static void
_handle_closed(GObject *obj)
{
g_message("closing");
g_object_unref(obj);
}
static void static void
emit_notification(int x, int y) emit_notification(int x, int y)
{ {
NotifyHints *hints; char *buffer;
static char buffer[BUFSIZ]; NotifyNotification *n;
hints = notify_hints_new(); buffer = g_strdup_printf("This notification should point to %d, %d.",
notify_hints_set_int(hints, "x", x); x, y);
notify_hints_set_int(hints, "y", y);
g_snprintf(buffer, sizeof(buffer), n = notify_notification_new("X, Y Test", buffer, NULL, NULL);
"This notification should point to %d, %d.", x, y); g_free(buffer);
NotifyHandle *n = notify_send_notification( notify_notification_set_hint_int32(n, "x", x);
NULL, // replaces nothing notify_notification_set_hint_int32(n, "y", y);
NULL,
NOTIFY_URGENCY_NORMAL,
"X, Y Test",
buffer,
NULL, // no icon
TRUE, 0,
hints,
NULL, // no user data
0); // no actions
if (!n) { g_signal_connect(G_OBJECT(n), "closed",
G_CALLBACK(_handle_closed), NULL);
if (!notify_notification_show(n, NULL))
fprintf(stderr, "failed to send notification\n"); fprintf(stderr, "failed to send notification\n");
}
} }
int static gboolean
main(int argc, char **argv) _popup_random_bubble(gpointer unused)
{ {
GdkDisplay *display; GdkDisplay *display;
GdkScreen *screen; GdkScreen *screen;
int screen_x2, screen_y2; int screen_x2, screen_y2;
int x, y;
gdk_init(&argc, &argv);
notify_init("XY");
display = gdk_display_get_default(); display = gdk_display_get_default();
screen = gdk_display_get_default_screen(display); screen = gdk_display_get_default_screen(display);
screen_x2 = gdk_screen_get_width(screen) - 1; screen_x2 = gdk_screen_get_width(screen) - 1;
screen_y2 = gdk_screen_get_height(screen) - 1; screen_y2 = gdk_screen_get_height(screen) - 1;
emit_notification(0, 0); x = g_random_int_range(0, screen_x2);
emit_notification(screen_x2, 0); y = g_random_int_range(0, screen_y2);
emit_notification(5, 150); emit_notification(x, y);
emit_notification(screen_x2 - 5, 150);
emit_notification(0, screen_y2 / 2); return TRUE;
emit_notification(screen_x2, screen_y2 / 2); }
emit_notification(5, screen_y2 - 150);
emit_notification(screen_x2 - 5, screen_y2 - 150); int
emit_notification(0, screen_y2); main(int argc, char **argv)
emit_notification(screen_x2, screen_y2); {
GMainLoop *loop;
DBusConnection *conn;
gdk_init(&argc, &argv);
notify_init("XY");
conn = dbus_bus_get(DBUS_BUS_SESSION, NULL);
dbus_connection_setup_with_g_main(conn, NULL);
g_timeout_add(1000, _popup_random_bubble, NULL);
loop = g_main_loop_new(NULL, FALSE);
g_main_loop_run(loop);
return 0; return 0;
} }

View File

@ -24,27 +24,18 @@
#include <unistd.h> #include <unistd.h>
int main() { int main() {
NotifyHints *hints; NotifyNotification *n;
notify_init("XY"); notify_init("XY");
hints = notify_hints_new(); n = notify_notification_new ("X, Y Test",
notify_hints_set_int(hints, "x", 150); "This notification should point to 150, 10",
notify_hints_set_int(hints, "y", 10); NULL, NULL);
NotifyHandle *n = notify_send_notification( notify_notification_set_hint_int32 (n, "x", 30);
NULL, // replaces nothing notify_notification_set_hint_int32 (n, "y", 10);
NULL,
NOTIFY_URGENCY_NORMAL,
"X, Y Test",
"This notification should point to 150, 10.",
NULL, // no icon
TRUE, 0,
hints,
NULL, // no user data
0); // no actions
if (!n) { if (!notify_notification_show (n, NULL)) {
fprintf(stderr, "failed to send notification\n"); fprintf(stderr, "failed to send notification\n");
return 1; return 1;
} }

View File

@ -8,4 +8,5 @@ common_ldflags = \
notify_send_SOURCES = notify-send.c notify_send_SOURCES = notify-send.c
notify_send_LDADD = $(common_ldflags) notify_send_LDADD = $(common_ldflags)
INCLUDES = $(PACKAGE_CFLAGS) -I$(top_srcdir) INCLUDES = $(PACKAGE_CFLAGS) \
-I$(top_srcdir)

View File

@ -24,6 +24,7 @@
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include <popt.h> #include <popt.h>
#include <glib.h>
#define N_(x) (x) #define N_(x) (x)
@ -34,14 +35,15 @@ main(int argc, const char **argv)
const gchar *body = NULL; const gchar *body = NULL;
const gchar *type = NULL; const gchar *type = NULL;
char *urgency_str = NULL; char *urgency_str = NULL;
gchar *icons = NULL;
gchar *icon_str = NULL; gchar *icon_str = NULL;
NotifyIcon *icon = NULL; gchar *icons = NULL;
NotifyUrgency urgency = NOTIFY_URGENCY_NORMAL; NotifyUrgency urgency = NOTIFY_URGENCY_NORMAL;
time_t expire_timeout = 0; long expire_timeout = NOTIFY_TIMEOUT_DEFAULT;
char ch; char ch;
poptContext opt_ctx; poptContext opt_ctx;
const char **args; const char **args;
NotifyNotification *notify;
struct poptOption options[] = struct poptOption options[] =
{ {
{ "urgency", 'u', POPT_ARG_STRING | POPT_ARGFLAG_STRIP, &urgency_str, { "urgency", 'u', POPT_ARG_STRING | POPT_ARGFLAG_STRIP, &urgency_str,
@ -57,11 +59,13 @@ main(int argc, const char **argv)
N_("ICON1,ICON2,...") }, N_("ICON1,ICON2,...") },
{ "type", 't', POPT_ARG_STRING | POPT_ARGFLAG_STRIP, &type, 0, { "type", 't', POPT_ARG_STRING | POPT_ARGFLAG_STRIP, &type, 0,
N_("Specifies the notification type."), N_("Specifies the notification type."),
N_("TYPE") }, N_("ICON1,ICON2,...") },
POPT_AUTOHELP POPT_AUTOHELP
POPT_TABLEEND POPT_TABLEEND
}; };
g_type_init ();
opt_ctx = poptGetContext("notify-send", argc, argv, options, 0); opt_ctx = poptGetContext("notify-send", argc, argv, options, 0);
poptSetOtherOptionHelp(opt_ctx, "[OPTIONS]* <summary> [body]"); poptSetOtherOptionHelp(opt_ctx, "[OPTIONS]* <summary> [body]");
@ -74,7 +78,8 @@ main(int argc, const char **argv)
exit(1); exit(1);
} }
summary = args[0]; if (args[0] != NULL)
summary = args[0];
if (summary == NULL) if (summary == NULL)
{ {
@ -82,12 +87,15 @@ main(int argc, const char **argv)
exit(1); exit(1);
} }
body = args[1]; if (args[1] != NULL)
if (body != NULL && args[2] != NULL)
{ {
poptPrintUsage(opt_ctx, stderr, 0); body = args[1];
exit(1);
if (args[2] != NULL)
{
poptPrintUsage(opt_ctx, stderr, 0);
exit(1);
}
} }
if (icons != NULL) if (icons != NULL)
@ -100,7 +108,6 @@ main(int argc, const char **argv)
icon_str = icons; icon_str = icons;
icon = notify_icon_new_from_uri(icon_str);
} }
if (urgency_str != NULL) if (urgency_str != NULL)
@ -121,11 +128,13 @@ main(int argc, const char **argv)
if (!notify_init("notify-send")) if (!notify_init("notify-send"))
exit(1); exit(1);
notify_send_notification(NULL, type, urgency, summary, body, icon,
TRUE, expire_timeout, NULL, NULL, 0);
if (icon != NULL) notify = notify_notification_new (summary, body, icon_str, NULL);
notify_icon_destroy(icon); notify_notification_set_category (notify, type);
notify_notification_set_urgency (notify, urgency);
notify_notification_set_timeout (notify, expire_timeout);
notify_notification_show_and_forget (notify, NULL);
poptFreeContext(opt_ctx); poptFreeContext(opt_ctx);
notify_uninit(); notify_uninit();