From 26727e093390c353efb2e5442e8c2f6d8c861cbd Mon Sep 17 00:00:00 2001 From: Christian Hammond Date: Mon, 28 Jun 2004 01:39:16 +0000 Subject: [PATCH] - Split notify_close() into notify_close_notification() and notify_close_request(). - Implement notify_send_request() and notify_send_request_with_icon_data(), and add versions of those functions that take a va_list for the buttons. --- ChangeLog | 10 ++ libnotify/notify.c | 234 ++++++++++++++++++++++++++++++++++++++++++++- libnotify/notify.h | 69 ++++++++++++- 3 files changed, 306 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index dfb52af..876798e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +Sun Jun 27 18:30:19 PDT 2004 Christian Hammond + + * libnotify/notify.c: + * libnotify/notify.h: + - Split notify_close() into notify_close_notification() and + notify_close_request(). + - Implement notify_send_request() and + notify_send_request_with_icon_data(), and add versions of those + functions that take a va_list for the buttons. + Sun Jun 27 16:46:32 PDT 2004 Christian Hammond * libnotify/notify.c: diff --git a/libnotify/notify.c b/libnotify/notify.c index df948dc..0854c17 100644 --- a/libnotify/notify.c +++ b/libnotify/notify.c @@ -62,6 +62,46 @@ _notify_dbus_message_new(const char *name, DBusMessageIter *iter) return message; } +static void +_notify_dbus_message_iter_append_string_or_nil(DBusMessageIter *iter, + const char *str) +{ + g_return_if_fail(iter != NULL); + + if (str == NULL) + dbus_message_iter_append_nil(iter); + else + dbus_message_iter_append_string(iter, str); +} + +#if 0 +static char * +_notify_dbus_message_iter_get_string_or_nil(DBusMessageIter *iter) +{ + int arg_type; + + g_return_val_if_fail(iter != NULL, NULL); + + arg_type = dbus_message_iter_get_arg_type(iter); + + if (arg_type == DBUS_TYPE_STRING) + return dbus_message_iter_get_string(iter); + + g_return_val_if_fail(arg_type == DBUS_TYPE_NIL, NULL); + + return NULL; +} +#endif + +static void +_notify_dbus_message_iter_append_app_info(DBusMessageIter *iter) +{ + g_return_if_fail(iter != NULL); + + dbus_message_iter_append_string(iter, _app_name); + dbus_message_iter_append_nil(iter); /* App Icon */ +} + static DBusHandlerResult _filter_func(DBusConnection *dbus_conn, DBusMessage *message, void *user_data) { @@ -210,6 +250,8 @@ notify_close_notification(guint32 id) message = _notify_dbus_message_new("CloseNotification", &iter); + g_return_if_fail(message != NULL); + dbus_message_iter_append_uint32(&iter, id); dbus_connection_send(_dbus_conn, message, NULL); @@ -226,28 +268,153 @@ notify_close_request(guint32 id) message = _notify_dbus_message_new("CloseRequest", &iter); + g_return_if_fail(message != NULL); + dbus_message_iter_append_uint32(&iter, id); dbus_connection_send(_dbus_conn, message, NULL); dbus_message_unref(message); } +static guint32 +_notify_send_notification(NotifyUrgency urgency, const char *summary, + const char *detailed, const char *icon_uri, + size_t icon_len, guchar *icon_data, time_t timeout) +{ + DBusMessage *message, *reply; + DBusMessageIter iter; + DBusError error; + guint32 id; + + message = _notify_dbus_message_new("SendNotification", &iter); + + g_return_val_if_fail(message != NULL, 0); + + _notify_dbus_message_iter_append_app_info(&iter); + dbus_message_iter_append_uint32(&iter, urgency); + dbus_message_iter_append_string(&iter, summary); + _notify_dbus_message_iter_append_string_or_nil(&iter, detailed); + + if (icon_len > 0 && icon_data != NULL) + dbus_message_iter_append_byte_array(&iter, icon_data, icon_len); + else + _notify_dbus_message_iter_append_string_or_nil(&iter, icon_uri); + + dbus_message_iter_append_uint32(&iter, timeout); + + dbus_error_init(&error); + + reply = dbus_connection_send_with_reply_and_block(_dbus_conn, message, + -1, &error); + + dbus_message_unref(message); + + if (dbus_error_is_set(&error)) + { + fprintf(stderr, "Error sending SendNotification: %s\n", + error.message); + dbus_error_free(&error); + + return 0; + } + + dbus_message_iter_init(reply, &iter); + id = dbus_message_iter_get_uint32(&iter); + + dbus_message_unref(reply); + dbus_error_free(&error); + + return id; +} + guint32 notify_send_notification(NotifyUrgency urgency, const char *summary, const char *detailed, const char *icon_uri, time_t timeout) { - return 0; + g_return_val_if_fail(summary != NULL, 0); + + return _notify_send_notification(urgency, summary, detailed, icon_uri, + 0, NULL, timeout); } guint32 notify_send_notification_with_icon_data(NotifyUrgency urgency, const char *summary, const char *detailed, - size_t icon_len, void *icon_data, + size_t icon_len, guchar *icon_data, time_t timeout) { - return 0; + g_return_val_if_fail(summary != NULL, 0); + + return _notify_send_notification(urgency, summary, detailed, NULL, + icon_len, icon_data, timeout); +} + +static guint32 +_notify_send_request(NotifyUrgency urgency, const char *summary, + const char *detailed, const char *icon_uri, + size_t icon_len, guchar *icon_data, time_t timeout, + gpointer user_data, guint32 default_button, + size_t button_count, va_list buttons) +{ + DBusMessage *message, *reply; + DBusMessageIter iter; + DBusError error; + guint32 id; + guint32 i; + char *text; + NotifyCallback cb; + + message = _notify_dbus_message_new("SendRequest", &iter); + + g_return_val_if_fail(message != NULL, 0); + + _notify_dbus_message_iter_append_app_info(&iter); + dbus_message_iter_append_uint32(&iter, urgency); + dbus_message_iter_append_string(&iter, summary); + _notify_dbus_message_iter_append_string_or_nil(&iter, detailed); + + if (icon_len > 0 && icon_data != NULL) + dbus_message_iter_append_byte_array(&iter, icon_data, icon_len); + else + _notify_dbus_message_iter_append_string_or_nil(&iter, icon_uri); + + dbus_message_iter_append_uint32(&iter, timeout); + dbus_message_iter_append_uint32(&iter, default_button); + dbus_message_iter_append_uint32(&iter, button_count); + + for (i = 0; i < button_count; i++) + { + text = va_arg(buttons, char *); + cb = va_arg(buttons, NotifyCallback); + + dbus_message_iter_append_string(&iter, text); + } + + dbus_error_init(&error); + + reply = dbus_connection_send_with_reply_and_block(_dbus_conn, message, + -1, &error); + + dbus_message_unref(message); + + if (dbus_error_is_set(&error)) + { + fprintf(stderr, "Error sending SendNotification: %s\n", + error.message); + dbus_error_free(&error); + + return 0; + } + + dbus_message_iter_init(reply, &iter); + id = dbus_message_iter_get_uint32(&iter); + + dbus_message_unref(reply); + dbus_error_free(&error); + + return id; } guint32 @@ -256,7 +423,34 @@ notify_send_request(NotifyUrgency urgency, const char *summary, time_t timeout, gpointer user_data, size_t default_button, size_t button_count, ...) { - return 0; + va_list buttons; + guint32 id; + + g_return_val_if_fail(summary != NULL, 0); + g_return_val_if_fail(button_count > 1, 0); + + va_start(buttons, button_count); + id = notify_send_request_varg(urgency, summary, detailed, icon_uri, + timeout, user_data, default_button, + button_count, buttons); + va_end(buttons); + + return id; +} + +guint32 +notify_send_request_varg(NotifyUrgency urgency, const char *summary, + const char *detailed, const char *icon_uri, + time_t timeout, gpointer user_data, + size_t default_button, size_t button_count, + va_list buttons) +{ + g_return_val_if_fail(summary != NULL, 0); + g_return_val_if_fail(button_count > 1, 0); + + return _notify_send_request(urgency, summary, detailed, icon_uri, + 0, NULL, timeout, user_data, default_button, + button_count, buttons); } guint32 @@ -267,5 +461,35 @@ notify_send_request_with_icon_data(NotifyUrgency urgency, gint32 default_button, size_t button_count, ...) { - return 0; + va_list buttons; + guint32 id; + + g_return_val_if_fail(summary != NULL, 0); + g_return_val_if_fail(button_count > 1, 0); + + va_start(buttons, button_count); + id = notify_send_request_with_icon_data_varg(urgency, summary, detailed, + icon_len, icon_data, timeout, + user_data, default_button, + button_count, buttons); + va_end(buttons); + + return id; +} + +guint32 +notify_send_request_with_icon_data_varg(NotifyUrgency urgency, + const char *summary, + const char *detailed, + size_t icon_len, guchar *icon_data, + time_t timeout, gpointer user_data, + gint32 default_button, + size_t button_count, va_list buttons) +{ + g_return_val_if_fail(summary != NULL, 0); + g_return_val_if_fail(button_count > 1, 0); + + return _notify_send_request(urgency, summary, detailed, NULL, icon_len, + icon_data, timeout, user_data, default_button, + button_count, buttons); } diff --git a/libnotify/notify.h b/libnotify/notify.h index 4cada9a..aaa6ab2 100644 --- a/libnotify/notify.h +++ b/libnotify/notify.h @@ -36,6 +36,8 @@ typedef enum } NotifyUrgency; +typedef void (*NotifyCallback)(guint32, guint32, gpointer); + /**************************************************************************/ /** @name libnotify Base API */ /**************************************************************************/ @@ -75,7 +77,7 @@ void notify_close_notification(guint32 id); /** * Automatically closes a request. * - * The default button's callback, if any, will be called. + * No callbacks for the dialog will be called. * * @param id The ID of the request. */ @@ -121,7 +123,7 @@ guint32 notify_send_notification_with_icon_data(NotifyUrgency urgency, const char *summary, const char *detailed, size_t icon_len, - void *icon_data, + guchar *icon_data, time_t timeout); /*@}*/ @@ -159,6 +161,34 @@ guint32 notify_send_request(NotifyUrgency urgency, const char *summary, size_t default_button, size_t button_count, ...); +/** + * Sends a standard request, taking a va_list for the buttons. + * + * A callback has the following prototype: + * + * @code + * void callback(guint32 id, guint32 button, void *user_data); + * @endcode + * + * @param urgency The urgency level. + * @param summary The summary of the request. + * @param detailed The optional detailed information. + * @param icon_uri The optional icon URI. + * @param timeout The optional time to automatically close the request, + * or 0. + * @param user_data User-specified data to send to a callback. + * @param default_button The default button, or -1. + * @param button_count The number of buttons. + * @param buttons The buttons in string/callback pairs. + * + * @return A unique ID for the request. + */ +guint32 notify_send_request_varg(NotifyUrgency urgency, const char *summary, + const char *detailed, const char *icon_uri, + time_t timeout, gpointer user_data, + size_t default_button, size_t button_count, + va_list buttons); + /** * Sends a standard request with raw icon data. * @@ -192,6 +222,41 @@ guint32 notify_send_request_with_icon_data(NotifyUrgency urgency, gint32 default_button, size_t button_count, ...); +/** + * Sends a standard request with raw icon data, taking a va_list for the + * buttons. + * + * A callback has the following prototype: + * + * @code + * void callback(guint32 id, guint32 button, void *user_data); + * @endcode + * + * @param urgency The urgency level. + * @param summary The summary of the request. + * @param detailed The optional detailed information. + * @param icon_len The icon data length. + * @param icon_data The icon data. + * @param timeout The optional time to automatically close the request, + * or 0. + * @param user_data User-specified data to send to a callback. + * @param default_button The default button, or -1. + * @param button_count The number of buttons. + * @param buttons The buttons in string/callback pairs. + * + * @return A unique ID for the request. + */ +guint32 notify_send_request_with_icon_data_varg(NotifyUrgency urgency, + const char *summary, + const char *detailed, + size_t icon_len, + guchar *icon_data, + time_t timeout, + gpointer user_data, + gint32 default_button, + size_t button_count, + va_list buttons); + /*@}*/ #endif /* _LIBNOTIFY_NOTIFY_H_ */