aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTed Gould <ted@gould.cx>2010-07-12 09:28:16 -0500
committerTed Gould <ted@gould.cx>2010-07-12 09:28:16 -0500
commite273b812e0ee52f84e2284d2560e63437cbc1a67 (patch)
tree1eb460bc2d5bbb769af264b1bbd826a69a722f68 /src
parent4e2c23b9b99d2014747a051d949b0c2a2d9595db (diff)
parent7ef183418aaee73864e44d93b32e80962fdea07a (diff)
downloadlibayatana-appindicator-e273b812e0ee52f84e2284d2560e63437cbc1a67.tar.gz
libayatana-appindicator-e273b812e0ee52f84e2284d2560e63437cbc1a67.tar.bz2
libayatana-appindicator-e273b812e0ee52f84e2284d2560e63437cbc1a67.zip
* Merge upstream
* Adding an Approver API to remove things from the AppIndicators.
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am1
-rw-r--r--src/application-service-appstore.c125
-rw-r--r--src/application-service-appstore.h14
-rw-r--r--src/application-service-watcher.c14
-rw-r--r--src/dbus-shared.h2
-rw-r--r--src/notification-approver.xml22
-rw-r--r--src/notification-watcher.xml7
7 files changed, 171 insertions, 14 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 787ba2f..68be1c0 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -116,6 +116,7 @@ libappindicator_la_LIBADD = \
DBUS_SPECS = \
dbus-properties.xml \
application-service.xml \
+ notification-approver.xml \
notification-item.xml \
notification-watcher.xml
diff --git a/src/application-service-appstore.c b/src/application-service-appstore.c
index 15abea3..311fcb1 100644
--- a/src/application-service-appstore.c
+++ b/src/application-service-appstore.c
@@ -31,6 +31,7 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
#include "application-service-marshal.h"
#include "dbus-properties-client.h"
#include "dbus-shared.h"
+#include "notification-approver-client.h"
/* DBus Prototypes */
static gboolean _application_service_server_get_applications (ApplicationServiceAppstore * appstore, GPtrArray ** apps, GError ** error);
@@ -50,13 +51,18 @@ static gboolean _application_service_server_get_applications (ApplicationService
#define NOTIFICATION_ITEM_SIG_NEW_STATUS "NewStatus"
/* Private Stuff */
-typedef struct _ApplicationServiceAppstorePrivate ApplicationServiceAppstorePrivate;
struct _ApplicationServiceAppstorePrivate {
DBusGConnection * bus;
GList * applications;
+ GList * approvers;
AppLruFile * lrufile;
};
+typedef struct _Approver Approver;
+struct _Approver {
+ DBusGProxy * proxy;
+};
+
typedef struct _Application Application;
struct _Application {
gchar * id;
@@ -95,6 +101,9 @@ static void application_service_appstore_dispose (GObject *object);
static void application_service_appstore_finalize (GObject *object);
static AppIndicatorStatus string_to_status(const gchar * status_string);
static void apply_status (Application * app, AppIndicatorStatus status);
+static void approver_free (gpointer papprover, gpointer user_data);
+static void check_with_new_approver (gpointer papp, gpointer papprove);
+static void check_with_old_approver (gpointer papprove, gpointer papp);
G_DEFINE_TYPE (ApplicationServiceAppstore, application_service_appstore, G_TYPE_OBJECT);
@@ -139,9 +148,11 @@ application_service_appstore_class_init (ApplicationServiceAppstoreClass *klass)
static void
application_service_appstore_init (ApplicationServiceAppstore *self)
{
- ApplicationServiceAppstorePrivate * priv = APPLICATION_SERVICE_APPSTORE_GET_PRIVATE(self);
+
+ ApplicationServiceAppstorePrivate * priv = APPLICATION_SERVICE_APPSTORE_GET_PRIVATE (self);
priv->applications = NULL;
+ priv->approvers = NULL;
priv->lrufile = NULL;
GError * error = NULL;
@@ -155,6 +166,8 @@ application_service_appstore_init (ApplicationServiceAppstore *self)
dbus_g_connection_register_g_object(priv->bus,
INDICATOR_APPLICATION_DBUS_OBJ,
G_OBJECT(self));
+
+ self->priv = priv;
return;
}
@@ -162,7 +175,7 @@ application_service_appstore_init (ApplicationServiceAppstore *self)
static void
application_service_appstore_dispose (GObject *object)
{
- ApplicationServiceAppstorePrivate * priv = APPLICATION_SERVICE_APPSTORE_GET_PRIVATE(object);
+ ApplicationServiceAppstorePrivate * priv = APPLICATION_SERVICE_APPSTORE(object)->priv;
while (priv->applications != NULL) {
application_service_appstore_application_remove(APPLICATION_SERVICE_APPSTORE(object),
@@ -170,6 +183,12 @@ application_service_appstore_dispose (GObject *object)
((Application *)priv->applications->data)->dbus_object);
}
+ if (priv->approvers != NULL) {
+ g_list_foreach(priv->approvers, approver_free, NULL);
+ g_list_free(priv->approvers);
+ priv->approvers = NULL;
+ }
+
G_OBJECT_CLASS (application_service_appstore_parent_class)->dispose (object);
return;
}
@@ -209,7 +228,7 @@ get_all_properties_cb (DBusGProxy * proxy, GHashTable * properties, GError * err
app->id = g_value_dup_string(g_hash_table_lookup(properties, NOTIFICATION_ITEM_PROP_ID));
app->category = g_value_dup_string(g_hash_table_lookup(properties, NOTIFICATION_ITEM_PROP_CATEGORY));
- ApplicationServiceAppstorePrivate * priv = APPLICATION_SERVICE_APPSTORE_GET_PRIVATE(app->appstore);
+ ApplicationServiceAppstorePrivate * priv = app->appstore->priv;
app_lru_file_touch(priv->lrufile, app->id, app->category);
app->icon = g_value_dup_string(g_hash_table_lookup(properties, NOTIFICATION_ITEM_PROP_ICON_NAME));
@@ -234,11 +253,23 @@ get_all_properties_cb (DBusGProxy * proxy, GHashTable * properties, GError * err
app->icon_path = g_strdup("");
}
+ /* TODO: Calling approvers, but we're ignoring the results. So, eh. */
+ g_list_foreach(priv->approvers, check_with_old_approver, app);
+
apply_status(app, string_to_status(g_value_get_string(g_hash_table_lookup(properties, NOTIFICATION_ITEM_PROP_STATUS))));
return;
}
+/* Check the application against an approver */
+static void
+check_with_old_approver (gpointer papprove, gpointer papp)
+{
+ /* Funny the parallels, eh? */
+ check_with_new_approver(papp, papprove);
+ return;
+}
+
/* Simple translation function -- could be optimized */
static AppIndicatorStatus
string_to_status(const gchar * status_string)
@@ -265,7 +296,7 @@ string_to_status(const gchar * status_string)
static gint
get_position (Application * app) {
ApplicationServiceAppstore * appstore = app->appstore;
- ApplicationServiceAppstorePrivate * priv = APPLICATION_SERVICE_APPSTORE_GET_PRIVATE(appstore);
+ ApplicationServiceAppstorePrivate * priv = appstore->priv;
GList * applistitem = g_list_find(priv->applications, app);
if (applistitem == NULL) {
@@ -384,7 +415,7 @@ apply_status (Application * app, AppIndicatorStatus status)
g_debug("Changing app status to: %d", status);
ApplicationServiceAppstore * appstore = app->appstore;
- ApplicationServiceAppstorePrivate * priv = APPLICATION_SERVICE_APPSTORE_GET_PRIVATE(appstore);
+ ApplicationServiceAppstorePrivate * priv = appstore->priv;
/* This means we're going off line */
if (status == APP_INDICATOR_STATUS_PASSIVE) {
@@ -567,7 +598,7 @@ application_service_appstore_application_add (ApplicationServiceAppstore * appst
g_return_if_fail(IS_APPLICATION_SERVICE_APPSTORE(appstore));
g_return_if_fail(dbus_name != NULL && dbus_name[0] != '\0');
g_return_if_fail(dbus_object != NULL && dbus_object[0] != '\0');
- ApplicationServiceAppstorePrivate * priv = APPLICATION_SERVICE_APPSTORE_GET_PRIVATE(appstore);
+ ApplicationServiceAppstorePrivate * priv = appstore->priv;
/* Build the application entry. This will be carried
along until we're sure we've got everything. */
@@ -665,7 +696,7 @@ application_service_appstore_application_remove (ApplicationServiceAppstore * ap
g_return_if_fail(dbus_name != NULL && dbus_name[0] != '\0');
g_return_if_fail(dbus_object != NULL && dbus_object[0] != '\0');
- ApplicationServiceAppstorePrivate * priv = APPLICATION_SERVICE_APPSTORE_GET_PRIVATE(appstore);
+ ApplicationServiceAppstorePrivate * priv = appstore->priv;
GList * listpntr;
for (listpntr = priv->applications; listpntr != NULL; listpntr = g_list_next(listpntr)) {
@@ -687,7 +718,7 @@ application_service_appstore_new (AppLruFile * lrufile)
{
g_return_val_if_fail(IS_APP_LRU_FILE(lrufile), NULL);
ApplicationServiceAppstore * appstore = APPLICATION_SERVICE_APPSTORE(g_object_new(APPLICATION_SERVICE_APPSTORE_TYPE, NULL));
- ApplicationServiceAppstorePrivate * priv = APPLICATION_SERVICE_APPSTORE_GET_PRIVATE(appstore);
+ ApplicationServiceAppstorePrivate * priv = appstore->priv;
priv->lrufile = lrufile;
return appstore;
}
@@ -696,7 +727,7 @@ application_service_appstore_new (AppLruFile * lrufile)
static gboolean
_application_service_server_get_applications (ApplicationServiceAppstore * appstore, GPtrArray ** apps, GError ** error)
{
- ApplicationServiceAppstorePrivate * priv = APPLICATION_SERVICE_APPSTORE_GET_PRIVATE(appstore);
+ ApplicationServiceAppstorePrivate * priv = appstore->priv;
*apps = g_ptr_array_new();
GList * listpntr;
@@ -743,3 +774,77 @@ _application_service_server_get_applications (ApplicationServiceAppstore * appst
return TRUE;
}
+/* Frees the data associated with an approver */
+static void
+approver_free (gpointer papprover, gpointer user_data)
+{
+ Approver * approver = (Approver *)papprover;
+ g_return_if_fail(approver != NULL);
+
+ if (approver->proxy != NULL) {
+ g_object_unref(approver->proxy);
+ approver->proxy = NULL;
+ }
+
+ g_free(approver);
+ return;
+}
+
+/* What did the approver tell us? */
+static void
+approver_request_cb (DBusGProxy *proxy, gboolean OUT_approved, GError *error, gpointer userdata)
+{
+ g_debug("Approver responded: %s", OUT_approved ? "approve" : "rejected");
+ return;
+}
+
+/* Run the applications through the new approver */
+static void
+check_with_new_approver (gpointer papp, gpointer papprove)
+{
+ Application * app = (Application *)papp;
+ Approver * approver = (Approver *)papprove;
+
+ org_ayatana_StatusNotifierApprover_approve_item_async(approver->proxy,
+ app->id,
+ app->category,
+ 0,
+ app->dbus_name,
+ app->dbus_object,
+ approver_request_cb,
+ app);
+
+ return;
+}
+
+/* Adds a new approver to the app store */
+void
+application_service_appstore_approver_add (ApplicationServiceAppstore * appstore, const gchar * dbus_name, const gchar * dbus_object)
+{
+ g_return_if_fail(IS_APPLICATION_SERVICE_APPSTORE(appstore));
+ g_return_if_fail(dbus_name != NULL);
+ g_return_if_fail(dbus_object != NULL);
+ ApplicationServiceAppstorePrivate * priv = APPLICATION_SERVICE_APPSTORE_GET_PRIVATE (appstore);
+
+ Approver * approver = g_new0(Approver, 1);
+
+ GError * error = NULL;
+ approver->proxy = dbus_g_proxy_new_for_name_owner(priv->bus,
+ dbus_name,
+ dbus_object,
+ NOTIFICATION_APPROVER_DBUS_IFACE,
+ &error);
+ if (error != NULL) {
+ g_warning("Unable to get approver interface on '%s:%s' : %s", dbus_name, dbus_object, error->message);
+ g_error_free(error);
+ g_free(approver);
+ return;
+ }
+
+ priv->approvers = g_list_prepend(priv->approvers, approver);
+
+ g_list_foreach(priv->applications, check_with_new_approver, approver);
+
+ return;
+}
+
diff --git a/src/application-service-appstore.h b/src/application-service-appstore.h
index d2e0013..e8ba8c1 100644
--- a/src/application-service-appstore.h
+++ b/src/application-service-appstore.h
@@ -38,6 +38,7 @@ G_BEGIN_DECLS
typedef struct _ApplicationServiceAppstore ApplicationServiceAppstore;
typedef struct _ApplicationServiceAppstoreClass ApplicationServiceAppstoreClass;
+typedef struct _ApplicationServiceAppstorePrivate ApplicationServiceAppstorePrivate;
struct _ApplicationServiceAppstoreClass {
GObjectClass parent_class;
@@ -49,16 +50,21 @@ struct _ApplicationServiceAppstoreClass {
struct _ApplicationServiceAppstore {
GObject parent;
+
+ ApplicationServiceAppstorePrivate * priv;
};
ApplicationServiceAppstore * application_service_appstore_new (AppLruFile * lrufile);
GType application_service_appstore_get_type (void);
void application_service_appstore_application_add (ApplicationServiceAppstore * appstore,
- const gchar * dbus_name,
- const gchar * dbus_object);
+ const gchar * dbus_name,
+ const gchar * dbus_object);
void application_service_appstore_application_remove (ApplicationServiceAppstore * appstore,
- const gchar * dbus_name,
- const gchar * dbus_object);
+ const gchar * dbus_name,
+ const gchar * dbus_object);
+void application_service_appstore_approver_add (ApplicationServiceAppstore * appstore,
+ const gchar * dbus_name,
+ const gchar * dbus_object);
G_END_DECLS
diff --git a/src/application-service-watcher.c b/src/application-service-watcher.c
index eff249d..4fe3bc7 100644
--- a/src/application-service-watcher.c
+++ b/src/application-service-watcher.c
@@ -34,6 +34,7 @@ static gboolean _notification_watcher_server_register_status_notifier_item (Appl
static gboolean _notification_watcher_server_registered_status_notifier_items (ApplicationServiceWatcher * appwatcher, GArray ** apps);
static gboolean _notification_watcher_server_protocol_version (ApplicationServiceWatcher * appwatcher, char ** version);
static gboolean _notification_watcher_server_register_notification_host (ApplicationServiceWatcher * appwatcher, const gchar * host);
+static gboolean _notification_watcher_server_register_notification_approver (ApplicationServiceWatcher * appwatcher, const gchar * path, const GArray * categories, DBusGMethodInvocation * method);
static gboolean _notification_watcher_server_is_notification_host_registered (ApplicationServiceWatcher * appwatcher, gboolean * haveHost);
static void get_name_cb (DBusGProxy * proxy, guint status, GError * error, gpointer data);
@@ -249,3 +250,16 @@ get_name_cb (DBusGProxy * proxy, guint status, GError * error, gpointer data)
return;
}
+
+static gboolean
+_notification_watcher_server_register_notification_approver (ApplicationServiceWatcher * appwatcher, const gchar * path, const GArray * categories, DBusGMethodInvocation * method)
+{
+ ApplicationServiceWatcherPrivate * priv = APPLICATION_SERVICE_WATCHER_GET_PRIVATE(appwatcher);
+
+ application_service_appstore_approver_add(priv->appstore,
+ dbus_g_method_get_sender(method),
+ path);
+
+ dbus_g_method_return(method, G_TYPE_NONE);
+ return TRUE;
+}
diff --git a/src/dbus-shared.h b/src/dbus-shared.h
index f158b1c..1d8d89c 100644
--- a/src/dbus-shared.h
+++ b/src/dbus-shared.h
@@ -31,3 +31,5 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
#define NOTIFICATION_ITEM_DBUS_IFACE "org.kde.StatusNotifierItem"
#define NOTIFICATION_ITEM_DEFAULT_OBJ "/StatusNotifierItem"
+#define NOTIFICATION_APPROVER_DBUS_IFACE "org.ayatana.StatusNotifierApprover"
+
diff --git a/src/notification-approver.xml b/src/notification-approver.xml
new file mode 100644
index 0000000..b1e69b9
--- /dev/null
+++ b/src/notification-approver.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<node name="/">
+ <interface name="org.ayatana.StatusNotifierApprover">
+
+<!-- Methods -->
+ <method name="ApproveItem">
+ <!-- KSNI ID -->
+ <arg type="s" name="id" direction="in" />
+ <!-- KSNI Category -->
+ <arg type="s" name="category" direction="in" />
+ <!-- Application PID -->
+ <arg type="u" name="pid" direction="in" />
+ <!-- Application DBus Address -->
+ <arg type="s" name="address" direction="in" />
+ <!-- Application DBus Path for KSNI interface -->
+ <arg type="o" name="path" direction="in" />
+ <!-- So, what do you think? -->
+ <arg type="b" name="approved" direction="out" />
+ </method>
+
+ </interface>
+</node>
diff --git a/src/notification-watcher.xml b/src/notification-watcher.xml
index c2324f1..cc7882d 100644
--- a/src/notification-watcher.xml
+++ b/src/notification-watcher.xml
@@ -22,6 +22,13 @@
<method name="IsNotificationHostRegistered">
<arg type="b" name="hasHost" direction="out" />
</method>
+ <method name="RegisterNotificationApprover">
+ <annotation name="org.freedesktop.DBus.GLib.Async" value="true" />
+ <!-- The path where to find the approver interface -->
+ <arg type="o" name="path" direction="in" />
+ <!-- List of categories to approve, none represents all -->
+ <arg type="as" name="categories" direction="in" />
+ </method>
<!-- Signals -->
<signal name="ServiceRegistered">