[pulseaudio-discuss] [PATCH 5/8] desktop-notifications: Implemented notification cancelling in the DN backend.
Ștefan Săftescu
stefan.saftescu at gmail.com
Thu Jul 12 09:10:26 PDT 2012
---
.../module-ui-notification-dn-backend.c | 126 +++++++++++++++++---
1 file changed, 112 insertions(+), 14 deletions(-)
diff --git a/src/modules/notifications/module-ui-notification-dn-backend.c b/src/modules/notifications/module-ui-notification-dn-backend.c
index c8918e0..aa13687 100644
--- a/src/modules/notifications/module-ui-notification-dn-backend.c
+++ b/src/modules/notifications/module-ui-notification-dn-backend.c
@@ -51,7 +51,9 @@ struct backend_userdata {
pa_dbus_connection *conn;
pa_hashmap* displaying;
- PA_LLIST_HEAD(pa_dbus_pending, pending);
+ pa_idxset* cancelling;
+ PA_LLIST_HEAD(pa_dbus_pending, pending_send);
+ PA_LLIST_HEAD(pa_dbus_pending, pending_cancel);
};
struct module_userdata {
@@ -82,6 +84,64 @@ static pa_dbus_pending* pa_dbus_send_message(
return p;
}
+static void cancel_notification_reply(DBusPendingCall *pending, void *userdata) {
+ DBusError err;
+ DBusMessage *msg;
+ pa_ui_notification_backend *backend;
+ pa_ui_notification *notification;
+ pa_dbus_pending *p;
+ struct backend_userdata *u;
+
+ pa_assert(pending);
+
+ dbus_error_init(&err);
+
+ pa_assert_se(p = userdata);
+ pa_assert_se(backend = p->context_data);
+ pa_assert_se(notification = p->call_data);
+ pa_assert_se(u = backend->userdata);
+ pa_assert_se(msg = dbus_pending_call_steal_reply(pending));
+
+ if (dbus_message_is_error(msg, DBUS_ERROR_SERVICE_UNKNOWN)) {
+ pa_log_debug("No Notifications server registered.");
+
+ /* TODO: notification reply error */
+
+ goto finish;
+ }
+
+ if (dbus_message_get_type(msg) == DBUS_MESSAGE_TYPE_ERROR) {
+ pa_log_error("org.freedesktop.Notifications.CancelNotification() failed: %s: %s", dbus_message_get_error_name(msg), pa_dbus_get_error_message(msg));
+ goto finish;
+ }
+
+ /* TODO: notificatioin reply cancel */
+finish:
+ dbus_message_unref(msg);
+
+ PA_LLIST_REMOVE(pa_dbus_pending, u->pending_cancel, p);
+ pa_dbus_pending_free(p);
+}
+
+static inline void cancel_notification_dbus(pa_ui_notification_backend *backend, pa_ui_notification *notification, unsigned *dbus_notification_id) {
+ DBusConnection *conn;
+ DBusMessage *msg;
+ pa_dbus_pending *p;
+ struct backend_userdata *u;
+
+ u = backend->userdata;
+
+ conn = pa_dbus_connection_get(u->conn);
+ msg = dbus_message_new_method_call("org.freedesktop.Notifications", "/org/freedesktop/Notifications", "org.freedesktop.Notifications", "CloseNotification");
+ pa_assert_se(dbus_message_append_args(msg, DBUS_TYPE_UINT32, dbus_notification_id, DBUS_TYPE_INVALID));
+
+ p = pa_dbus_send_message(conn, msg, cancel_notification_reply, backend, notification);
+
+ PA_LLIST_PREPEND(pa_dbus_pending, u->pending_cancel, p);
+
+ pa_xfree(dbus_notification_id);
+}
+
static void send_notification_reply(DBusPendingCall *pending, void *userdata) {
DBusError err;
DBusMessage *msg;
@@ -89,7 +149,7 @@ static void send_notification_reply(DBusPendingCall *pending, void *userdata) {
pa_ui_notification *notification;
pa_dbus_pending *p;
struct backend_userdata *u;
- int *dbus_notification_id;
+ unsigned *dbus_notification_id;
pa_assert(pending);
@@ -101,7 +161,7 @@ static void send_notification_reply(DBusPendingCall *pending, void *userdata) {
pa_assert_se(u = backend->userdata);
pa_assert_se(msg = dbus_pending_call_steal_reply(pending));
- dbus_notification_id = pa_xnew(int, 1);
+ dbus_notification_id = pa_xnew(unsigned, 1);
if (dbus_message_is_error(msg, DBUS_ERROR_SERVICE_UNKNOWN)) {
pa_log_debug("No Notifications server registered.");
@@ -121,12 +181,16 @@ static void send_notification_reply(DBusPendingCall *pending, void *userdata) {
goto finish;
}
- pa_hashmap_put(u->displaying, notification, dbus_notification_id);
+ if (pa_idxset_remove_by_data(u->cancelling, notification, NULL)) {
+ cancel_notification_dbus(backend, notification, dbus_notification_id);
+ } else {
+ pa_hashmap_put(u->displaying, notification, dbus_notification_id);
+ }
finish:
dbus_message_unref(msg);
- PA_LLIST_REMOVE(pa_dbus_pending, u->pending, p);
+ PA_LLIST_REMOVE(pa_dbus_pending, u->pending_send, p);
pa_dbus_pending_free(p);
}
@@ -163,11 +227,20 @@ static void send_notification(pa_ui_notification_backend *b, pa_ui_notification
p = pa_dbus_send_message(conn, msg, send_notification_reply, b, n);
pa_log_debug("D-Bus message sent.");
- PA_LLIST_PREPEND(pa_dbus_pending, u->pending, p);
+ PA_LLIST_PREPEND(pa_dbus_pending, u->pending_send, p);
}
-static void cancel_notification(pa_ui_notification_backend *b, pa_ui_notification *n) {
- /* TODO */
+static void cancel_notification(pa_ui_notification_backend *backend, pa_ui_notification *notification) {
+ struct backend_userdata *u;
+ unsigned *dbus_notification_id;
+
+ u = backend->userdata;
+
+ if ((dbus_notification_id = pa_hashmap_remove(u->displaying, notification))) {
+ cancel_notification_dbus(backend, notification, dbus_notification_id);
+ } else {
+ pa_idxset_put(u->cancelling, notification, NULL);
+ }
}
int pa__init(pa_module*m) {
@@ -188,10 +261,12 @@ int pa__init(pa_module*m) {
u->app_icon = "";
u->conn = pa_dbus_bus_get(m->core, DBUS_BUS_SESSION, &err);
u->displaying = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
+ u->cancelling = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
/* TODO: error checking */
- PA_LLIST_HEAD_INIT(pa_dbus_pending, u->pending);
+ PA_LLIST_HEAD_INIT(pa_dbus_pending, u->pending_send);
+ PA_LLIST_HEAD_INIT(pa_dbus_pending, u->pending_cancel);
backend->send_notification = send_notification;
backend->cancel_notification = cancel_notification;
@@ -210,12 +285,34 @@ int pa__init(pa_module*m) {
}
}
-static void displaying_notifications_cancel(pa_hashmap *displaying) {
+static void displaying_notifications_cancel(pa_ui_notification_backend *backend) {
+ void *state;
+ pa_ui_notification *notification;
+ unsigned *dbus_notification_id;
+ struct backend_userdata *u;
+
+ pa_assert(backend);
+ pa_assert(u = backend->userdata);
+
+ PA_HASHMAP_FOREACH_KEY(dbus_notification_id, notification, u->displaying, state) {
+ pa_hashmap_remove(u->displaying, notification);
+ cancel_notification_dbus(backend, notification, dbus_notification_id);
+ }
}
-static void pending_notifications_cancel(pa_dbus_pending **pending) {
+static void pending_notifications_cancel(pa_dbus_pending **p) {
+ pa_dbus_pending *i;
+
+ pa_assert(p);
+ while ((i = *p)) {
+ PA_LLIST_REMOVE(pa_dbus_pending, *p, i);
+
+ /* TODO: notification reply cancel */
+
+ pa_dbus_pending_free(i);
+ }
}
void pa__done(pa_module*m) {
@@ -239,11 +336,12 @@ void pa__done(pa_module*m) {
if(u) {
pa_dbus_connection_unref(u->conn);
- displaying_notifications_cancel(u->displaying);
+ displaying_notifications_cancel(b);
pa_hashmap_free(u->displaying, NULL, NULL);
+ pa_idxset_free(u->cancelling, NULL, NULL);
- pending_notifications_cancel(&u->pending);
- pa_dbus_free_pending_list(&u->pending); /* TODO: reply cb: cancelled */
+ pending_notifications_cancel(&u->pending_send);
+ pending_notifications_cancel(&u->pending_cancel);
}
pa_xfree(u);
--
1.7.10.4
More information about the pulseaudio-discuss
mailing list