diff options
author | seb128 <seb128@seb128-desktop> | 2009-04-08 10:57:41 +0200 |
---|---|---|
committer | seb128 <seb128@seb128-desktop> | 2009-04-08 10:57:41 +0200 |
commit | df604ba78746b932c269d6c5b1b455ef28e2a319 (patch) | |
tree | f9c8b374a13391d0935aa6474eb5db9113382437 /libindicate/listener.c | |
parent | 4134dd03ae290419bfab493afc8c71ceab9a5d75 (diff) | |
parent | 746b6aa32390dc97bebf371f5b36b2fa24a288c6 (diff) | |
download | libayatana-indicator-df604ba78746b932c269d6c5b1b455ef28e2a319.tar.gz libayatana-indicator-df604ba78746b932c269d6c5b1b455ef28e2a319.tar.bz2 libayatana-indicator-df604ba78746b932c269d6c5b1b455ef28e2a319.zip |
releasing version 0.1.5-0ubuntu1
Diffstat (limited to 'libindicate/listener.c')
-rw-r--r-- | libindicate/listener.c | 214 |
1 files changed, 160 insertions, 54 deletions
diff --git a/libindicate/listener.c b/libindicate/listener.c index b786552..381a5f9 100644 --- a/libindicate/listener.c +++ b/libindicate/listener.c @@ -32,7 +32,7 @@ License version 3 and version 2.1 along with this program. If not, see #include <dbus/dbus-glib-bindings.h> #include "dbus-indicate-client.h" #include "dbus-listener-client.h" -#include "dbus-listener-server.h" +#include "interests-priv.h" /* Errors */ enum { @@ -51,6 +51,17 @@ enum { static guint signals[LAST_SIGNAL] = { 0 }; +struct _IndicateListenerServer { + gchar * name; + DBusGProxy * proxy; + DBusGConnection * connection; + gboolean interests[INDICATE_INTEREST_LAST]; +}; + +struct _IndicateListenerIndicator { + guint id; +}; + typedef struct _IndicateListenerPrivate IndicateListenerPrivate; struct _IndicateListenerPrivate { @@ -60,8 +71,8 @@ struct _IndicateListenerPrivate DBusGProxy * dbus_proxy_session; DBusGProxy * dbus_proxy_system; - GHashTable * proxies_working; - GHashTable * proxies_possible; + GList * proxies_working; + GList * proxies_possible; GArray * proxy_todo; guint todo_idle; @@ -78,8 +89,23 @@ typedef struct { gchar * type; IndicateListener * listener; GHashTable * indicators; + + IndicateListenerServer server; } proxy_t; +static gint +proxy_t_equal (gconstpointer pa, gconstpointer pb) +{ + proxy_t * a = (proxy_t *)pa; proxy_t * b = (proxy_t *)pb; + + if (a->connection == b->connection) { + return g_strcmp0(a->name, b->name); + } else { + /* we're only using this for equal, not sorting */ + return 1; + } +} + typedef struct { DBusGConnection * bus; gchar * name; @@ -95,7 +121,7 @@ static void proxy_struct_destroy (gpointer data); static void build_todo_list_cb (DBusGProxy * proxy, char ** names, GError * error, void * data); static void todo_list_add (const gchar * name, DBusGProxy * proxy, IndicateListener * listener, gboolean startup); static gboolean todo_idle (gpointer data); -void get_type_cb (IndicateListener * listener, IndicateListenerServer * server, gchar * type, gpointer data); +static void get_type_cb (IndicateListener * listener, IndicateListenerServer * server, gchar * type, gpointer data); static void proxy_server_added (DBusGProxy * proxy, const gchar * type, proxy_t * proxyt); static void proxy_indicator_added (DBusGProxy * proxy, guint id, const gchar * type, proxy_t * proxyt); static void proxy_indicator_removed (DBusGProxy * proxy, guint id, const gchar * type, proxy_t * proxyt); @@ -104,6 +130,12 @@ static void proxy_get_indicator_list (DBusGProxy * proxy, GArray * indicators, G static void proxy_get_indicator_type (DBusGProxy * proxy, gchar * type, GError * error, gpointer data); static void proxy_indicators_free (gpointer data); +/* DBus interface */ +gboolean _indicate_listener_get_indicator_servers (IndicateListener * listener, GList * servers); + +/* Need the above prototypes */ +#include "dbus-listener-server.h" + /* Code */ static void indicate_listener_class_init (IndicateListenerClass * class) @@ -121,38 +153,38 @@ indicate_listener_class_init (IndicateListenerClass * class) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (IndicateListenerClass, indicator_added), NULL, NULL, - indicate_listener_marshal_VOID__POINTER_POINTER_STRING, + _indicate_listener_marshal_VOID__POINTER_POINTER_STRING, G_TYPE_NONE, 3, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_STRING); signals[INDICATOR_REMOVED] = g_signal_new(INDICATE_LISTENER_SIGNAL_INDICATOR_REMOVED, G_TYPE_FROM_CLASS (class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (IndicateListenerClass, indicator_removed), NULL, NULL, - indicate_listener_marshal_VOID__POINTER_POINTER_STRING, + _indicate_listener_marshal_VOID__POINTER_POINTER_STRING, G_TYPE_NONE, 3, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_STRING); signals[INDICATOR_MODIFIED] = g_signal_new(INDICATE_LISTENER_SIGNAL_INDICATOR_MODIFIED, G_TYPE_FROM_CLASS (class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (IndicateListenerClass, indicator_modified), NULL, NULL, - indicate_listener_marshal_VOID__POINTER_POINTER_STRING_STRING, + _indicate_listener_marshal_VOID__POINTER_POINTER_STRING_STRING, G_TYPE_NONE, 4, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_STRING, G_TYPE_STRING); signals[SERVER_ADDED] = g_signal_new(INDICATE_LISTENER_SIGNAL_SERVER_ADDED, G_TYPE_FROM_CLASS (class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (IndicateListenerClass, server_added), NULL, NULL, - indicate_listener_marshal_VOID__POINTER_STRING, + _indicate_listener_marshal_VOID__POINTER_STRING, G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_STRING); signals[SERVER_REMOVED] = g_signal_new(INDICATE_LISTENER_SIGNAL_SERVER_REMOVED, G_TYPE_FROM_CLASS (class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (IndicateListenerClass, server_removed), NULL, NULL, - indicate_listener_marshal_VOID__POINTER_STRING, + _indicate_listener_marshal_VOID__POINTER_STRING, G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_STRING); - dbus_g_object_register_marshaller(indicate_listener_marshal_VOID__UINT_STRING, + dbus_g_object_register_marshaller(_indicate_listener_marshal_VOID__UINT_STRING, G_TYPE_NONE, G_TYPE_UINT, G_TYPE_STRING, @@ -219,8 +251,8 @@ indicate_listener_init (IndicateListener * listener) G_CALLBACK(dbus_owner_change), listener, NULL); /* Initialize Data structures */ - priv->proxies_working = g_hash_table_new(g_str_hash, g_str_equal); - priv->proxies_possible = g_hash_table_new(g_str_hash, g_str_equal); + priv->proxies_working = NULL; + priv->proxies_possible = NULL; /* TODO: Look at some common scenarios and find out how to make this sized */ priv->proxy_todo = g_array_new(FALSE, TRUE, sizeof(proxy_todo_t)); @@ -292,16 +324,20 @@ dbus_owner_change (DBusGProxy * proxy, const gchar * name, const gchar * prev, c todo_list_add(name, proxy, listener, FALSE); } if (new != NULL && new[0] == '\0') { - proxy_t * proxyt; - proxyt = g_hash_table_lookup(priv->proxies_working, name); - if (proxyt != NULL) { - g_hash_table_remove(priv->proxies_working, name); - proxy_struct_destroy(proxyt); + proxy_t searchitem; + searchitem.connection = bus; + searchitem.name = (gchar *)name; /* Droping const, not that it isn't, but to remove the warning */ + + GList * proxyt_item; + proxyt_item = g_list_find_custom(priv->proxies_working, &searchitem, proxy_t_equal); + if (proxyt_item != NULL) { + proxy_struct_destroy((proxy_t *)proxyt_item->data); + priv->proxies_working = g_list_remove(priv->proxies_working, proxyt_item->data); } - proxyt = g_hash_table_lookup(priv->proxies_possible, name); - if (proxyt != NULL) { - g_hash_table_remove(priv->proxies_possible, name); - proxy_struct_destroy(proxyt); + proxyt_item = g_list_find_custom(priv->proxies_possible, &searchitem, proxy_t_equal); + if (proxyt_item != NULL) { + proxy_struct_destroy((proxy_t *)proxyt_item->data); + priv->proxies_possible = g_list_remove(priv->proxies_possible, proxyt_item->data); } } @@ -319,7 +355,7 @@ proxy_struct_destroy_indicators (gpointer key, gpointer value, gpointer data) GList * indicator; for (indicator = keys; indicator != NULL; indicator = indicator->next) { guint id = (guint)indicator->data; - g_signal_emit(proxy_data->listener, signals[INDICATOR_REMOVED], 0, proxy_data->name, id, type, TRUE); + g_signal_emit(proxy_data->listener, signals[INDICATOR_REMOVED], 0, &proxy_data->server, GUINT_TO_POINTER(id), type, TRUE); } g_list_free(keys); @@ -339,15 +375,15 @@ proxy_struct_destroy (gpointer data) proxy_data); g_hash_table_remove_all(proxy_data->indicators); - g_signal_emit(proxy_data->listener, signals[SERVER_REMOVED], 0, proxy_data->name, proxy_data->type, TRUE); + g_signal_emit(proxy_data->listener, signals[SERVER_REMOVED], 0, &proxy_data->server, proxy_data->type, TRUE); proxy_data->indicators = NULL; } - if (proxy_data->property_proxy) { + if (DBUS_IS_G_PROXY(proxy_data->property_proxy)) { g_object_unref(G_OBJECT(proxy_data->property_proxy)); } - if (proxy_data->proxy) { + if (DBUS_IS_G_PROXY(proxy_data->proxy)) { g_object_unref(G_OBJECT(proxy_data->proxy)); } @@ -433,7 +469,7 @@ todo_idle (gpointer data) proxy_todo_t * todo = &g_array_index(priv->proxy_todo, proxy_todo_t, priv->proxy_todo->len - 1); - proxy_t * proxyt = g_new(proxy_t, 1); + proxy_t * proxyt = g_new0(proxy_t, 1); proxyt->name = todo->name; proxyt->type = NULL; proxyt->proxy = dbus_g_proxy_new_for_name(todo->bus, @@ -444,6 +480,9 @@ todo_idle (gpointer data) proxyt->listener = listener; proxyt->indicators = NULL; proxyt->connection = todo->bus; + proxyt->server.name = todo->name; + proxyt->server.proxy = proxyt->proxy; + proxyt->server.connection = proxyt->connection; priv->proxy_todo = g_array_remove_index(priv->proxy_todo, priv->proxy_todo->len - 1); @@ -457,7 +496,7 @@ todo_idle (gpointer data) dbus_g_proxy_connect_signal(proxyt->proxy, "ServerShow", G_CALLBACK(proxy_server_added), proxyt, NULL); - g_hash_table_insert(priv->proxies_possible, proxyt->name, proxyt); + priv->proxies_possible = g_list_prepend(priv->proxies_possible, proxyt); /* I think that we need to have this as there is a race * condition here. If someone comes on the bus and we get @@ -465,12 +504,12 @@ todo_idle (gpointer data) * signal it gets sent, we wouldn't get it. So then we would * miss an indicator server coming on the bus. I'd like to not * generate a warning in every app with DBus though. */ - indicate_listener_server_get_type(listener, (IndicateListenerServer *)proxyt->name, get_type_cb, proxyt); + indicate_listener_server_get_type(listener, &proxyt->server, get_type_cb, proxyt); return TRUE; } -void +static void get_type_cb (IndicateListener * listener, IndicateListenerServer * server, gchar * type, gpointer data) { if (type == NULL) { @@ -538,8 +577,13 @@ proxy_server_added (DBusGProxy * proxy, const gchar * type, proxy_t * proxyt) g_free, proxy_indicators_free); /* Elevate to working */ IndicateListenerPrivate * priv = INDICATE_LISTENER_GET_PRIVATE(proxyt->listener); - g_hash_table_remove(priv->proxies_possible, proxyt->name); - g_hash_table_insert(priv->proxies_working, proxyt->name, proxyt); + + GList * proxyt_item; + proxyt_item = g_list_find_custom(priv->proxies_possible, proxyt, proxy_t_equal); + if (proxyt_item != NULL) { + priv->proxies_possible = g_list_remove(priv->proxies_possible, proxyt_item->data); + } + priv->proxies_working = g_list_prepend(priv->proxies_working, proxyt); dbus_g_proxy_add_signal(proxyt->proxy, "IndicatorAdded", G_TYPE_UINT, G_TYPE_STRING, G_TYPE_INVALID); @@ -561,7 +605,7 @@ proxy_server_added (DBusGProxy * proxy, const gchar * type, proxy_t * proxyt) proxyt->type = g_strdup(type); } - g_signal_emit(proxyt->listener, signals[SERVER_ADDED], 0, proxyt->name, proxyt->type, TRUE); + g_signal_emit(proxyt->listener, signals[SERVER_ADDED], 0, &proxyt->server, proxyt->type, TRUE); } return; @@ -583,7 +627,7 @@ proxy_indicator_added (DBusGProxy * proxy, guint id, const gchar * type, proxy_t if (!g_hash_table_lookup(indicators, (gpointer)id)) { g_hash_table_insert(indicators, (gpointer)id, (gpointer)TRUE); - g_signal_emit(proxyt->listener, signals[INDICATOR_ADDED], 0, proxyt->name, id, type, TRUE); + g_signal_emit(proxyt->listener, signals[INDICATOR_ADDED], 0, &proxyt->server, GUINT_TO_POINTER(id), type, TRUE); } return; @@ -609,7 +653,7 @@ proxy_indicator_removed (DBusGProxy * proxy, guint id, const gchar * type, proxy } g_hash_table_remove(indicators, (gpointer)id); - g_signal_emit(proxyt->listener, signals[INDICATOR_REMOVED], 0, proxyt->name, id, type, TRUE); + g_signal_emit(proxyt->listener, signals[INDICATOR_REMOVED], 0, &proxyt->server, GUINT_TO_POINTER(id), type, TRUE); return; } @@ -642,7 +686,7 @@ proxy_indicator_modified (DBusGProxy * proxy, guint id, const gchar * property, return; } - g_signal_emit(proxyt->listener, signals[INDICATOR_MODIFIED], 0, proxyt->name, id, type, property, TRUE); + g_signal_emit(proxyt->listener, signals[INDICATOR_MODIFIED], 0, &proxyt->server, GUINT_TO_POINTER(id), type, property, TRUE); return; } @@ -754,14 +798,6 @@ get_property_helper (IndicateListener * listener, IndicateListenerServer * serve { /* g_debug("get_property_helper: %s %d", property, prop_type); */ /* TODO: Do we need to somehow refcount the server/indicator while we're waiting on this? */ - IndicateListenerPrivate * priv = INDICATE_LISTENER_GET_PRIVATE(listener); - - proxy_t * proxyt = g_hash_table_lookup(priv->proxies_working, server); - if (proxyt == NULL) { - g_error("Trying to get property '%s' on server '%s' that currently isn't set to working.", property, (gchar *)server); - return; - } - get_property_t * get_property_data = g_new(get_property_t, 1); get_property_data->cb = callback; get_property_data->data = data; @@ -771,7 +807,7 @@ get_property_helper (IndicateListener * listener, IndicateListenerServer * serve get_property_data->property = g_strdup(property); get_property_data->type = prop_type; - org_freedesktop_indicator_get_indicator_property_async (proxyt->proxy , INDICATE_LISTENER_INDICATOR_ID(indicator), property, get_property_cb, get_property_data); + org_freedesktop_indicator_get_indicator_property_async (server->proxy , INDICATE_LISTENER_INDICATOR_ID(indicator), property, get_property_cb, get_property_data); return; } @@ -794,7 +830,7 @@ indicate_listener_get_property_icon (IndicateListener * listener, IndicateListen } gboolean -indicate_listener_get_indicator_servers (IndicateListener * listener, GList * servers) +_indicate_listener_get_indicator_servers (IndicateListener * listener, GList * servers) { @@ -812,11 +848,7 @@ listener_display_cb (DBusGProxy *proxy, GError *error, gpointer userdata) void indicate_listener_display (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator) { - IndicateListenerPrivate * priv = INDICATE_LISTENER_GET_PRIVATE(listener); - - proxy_t * proxyt = g_hash_table_lookup(priv->proxies_working, server); - - org_freedesktop_indicator_show_indicator_to_user_async (proxyt->proxy, INDICATE_LISTENER_INDICATOR_ID(indicator), listener_display_cb, NULL); + org_freedesktop_indicator_show_indicator_to_user_async (server->proxy, INDICATE_LISTENER_INDICATOR_ID(indicator), listener_display_cb, NULL); return; } @@ -871,16 +903,22 @@ get_server_property (IndicateListener * listener, IndicateListenerServer * serve /* g_debug("Setting up callback for property %s on %s", property_name, INDICATE_LISTENER_SERVER_DBUS_NAME(server)); */ IndicateListenerPrivate * priv = INDICATE_LISTENER_GET_PRIVATE(listener); - proxy_t * proxyt = g_hash_table_lookup(priv->proxies_possible, server); - if (proxyt == NULL) { - proxyt = g_hash_table_lookup(priv->proxies_working, server); + proxy_t searchitem; + searchitem.name = server->name; + searchitem.connection = server->connection; + + GList * proxyitem = g_list_find_custom(priv->proxies_possible, &searchitem, proxy_t_equal); + if (proxyitem == NULL) { + proxyitem = g_list_find_custom(priv->proxies_working, &searchitem, proxy_t_equal); } - if (proxyt == NULL) { + if (proxyitem == NULL) { g_warning("Can not find a proxy for the server at all."); return; } + proxy_t * proxyt = (proxy_t *)proxyitem->data; + if (proxyt->property_proxy == NULL) { proxyt->property_proxy = dbus_g_proxy_new_for_name(proxyt->connection, proxyt->name, @@ -918,3 +956,71 @@ indicate_listener_server_get_desktop (IndicateListener * listener, IndicateListe return get_server_property(listener, server, callback, "desktop", data); } +const gchar * +indicate_listener_server_get_dbusname (IndicateListenerServer * server) +{ + if (server == NULL) return NULL; + return server->name; +} + +guint +indicate_listener_indicator_get_id (IndicateListenerIndicator * indicator) +{ + return GPOINTER_TO_UINT(indicator); +} + +static const gchar * +interest_to_string (IndicateInterests interest) +{ + switch (interest) { + case INDICATE_INTEREST_SERVER_DISPLAY: + return INDICATE_INTEREST_STRING_SERVER_DISPLAY; + case INDICATE_INTEREST_SERVER_SIGNAL: + return INDICATE_INTEREST_STRING_SERVER_SIGNAL; + case INDICATE_INTEREST_INDICATOR_DISPLAY: + return INDICATE_INTEREST_STRING_INDICATOR_DISPLAY; + case INDICATE_INTEREST_INDICATOR_SIGNAL: + return INDICATE_INTEREST_STRING_INDICATOR_SIGNAL; + case INDICATE_INTEREST_INDICATOR_COUNT: + return INDICATE_INTEREST_STRING_INDICATOR_COUNT; + default: + return ""; + } +} + +static void +interest_cb (DBusGProxy *proxy, GError *error, gpointer userdata) +{ + if (error != NULL) { + g_warning("Unable to configure interest."); + } + + return; +} + +void +indicate_listener_server_show_interest (IndicateListener * listener, IndicateListenerServer * server, IndicateInterests interest) +{ + if (!server->interests[interest]) { + org_freedesktop_indicator_show_interest_async (server->proxy, interest_to_string(interest), interest_cb, server); + server->interests[interest] = TRUE; + } + return; +} + +void +indicate_listener_server_remove_interest (IndicateListener * listener, IndicateListenerServer * server, IndicateInterests interest) +{ + if (server->interests[interest]) { + org_freedesktop_indicator_remove_interest_async (server->proxy, interest_to_string(interest), interest_cb, server); + server->interests[interest] = FALSE; + } + return; +} + +gboolean +indicate_listener_server_check_interest (IndicateListener * listener, IndicateListenerServer * server, IndicateInterests interest) +{ + return server->interests[interest]; +} + |