From 41d4a3e49882860c6ec8c43e54f2360dd4e75dc0 Mon Sep 17 00:00:00 2001 From: Christian Hammond Date: Thu, 4 Nov 2004 07:44:53 +0000 Subject: [PATCH] Patch from Mike Hearn to do a bunch of stuff, like handling icons and animations better. --- ChangeLog | 9 ++++ libnotify/notify.c | 97 ++++++++++++++++++++++++++++++++++++------ libnotify/notify.h | 54 +++++++++++++++++++++-- tests/test-animation.c | 22 +++++++++- tests/test-image.c | 5 +-- 5 files changed, 164 insertions(+), 23 deletions(-) diff --git a/ChangeLog b/ChangeLog index 57bae5e..faeaca0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +Wed Nov 03 23:34:10 PST 2004 Christian Hammond + + * libnotify/notify.c: + * libnotify/notify.h: + * tests/test-animation.c: + * tests/test-image.c: + - Patch from Mike Hearn to do a bunch of stuff, like handling icons + and animations better. + Wed Nov 03 01:19:42 PST 2004 Christian Hammond * configure.ac: diff --git a/libnotify/notify.c b/libnotify/notify.c index 2c18e3f..1f4d86b 100644 --- a/libnotify/notify.c +++ b/libnotify/notify.c @@ -55,10 +55,12 @@ struct _NotifyHandle struct _NotifyIcon { - char *uri; + int frames; - size_t raw_len; - guchar *raw_data; + char **uri; + + size_t *raw_len; + guchar **raw_data; }; typedef struct @@ -507,8 +509,19 @@ notify_get_server_caps(void) /************************************************************************** * Icon API **************************************************************************/ + NotifyIcon * -notify_icon_new(const char *icon_uri) +notify_icon_new() +{ + NotifyIcon *icon; + + icon = g_new0(NotifyIcon, 1); + + return icon; +} + +NotifyIcon * +notify_icon_new_from_uri(const char *icon_uri) { NotifyIcon *icon; @@ -517,13 +530,15 @@ notify_icon_new(const char *icon_uri) icon = g_new0(NotifyIcon, 1); - icon->uri = g_strdup(icon_uri); + icon->frames = 1; + icon->uri = malloc(sizeof(char *)); + icon->uri[0] = g_strdup(icon_uri); return icon; } NotifyIcon * -notify_icon_new_with_data(size_t icon_len, const guchar *icon_data) +notify_icon_new_from_data(size_t icon_len, const guchar *icon_data) { NotifyIcon *icon; @@ -532,12 +547,48 @@ notify_icon_new_with_data(size_t icon_len, const guchar *icon_data) icon = g_new0(NotifyIcon, 1); - icon->raw_len = icon_len; - icon->raw_data = g_memdup(icon_data, icon_len); + icon->frames = 1; + icon->raw_len = malloc(sizeof(icon->raw_len)); + icon->raw_len[0] = icon_len; + icon->raw_data = malloc(sizeof(guchar *)); + icon->raw_data[0] = g_memdup(icon_data, icon_len); return icon; } +gboolean +notify_icon_add_frame_from_data(NotifyIcon *icon, size_t icon_len, const guchar *icon_data) +{ + g_return_val_if_fail(icon != NULL, FALSE); + g_return_val_if_fail(icon_data != NULL, FALSE); + g_return_val_if_fail(icon_len != 0, FALSE); + + if (icon->frames) g_return_val_if_fail(icon->raw_len != NULL, FALSE); + + icon->frames++; + icon->raw_len = realloc(icon->raw_len, sizeof(size_t) * icon->frames); + icon->raw_len[icon->frames - 1] = icon_len; + icon->raw_data = realloc(icon->raw_data, sizeof(guchar *) * icon->frames); + icon->raw_data[icon->frames - 1] = g_memdup(icon_data, icon_len); + + return TRUE; +} + +gboolean +notify_icon_add_frame_from_uri(NotifyIcon *icon, const char *uri) +{ + g_return_val_if_fail(icon != NULL, FALSE); + g_return_val_if_fail(uri != NULL, FALSE); + + if (icon->frames) g_return_val_if_fail(icon->uri != NULL, FALSE); + + icon->frames++; + icon->uri = realloc(icon->uri, sizeof(char *) * icon->frames); + icon->uri[icon->frames - 1] = g_strdup(uri); + + return TRUE; +} + void notify_icon_destroy(NotifyIcon *icon) { @@ -593,9 +644,11 @@ notify_send_notification_varg(NotifyHandle *replaces, const char *type, guint32 i; NotifyHandle *handle; + g_return_val_if_fail(notify_is_initted(), NULL); + message = _notify_dbus_message_new("Notify", &iter); - g_return_val_if_fail(message != NULL, 0); + g_return_val_if_fail(message != NULL, NULL); _notify_dbus_message_iter_append_string_or_nil(&iter, _app_name); dbus_message_iter_append_nil(&iter); @@ -611,17 +664,33 @@ notify_send_notification_varg(NotifyHandle *replaces, const char *type, * For now, allow a NIL. */ if (icon == NULL) - dbus_message_iter_append_nil(&iter); - else if (icon->raw_len > 0 && icon->raw_data != NULL) { + dbus_message_iter_append_nil(&iter); + } + else if (icon->raw_data) + { + int i; + dbus_message_iter_append_array(&iter, &array_iter, DBUS_TYPE_ARRAY); - dbus_message_iter_append_byte_array(&array_iter, icon->raw_data, - icon->raw_len); + + for (i = 0; i < icon->frames; i++) + { + dbus_message_iter_append_byte_array(&array_iter, icon->raw_data[i], + icon->raw_len[i]); + } } else { + int i; + dbus_message_iter_append_array(&iter, &array_iter, DBUS_TYPE_STRING); - dbus_message_iter_append_string(&array_iter, icon->uri); + + g_assert( icon->uri != NULL); /* can be either raw data OR uri */ + + for (i = 0; i < icon->frames; i++) + { + dbus_message_iter_append_string(&array_iter, icon->uri[i]); + } } /* Actions */ diff --git a/libnotify/notify.h b/libnotify/notify.h index 69bf640..e8fc0e0 100644 --- a/libnotify/notify.h +++ b/libnotify/notify.h @@ -17,7 +17,12 @@ * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. + * + * TODO: + * - We talk about URIs, but they are actually file paths not URIs + * - Un-glibify? */ + #ifndef _LIBNOTIFY_NOTIFY_H_ #define _LIBNOTIFY_NOTIFY_H_ @@ -108,25 +113,66 @@ GList *notify_get_server_caps(void); /*@{*/ /** - * Creates an icon with the specified icon URI. + * 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(const char *icon_uri); +NotifyIcon *notify_icon_new_from_uri(const char *icon_uri); /** - * Creates an icon with the specified icon data. + * 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_with_data(size_t icon_len, +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. * diff --git a/tests/test-animation.c b/tests/test-animation.c index 66c8dd9..911d594 100644 --- a/tests/test-animation.c +++ b/tests/test-animation.c @@ -20,6 +20,7 @@ */ #include +#include #include #include #include @@ -29,7 +30,7 @@ /// WRITE ME! /// -int frames = 10; +const int frames = 10; // returns array of pixbufs for a pulsing animation GdkPixbuf **generate_animation() @@ -62,18 +63,35 @@ GdkPixbuf **generate_animation() 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, pngdata); } NotifyHandle *n = notify_send_notification(NULL, // replaces nothing NULL, NOTIFY_URGENCY_NORMAL, "Summary", "Content", - NULL, // no icon + icon, TRUE, time(NULL) + 5, NULL, // no user data 0); // no actions diff --git a/tests/test-image.c b/tests/test-image.c index 10735ef..a12728b 100644 --- a/tests/test-image.c +++ b/tests/test-image.c @@ -46,9 +46,9 @@ static void send(char *i, size_t rawlen, char *s, char *b) NotifyIcon *icon; if (rawlen > 0) - icon = notify_icon_new_with_data(rawlen, i); + icon = notify_icon_new_from_data(rawlen, i); else - icon = notify_icon_new(i); + icon = notify_icon_new_from_uri(i); n = notify_send_notification(NULL, // replaces nothing NULL, @@ -95,7 +95,6 @@ int main() { "Warning!"); - // FIXME: test raw image transfer struct stat buf; if (stat(file, &buf) == -1) {