diff options
-rw-r--r-- | debian/changelog | 9 | ||||
-rw-r--r-- | debian/control | 1 | ||||
-rw-r--r-- | libindicate/Makefile.am | 4 | ||||
-rw-r--r-- | libindicate/indicate.pc.in | 2 | ||||
-rw-r--r-- | libindicate/indicator-message.c | 1 | ||||
-rw-r--r-- | libindicate/indicator.c | 86 | ||||
-rw-r--r-- | libindicate/indicator.h | 9 | ||||
-rw-r--r-- | libindicate/listener.c | 141 | ||||
-rw-r--r-- | libindicate/listener.h | 23 | ||||
-rw-r--r-- | libindicate/server.c | 108 | ||||
-rw-r--r-- | libindicate/server.h | 13 | ||||
-rw-r--r-- | tests/im-client.c | 4 | ||||
-rw-r--r-- | tests/listen-and-print.c | 20 |
13 files changed, 273 insertions, 148 deletions
diff --git a/debian/changelog b/debian/changelog index 5ee19e7..7558022 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,12 @@ +indicator-applet (0.1~ppa17) intrepid; urgency=low + + * Fixing the handling of named DBus connections + * Moving most of the data in the objects to private sections + * Making the signal names defines for easier usage + * Having property changes actually work now. + + -- Ted Gould <ted@ubuntu.com> Thu, 29 Jan 2009 13:38:16 -0600 + indicator-applet (0.1~ppa16) intrepid; urgency=low * Forgot to run autogen.sh before last package :( diff --git a/debian/control b/debian/control index bdc2172..2b47abf 100644 --- a/debian/control +++ b/debian/control @@ -13,7 +13,6 @@ Build-Depends: debhelper (>= 5.0), intltool, gobject-introspection (>= 0.6), gobject-introspection-glib-2.0 (>= 0.6), - gobject-introspection-repository (>= 0.6), libgirepository-dev (>= 0.6) Standards-Version: 3.8.0 diff --git a/libindicate/Makefile.am b/libindicate/Makefile.am index e2aef39..9fe05dc 100644 --- a/libindicate/Makefile.am +++ b/libindicate/Makefile.am @@ -14,7 +14,7 @@ BUILT_SOURCES = \ lib_LTLIBRARIES = \ libindicate.la -libindicateincludedir=$(includedir)/libindicate-1.0/libindicate +libindicateincludedir=$(includedir)/libindicate-0.1/libindicate indicate_headers = \ indicator.h \ @@ -90,8 +90,6 @@ Indicate-0.1.gir: $(irscanner_headers) --add-include-path=$(srcdir) \ --include=GObject-2.0 \ --include=GLib-2.0 \ - --include=DBus-1.0 \ - --include=DBusGLib-1.0 \ --library=indicate --pkg indicate \ --output Indicate-0.1.gir $(irscanner_headers) diff --git a/libindicate/indicate.pc.in b/libindicate/indicate.pc.in index 96ef15e..cdc79b6 100644 --- a/libindicate/indicate.pc.in +++ b/libindicate/indicate.pc.in @@ -4,7 +4,7 @@ libdir=@libdir@ bindir=@bindir@ includedir=@includedir@ -Cflags: -I${includedir}/libindicate-1.0 +Cflags: -I${includedir}/libindicate-0.1 Requires: gtk+-2.0 dbus-glib-1 Libs: -L${libdir} -lindicate diff --git a/libindicate/indicator-message.c b/libindicate/indicator-message.c index 32cf000..00217d7 100644 --- a/libindicate/indicator-message.c +++ b/libindicate/indicator-message.c @@ -8,6 +8,7 @@ typedef struct _IndicateIndicatorMessagePrivate IndicateIndicatorMessagePrivate; struct _IndicateIndicatorMessagePrivate { + gchar * subtype; }; #define INDICATE_INDICATOR_MESSAGE_GET_PRIVATE(o) \ diff --git a/libindicate/indicator.c b/libindicate/indicator.c index 8caf8e4..94af726 100644 --- a/libindicate/indicator.c +++ b/libindicate/indicator.c @@ -2,17 +2,31 @@ #include "glib.h" #include "glib/gmessages.h" #include "indicator.h" +#include "server.h" /* Signals */ enum { HIDE, SHOW, USER_DISPLAY, + MODIFIED, LAST_SIGNAL }; static guint signals[LAST_SIGNAL] = { 0 }; +typedef struct _IndicateIndicatorPrivate IndicateIndicatorPrivate; +struct _IndicateIndicatorPrivate +{ + guint id; + gboolean is_visible; + IndicateServer * server; + GHashTable * properties; +}; + +#define INDICATE_INDICATOR_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((o), INDICATE_TYPE_INDICATOR, IndicateIndicatorPrivate)) + G_DEFINE_TYPE (IndicateIndicator, indicate_indicator, G_TYPE_OBJECT); static void indicate_indicator_finalize (GObject * object); @@ -30,6 +44,8 @@ indicate_indicator_class_init (IndicateIndicatorClass * class) GObjectClass * gobj; gobj = G_OBJECT_CLASS(class); + g_type_class_add_private (class, sizeof (IndicateIndicatorPrivate)); + gobj->finalize = indicate_indicator_finalize; signals[USER_DISPLAY] = g_signal_new(INDICATE_INDICATOR_SIGNAL_DISPLAY, @@ -53,6 +69,13 @@ indicate_indicator_class_init (IndicateIndicatorClass * class) NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + signals[MODIFIED] = g_signal_new(INDICATE_INDICATOR_SIGNAL_MODIFIED, + G_TYPE_FROM_CLASS(class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(IndicateIndicatorClass, modified), + NULL, NULL, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, 1, G_TYPE_STRING); class->get_type = NULL; class->set_property = set_property; @@ -66,15 +89,16 @@ static void indicate_indicator_init (IndicateIndicator * indicator) { g_debug("Indicator Object Initialized."); + IndicateIndicatorPrivate * priv = INDICATE_INDICATOR_GET_PRIVATE(indicator); - indicator->is_visible = FALSE; + priv->is_visible = FALSE; - indicator->properties = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); + priv->properties = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); + priv->server = indicate_server_ref_default(); + priv->id = indicate_server_get_next_id(priv->server); - indicator->server = indicate_server_ref_default(); - indicator->id = indicate_server_get_next_id(indicator->server); - indicate_server_add_indicator(indicator->server, indicator); + indicate_server_add_indicator(priv->server, indicator); return; } @@ -83,10 +107,11 @@ static void indicate_indicator_finalize (GObject * obj) { IndicateIndicator * indicator = INDICATE_INDICATOR(obj); + IndicateIndicatorPrivate * priv = INDICATE_INDICATOR_GET_PRIVATE(indicator); - indicate_server_remove_indicator(indicator->server, indicator); - g_object_unref(indicator->server); - indicator->server = NULL; + indicate_server_remove_indicator(priv->server, indicator); + g_object_unref(priv->server); + priv->server = NULL; return; } @@ -101,15 +126,17 @@ indicate_indicator_new (void) void indicate_indicator_show (IndicateIndicator * indicator) { - if (indicator->is_visible) { + IndicateIndicatorPrivate * priv = INDICATE_INDICATOR_GET_PRIVATE(indicator); + + if (priv->is_visible) { return; } - if (indicator->server) { - indicate_server_show(indicator->server); + if (priv->server) { + indicate_server_show(priv->server); } - indicator->is_visible = TRUE; + priv->is_visible = TRUE; g_signal_emit(indicator, signals[SHOW], 0, TRUE); return; @@ -118,11 +145,13 @@ indicate_indicator_show (IndicateIndicator * indicator) void indicate_indicator_hide (IndicateIndicator * indicator) { - if (!indicator->is_visible) { + IndicateIndicatorPrivate * priv = INDICATE_INDICATOR_GET_PRIVATE(indicator); + + if (!priv->is_visible) { return; } - indicator->is_visible = FALSE; + priv->is_visible = FALSE; g_signal_emit(indicator, signals[HIDE], 0, TRUE); return; @@ -131,14 +160,17 @@ indicate_indicator_hide (IndicateIndicator * indicator) gboolean indicate_indicator_is_visible (IndicateIndicator * indicator) { - return indicator->is_visible; + g_return_val_if_fail(INDICATE_IS_INDICATOR(indicator), FALSE); + IndicateIndicatorPrivate * priv = INDICATE_INDICATOR_GET_PRIVATE(indicator); + return priv->is_visible; } guint indicate_indicator_get_id (IndicateIndicator * indicator) { g_return_val_if_fail(INDICATE_IS_INDICATOR(indicator), 0); - return indicator->id; + IndicateIndicatorPrivate * priv = INDICATE_INDICATOR_GET_PRIVATE(indicator); + return priv->id; } const gchar * @@ -157,7 +189,8 @@ indicate_indicator_get_indicator_type (IndicateIndicator * indicator) void indicate_indicator_user_display (IndicateIndicator * indicator) { - if (!indicator->is_visible) { + IndicateIndicatorPrivate * priv = INDICATE_INDICATOR_GET_PRIVATE(indicator); + if (!priv->is_visible) { return; } @@ -208,8 +241,16 @@ set_property (IndicateIndicator * indicator, const gchar * key, const gchar * da return; } - g_hash_table_insert(indicator->properties, g_strdup(key), g_strdup(data)); - // TODO: Signal + IndicateIndicatorPrivate * priv = INDICATE_INDICATOR_GET_PRIVATE(indicator); + + gchar * current = g_hash_table_lookup(priv->properties, key); + if (current == NULL || strcmp(current, data)) { + /* If the value has changed or there is no value */ + gchar * newkey = g_strdup(key); + g_hash_table_insert(priv->properties, newkey, g_strdup(data)); + g_signal_emit(indicator, signals[MODIFIED], 0, newkey, TRUE); + } + return; } @@ -222,16 +263,19 @@ get_property (IndicateIndicator * indicator, const gchar * key) return indicate_indicator_get_indicator_type(indicator); } + IndicateIndicatorPrivate * priv = INDICATE_INDICATOR_GET_PRIVATE(indicator); + // TODO: Think about whether we should be strdup'ing this. Seems like overkill, but might not be. - return (const gchar *)g_hash_table_lookup(indicator->properties, key); + return (const gchar *)g_hash_table_lookup(priv->properties, key); } static GPtrArray * list_properties (IndicateIndicator * indicator) { g_return_val_if_fail(INDICATE_IS_INDICATOR(indicator), g_ptr_array_new()); + IndicateIndicatorPrivate * priv = INDICATE_INDICATOR_GET_PRIVATE(indicator); - GList * keys = g_hash_table_get_keys(indicator->properties); + GList * keys = g_hash_table_get_keys(priv->properties); GPtrArray * properties = g_ptr_array_sized_new(g_list_length(keys) + 1); g_ptr_array_add(properties, g_strdup("type")); diff --git a/libindicate/indicator.h b/libindicate/indicator.h index 91f08a7..8823757 100644 --- a/libindicate/indicator.h +++ b/libindicate/indicator.h @@ -21,19 +21,13 @@ G_BEGIN_DECLS #define INDICATE_INDICATOR_SIGNAL_HIDE "hide" #define INDICATE_INDICATOR_SIGNAL_SHOW "show" #define INDICATE_INDICATOR_SIGNAL_DISPLAY "user-display" +#define INDICATE_INDICATOR_SIGNAL_MODIFIED "modified" typedef struct _IndicateIndicator IndicateIndicator; typedef struct _IndicateIndicatorClass IndicateIndicatorClass; -#include "server.h" - struct _IndicateIndicator { GObject parent; - - guint id; - gboolean is_visible; - IndicateServer * server; - GHashTable * properties; }; struct _IndicateIndicatorClass { @@ -42,6 +36,7 @@ struct _IndicateIndicatorClass { void (*hide) (IndicateIndicator * indicator, gpointer data); void (*show) (IndicateIndicator * indicator, gpointer data); void (*user_display) (IndicateIndicator * indicator, gpointer data); + void (*modified) (IndicateIndicator * indicator, gchar * property, gpointer data); const gchar * (*get_type) (IndicateIndicator * indicator); void (*set_property) (IndicateIndicator * indicator, const gchar * key, const gchar * data); diff --git a/libindicate/listener.c b/libindicate/listener.c index 7510c49..31fdf4b 100644 --- a/libindicate/listener.c +++ b/libindicate/listener.c @@ -21,6 +21,25 @@ enum { static guint signals[LAST_SIGNAL] = { 0 }; +typedef struct _IndicateListenerPrivate IndicateListenerPrivate; +struct _IndicateListenerPrivate +{ + DBusGConnection * session_bus; + DBusGConnection * system_bus; + + DBusGProxy * dbus_proxy_session; + DBusGProxy * dbus_proxy_system; + + GHashTable * proxies_working; + GHashTable * proxies_possible; + + GArray * proxy_todo; + guint todo_idle; +}; + +#define INDICATE_LISTENER_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((o), INDICATE_TYPE_LISTENER, IndicateListenerPrivate)) + typedef struct { DBusGProxy * proxy; gchar * name; @@ -57,37 +76,39 @@ indicate_listener_class_init (IndicateListenerClass * class) GObjectClass * gobj; gobj = G_OBJECT_CLASS(class); + g_type_class_add_private (class, sizeof (IndicateListenerPrivate)); + gobj->finalize = indicate_listener_finalize; - signals[INDICATOR_ADDED] = g_signal_new("indicator-added", + signals[INDICATOR_ADDED] = g_signal_new(INDICATE_LISTENER_SIGNAL_INDICATOR_ADDED, G_TYPE_FROM_CLASS (class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (IndicateListenerClass, indicator_added), NULL, NULL, 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("indicator-removed", + 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, G_TYPE_NONE, 3, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_STRING); - signals[INDICATOR_MODIFIED] = g_signal_new("indicator-modified", + 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, G_TYPE_NONE, 4, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_STRING, G_TYPE_STRING); - signals[SERVER_ADDED] = g_signal_new("server-added", + 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, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); - signals[SERVER_REMOVED] = g_signal_new("server-removed", + 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), @@ -108,17 +129,18 @@ static void indicate_listener_init (IndicateListener * listener) { /* g_debug("Listener Object Initialized"); */ + IndicateListenerPrivate * priv = INDICATE_LISTENER_GET_PRIVATE(listener); GError *error = NULL; /* Get the buses */ - listener->session_bus = dbus_g_bus_get(DBUS_BUS_SESSION, &error); + priv->session_bus = dbus_g_bus_get(DBUS_BUS_SESSION, &error); if (error != NULL) { g_error("Unable to get session bus: %s", error->message); g_error_free(error); return; } - listener->system_bus = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error); + priv->system_bus = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error); if (error != NULL) { g_error("Unable to get system bus: %s", error->message); g_error_free(error); @@ -126,7 +148,7 @@ indicate_listener_init (IndicateListener * listener) } /* Set up the DBUS service proxies */ - listener->dbus_proxy_session = dbus_g_proxy_new_for_name_owner (listener->session_bus, + priv->dbus_proxy_session = dbus_g_proxy_new_for_name_owner (priv->session_bus, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, @@ -137,7 +159,7 @@ indicate_listener_init (IndicateListener * listener) return; } - listener->dbus_proxy_system = dbus_g_proxy_new_for_name_owner (listener->system_bus, + priv->dbus_proxy_system = dbus_g_proxy_new_for_name_owner (priv->system_bus, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, @@ -149,32 +171,32 @@ indicate_listener_init (IndicateListener * listener) } /* Set up name change signals */ - dbus_g_proxy_add_signal(listener->dbus_proxy_session, "NameOwnerChanged", + dbus_g_proxy_add_signal(priv->dbus_proxy_session, "NameOwnerChanged", G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID); - dbus_g_proxy_connect_signal(listener->dbus_proxy_session, "NameOwnerChanged", + dbus_g_proxy_connect_signal(priv->dbus_proxy_session, "NameOwnerChanged", G_CALLBACK(dbus_owner_change), listener, NULL); - dbus_g_proxy_add_signal(listener->dbus_proxy_system, "NameOwnerChanged", + dbus_g_proxy_add_signal(priv->dbus_proxy_system, "NameOwnerChanged", G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID); - dbus_g_proxy_connect_signal(listener->dbus_proxy_system, "NameOwnerChanged", + dbus_g_proxy_connect_signal(priv->dbus_proxy_system, "NameOwnerChanged", G_CALLBACK(dbus_owner_change), listener, NULL); /* Initialize Data structures */ - listener->proxies_working = g_hash_table_new(g_str_hash, g_str_equal); - listener->proxies_possible = g_hash_table_new(g_str_hash, g_str_equal); + 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); /* TODO: Look at some common scenarios and find out how to make this sized */ - listener->proxy_todo = g_array_new(FALSE, TRUE, sizeof(proxy_todo_t)); - listener->todo_idle = 0; + priv->proxy_todo = g_array_new(FALSE, TRUE, sizeof(proxy_todo_t)); + priv->todo_idle = 0; /* WARNING */ /* Starting massive asynchronisity */ /* */ /* Build todo list */ - org_freedesktop_DBus_list_names_async (listener->dbus_proxy_session, build_todo_list_cb, listener); - org_freedesktop_DBus_list_names_async (listener->dbus_proxy_system, build_todo_list_cb, listener); + org_freedesktop_DBus_list_names_async (priv->dbus_proxy_session, build_todo_list_cb, listener); + org_freedesktop_DBus_list_names_async (priv->dbus_proxy_system, build_todo_list_cb, listener); return; } @@ -198,13 +220,15 @@ indicate_listener_new (void) static void dbus_owner_change (DBusGProxy * proxy, const gchar * name, const gchar * prev, const gchar * new, IndicateListener * listener) { + IndicateListenerPrivate * priv = INDICATE_LISTENER_GET_PRIVATE(listener); + DBusGConnection * bus; gchar * bus_name; - if (proxy == listener->dbus_proxy_system) { - bus = listener->system_bus; + if (proxy == priv->dbus_proxy_system) { + bus = priv->system_bus; bus_name = "system"; } else { - bus = listener->session_bus; + bus = priv->session_bus; bus_name = "session"; } @@ -215,14 +239,14 @@ dbus_owner_change (DBusGProxy * proxy, const gchar * name, const gchar * prev, c } if (new != NULL && new[0] == '\0') { proxy_t * proxyt; - proxyt = g_hash_table_lookup(listener->proxies_working, name); + proxyt = g_hash_table_lookup(priv->proxies_working, name); if (proxyt != NULL) { - g_hash_table_remove(listener->proxies_working, name); + g_hash_table_remove(priv->proxies_working, name); proxy_struct_destroy(proxyt); } - proxyt = g_hash_table_lookup(listener->proxies_possible, name); + proxyt = g_hash_table_lookup(priv->proxies_possible, name); if (proxyt != NULL) { - g_hash_table_remove(listener->proxies_possible, name); + g_hash_table_remove(priv->proxies_possible, name); proxy_struct_destroy(proxyt); } } @@ -292,13 +316,19 @@ build_todo_list_cb (DBusGProxy * proxy, char ** names, GError * error, void * da static void todo_list_add (const gchar * name, DBusGProxy * proxy, IndicateListener * listener) { + if (name == NULL || name[0] != ':') { + return; + } + + IndicateListenerPrivate * priv = INDICATE_LISTENER_GET_PRIVATE(listener); + DBusGConnection * bus; gchar * bus_name; - if (proxy == listener->dbus_proxy_system) { - bus = listener->system_bus; + if (proxy == priv->dbus_proxy_system) { + bus = priv->system_bus; bus_name = "system"; } else { - bus = listener->session_bus; + bus = priv->session_bus; bus_name = "session"; } /* g_debug ("Adding on %s bus: %s", bus_name, name); */ @@ -307,10 +337,10 @@ todo_list_add (const gchar * name, DBusGProxy * proxy, IndicateListener * listen todo.name = g_strdup(name); todo.bus = bus; - g_array_append_val(listener->proxy_todo, todo); + g_array_append_val(priv->proxy_todo, todo); - if (listener->todo_idle == 0) { - listener->todo_idle = g_idle_add(todo_idle, listener); + if (priv->todo_idle == 0) { + priv->todo_idle = g_idle_add(todo_idle, listener); } return; @@ -322,19 +352,20 @@ todo_idle (gpointer data) IndicateListener * listener = INDICATE_LISTENER(data); if (listener == NULL) { g_error("Listener got lost in todo_idle"); - listener->todo_idle = 0; return FALSE; } - if (listener->proxy_todo->len == 0) { + IndicateListenerPrivate * priv = INDICATE_LISTENER_GET_PRIVATE(listener); + + if (priv->proxy_todo->len == 0) { /* Basically if we have no todo, we need to stop running. This * is done this way to make the function error handling simpler * and results in an extra run */ - listener->todo_idle = 0; + priv->todo_idle = 0; return FALSE; } - proxy_todo_t * todo = &g_array_index(listener->proxy_todo, proxy_todo_t, listener->proxy_todo->len - 1); + 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); proxyt->name = todo->name; @@ -345,7 +376,7 @@ todo_idle (gpointer data) proxyt->listener = listener; proxyt->indicators = NULL; - listener->proxy_todo = g_array_remove_index(listener->proxy_todo, listener->proxy_todo->len - 1); + priv->proxy_todo = g_array_remove_index(priv->proxy_todo, priv->proxy_todo->len - 1); if (proxyt->proxy == NULL) { g_warning("Unable to create proxy for %s", proxyt->name); @@ -359,7 +390,7 @@ todo_idle (gpointer data) org_freedesktop_indicator_get_indicator_list_async(proxyt->proxy, proxy_get_indicator_list, proxyt); - g_hash_table_insert(listener->proxies_possible, proxyt->name, proxyt); + g_hash_table_insert(priv->proxies_possible, proxyt->name, proxyt); return TRUE; } @@ -416,8 +447,9 @@ proxy_indicator_added (DBusGProxy * proxy, guint id, const gchar * type, proxy_t proxyt->indicators = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, proxy_indicators_free); /* Elevate to working */ - g_hash_table_remove(proxyt->listener->proxies_possible, proxyt->name); - g_hash_table_insert(proxyt->listener->proxies_working, proxyt->name, proxyt); + 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); dbus_g_proxy_add_signal(proxyt->proxy, "IndicatorRemoved", G_TYPE_UINT, G_TYPE_STRING, G_TYPE_INVALID); @@ -472,26 +504,34 @@ proxy_indicator_removed (DBusGProxy * proxy, guint id, const gchar * type, proxy } static void -proxy_indicator_modified (DBusGProxy * proxy, guint id, const gchar * type, proxy_t * proxyt) +proxy_indicator_modified (DBusGProxy * proxy, guint id, const gchar * property, proxy_t * proxyt) { if (proxyt->indicators == NULL) { g_warning("Oddly we had an indicator modified from an interface that we didn't think had indicators."); return; } - // TODO: Search for the ID to discover the type - GHashTable * indicators = g_hash_table_lookup(proxyt->indicators, type); - if (indicators == NULL) { - g_warning("Can not modify indicator %d of type '%s' as there are no indicators of that type on %s.", id, type, proxyt->name); - return; + GList * keys = g_hash_table_get_keys(proxyt->indicators); + GList * inc = NULL; + gchar * type; + + for (inc = g_list_first(keys); inc != NULL; inc = g_list_next(inc)) { + type = (gchar *)inc->data; + + GHashTable * indicators = g_hash_table_lookup(proxyt->indicators, type); + if (indicators == NULL) continue; /* no indicators for this type? Odd, but not an error */ + + if (g_hash_table_lookup(indicators, (gpointer)id)) { + break; + } } - if (!g_hash_table_lookup(indicators, (gpointer)id)) { - g_warning("No indicator %d of type '%s' on '%s'.", id, type, proxyt->name); + if (inc == NULL) { + g_warning("Can not modify indicator %d with property '%s' as there are no indicators with that id on %s.", id, property, proxyt->name); return; } - g_signal_emit(proxyt->listener, signals[INDICATOR_MODIFIED], 0, proxyt->name, id, type, type, TRUE); + g_signal_emit(proxyt->listener, signals[INDICATOR_MODIFIED], 0, proxyt->name, id, type, property, TRUE); return; } @@ -542,8 +582,9 @@ void indicate_listener_get_property (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gchar * property, indicate_listener_get_property_cb callback, gpointer data) { /* 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(listener->proxies_working, server); + 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; diff --git a/libindicate/listener.h b/libindicate/listener.h index 511cdd3..bc2332f 100644 --- a/libindicate/listener.h +++ b/libindicate/listener.h @@ -5,8 +5,6 @@ #include <glib.h> #include <glib-object.h> -#include <dbus/dbus-glib.h> - #include "indicator.h" #include "server.h" @@ -20,24 +18,21 @@ G_BEGIN_DECLS #define INDICATE_IS_LISTENER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), INDICATE_TYPE_LISTENER)) #define INDICATE_LISTENER_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS((object), INDICATE_TYPE_LISTENER, IndicateListenerClass)) +#define INDICATE_LISTENER_SIGNAL_INDICATOR_ADDED "indicator-added" +#define INDICATE_LISTENER_SIGNAL_INDICATOR_REMOVED "indicator-removed" +#define INDICATE_LISTENER_SIGNAL_INDICATOR_MODIFIED "indicator-modified" +#define INDICATE_LISTENER_SIGNAL_SERVER_ADDED "server-added" +#define INDICATE_LISTENER_SIGNAL_SERVER_REMOVED "server-removed" + +#define INDICATE_LISTENER_SERVER_DBUS_NAME(server) ((gchar *)server) +#define INDICATE_LISTENER_INDICATOR_ID(indicator) (GPOINTER_TO_UINT(indicator)) + typedef gchar IndicateListenerServer; typedef guint IndicateListenerIndicator; typedef struct _IndicateListener IndicateListener; struct _IndicateListener { GObject parent; - - DBusGConnection * session_bus; - DBusGConnection * system_bus; - - DBusGProxy * dbus_proxy_session; - DBusGProxy * dbus_proxy_system; - - GHashTable * proxies_working; - GHashTable * proxies_possible; - - GArray * proxy_todo; - guint todo_idle; }; typedef struct _IndicateListenerClass IndicateListenerClass; diff --git a/libindicate/server.c b/libindicate/server.c index 497debd..cd35871 100644 --- a/libindicate/server.c +++ b/libindicate/server.c @@ -27,6 +27,24 @@ enum { static guint signals[LAST_SIGNAL] = { 0 }; +/* Private area */ +typedef struct _IndicateServerPrivate IndicateServerPrivate; +struct _IndicateServerPrivate +{ + gchar * path; + GSList * indicators; + gboolean visible; + guint current_id; + + // TODO: Should have a more robust way to track this, but this'll work for now + guint num_hidden; +}; + +#define INDICATE_SERVER_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((o), INDICATE_TYPE_SERVER, IndicateServerPrivate)) + + +/* Define Type */ G_DEFINE_TYPE (IndicateServer, indicate_server, G_TYPE_OBJECT); /* Prototypes */ @@ -50,6 +68,8 @@ indicate_server_class_init (IndicateServerClass * class) GObjectClass * gobj; gobj = G_OBJECT_CLASS(class); + g_type_class_add_private (class, sizeof (IndicateServerPrivate)); + gobj->finalize = indicate_server_finalize; signals[INDICATOR_ADDED] = g_signal_new("indicator-added", @@ -96,11 +116,13 @@ indicate_server_init (IndicateServer * server) { g_debug("Server Object Initialized"); - server->path = g_strdup("/org/freedesktop/indicate"); - server->indicators = NULL; - server->num_hidden = 0; - server->visible = FALSE; - server->current_id = 0; + IndicateServerPrivate * priv = INDICATE_SERVER_GET_PRIVATE(server); + + priv->path = g_strdup("/org/freedesktop/indicate"); + priv->indicators = NULL; + priv->num_hidden = 0; + priv->visible = FALSE; + priv->current_id = 0; return; } @@ -109,9 +131,10 @@ static void indicate_server_finalize (GObject * obj) { IndicateServer * server = INDICATE_SERVER(obj); + IndicateServerPrivate * priv = INDICATE_SERVER_GET_PRIVATE(server); - if (server->path) { - g_free(server->path); + if (priv->path) { + g_free(priv->path); } return; @@ -132,8 +155,9 @@ void indicate_server_show (IndicateServer * server) { g_return_if_fail(INDICATE_IS_SERVER(server)); + IndicateServerPrivate * priv = INDICATE_SERVER_GET_PRIVATE(server); - if (server->visible) + if (priv->visible) return; DBusGConnection * connection; @@ -141,9 +165,9 @@ indicate_server_show (IndicateServer * server) connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL); dbus_g_connection_register_g_object(connection, - server->path, + priv->path, G_OBJECT(server)); - server->visible = TRUE; + priv->visible = TRUE; return; } @@ -151,14 +175,16 @@ indicate_server_show (IndicateServer * server) static guint get_next_id (IndicateServer * server) { - server->current_id++; - return server->current_id; + IndicateServerPrivate * priv = INDICATE_SERVER_GET_PRIVATE(server); + priv->current_id++; + return priv->current_id; } static void indicator_show_cb (IndicateIndicator * indicator, IndicateServer * server) { - server->num_hidden--; + IndicateServerPrivate * priv = INDICATE_SERVER_GET_PRIVATE(server); + priv->num_hidden--; g_signal_emit(server, signals[INDICATOR_ADDED], 0, indicate_indicator_get_id(indicator), indicate_indicator_get_indicator_type(indicator), TRUE); return; } @@ -166,25 +192,35 @@ indicator_show_cb (IndicateIndicator * indicator, IndicateServer * server) static void indicator_hide_cb (IndicateIndicator * indicator, IndicateServer * server) { - server->num_hidden++; + IndicateServerPrivate * priv = INDICATE_SERVER_GET_PRIVATE(server); + priv->num_hidden++; g_signal_emit(server, signals[INDICATOR_REMOVED], 0, indicate_indicator_get_id(indicator), indicate_indicator_get_indicator_type(indicator), TRUE); return; } +static void +indicator_modified_cb (IndicateIndicator * indicator, gchar * property, IndicateServer * server) +{ + g_signal_emit(server, signals[INDICATOR_MODIFIED], 0, indicate_indicator_get_id(indicator), property, TRUE); +} + void indicate_server_add_indicator (IndicateServer * server, IndicateIndicator * indicator) { + IndicateServerPrivate * priv = INDICATE_SERVER_GET_PRIVATE(server); + g_object_ref(indicator); - server->indicators = g_slist_prepend(server->indicators, indicator); + priv->indicators = g_slist_prepend(priv->indicators, indicator); if (!indicate_indicator_is_visible(indicator)) { - server->num_hidden++; + priv->num_hidden++; } else { g_signal_emit(server, signals[INDICATOR_ADDED], 0, indicate_indicator_get_id(indicator), indicate_indicator_get_indicator_type(indicator), TRUE); } g_signal_connect(indicator, INDICATE_INDICATOR_SIGNAL_SHOW, G_CALLBACK(indicator_show_cb), server); g_signal_connect(indicator, INDICATE_INDICATOR_SIGNAL_HIDE, G_CALLBACK(indicator_hide_cb), server); + g_signal_connect(indicator, INDICATE_INDICATOR_SIGNAL_MODIFIED, G_CALLBACK(indicator_modified_cb), server); return; } @@ -192,15 +228,18 @@ indicate_server_add_indicator (IndicateServer * server, IndicateIndicator * indi void indicate_server_remove_indicator (IndicateServer * server, IndicateIndicator * indicator) { - server->indicators = g_slist_remove(server->indicators, indicator); + IndicateServerPrivate * priv = INDICATE_SERVER_GET_PRIVATE(server); + + priv->indicators = g_slist_remove(priv->indicators, indicator); if (indicate_indicator_is_visible(indicator)) { g_signal_emit(server, signals[INDICATOR_REMOVED], 0, indicate_indicator_get_id(indicator), indicate_indicator_get_indicator_type(indicator), TRUE); } else { - server->num_hidden--; + priv->num_hidden--; } g_signal_handlers_disconnect_by_func(indicator, indicator_show_cb, server); g_signal_handlers_disconnect_by_func(indicator, indicator_hide_cb, server); + g_signal_handlers_disconnect_by_func(indicator, indicator_modified_cb, server); g_object_unref(indicator); return; @@ -241,9 +280,11 @@ indicate_server_set_default (IndicateServer * server) static gboolean get_desktop (IndicateServer * server, gchar ** desktop_path, GError **error) { - if (server->path != NULL) { + IndicateServerPrivate * priv = INDICATE_SERVER_GET_PRIVATE(server); + + if (priv->path != NULL) { // TODO: This might be a memory leak, check into that. - *desktop_path = g_strdup(server->path); + *desktop_path = g_strdup(priv->path); } return TRUE; } @@ -251,11 +292,13 @@ get_desktop (IndicateServer * server, gchar ** desktop_path, GError **error) static gboolean get_indicator_count (IndicateServer * server, guint * count, GError **error) { - guint lstcnt = g_slist_length(server->indicators); + IndicateServerPrivate * priv = INDICATE_SERVER_GET_PRIVATE(server); - g_return_val_if_fail(server->num_hidden < lstcnt, TRUE); + guint lstcnt = g_slist_length(priv->indicators); + + g_return_val_if_fail(priv->num_hidden < lstcnt, TRUE); - *count = lstcnt - server->num_hidden; + *count = lstcnt - priv->num_hidden; return TRUE; } @@ -300,7 +343,9 @@ get_indicator_count_by_type (IndicateServer * server, gchar * type, guint * coun cbt.type = NULL; } - g_slist_foreach(server->indicators, (GFunc)count_by_type, &cbt); + IndicateServerPrivate * priv = INDICATE_SERVER_GET_PRIVATE(server); + + g_slist_foreach(priv->indicators, (GFunc)count_by_type, &cbt); *count = cbt.count; return TRUE; @@ -314,11 +359,13 @@ get_indicator_list (IndicateServer * server, GArray ** indicators, GError ** err IndicateServerClass * class = INDICATE_SERVER_GET_CLASS(server); g_return_val_if_fail(class->get_indicator_count != NULL, TRUE); - *indicators = g_array_sized_new(FALSE, FALSE, sizeof(guint), g_slist_length(server->indicators) - server->num_hidden); + IndicateServerPrivate * priv = INDICATE_SERVER_GET_PRIVATE(server); + + *indicators = g_array_sized_new(FALSE, FALSE, sizeof(guint), g_slist_length(priv->indicators) - priv->num_hidden); GSList * iter; int i; - for (iter = server->indicators, i = 0; iter != NULL; iter = iter->next, i++) { + for (iter = priv->indicators, i = 0; iter != NULL; iter = iter->next, i++) { IndicateIndicator * indicator = INDICATE_INDICATOR(iter->data); if (indicate_indicator_is_visible(indicator)) { guint id = indicate_indicator_get_id(indicator); @@ -341,13 +388,15 @@ get_indicator_list_by_type (IndicateServer * server, gchar * type, guint ** indi type = NULL; } + IndicateServerPrivate * priv = INDICATE_SERVER_GET_PRIVATE(server); + /* Can't be larger than this and it's not worth the reallocation for the small number we have. The memory isn't worth the time. */ - *indicators = g_array_sized_new(FALSE, FALSE, sizeof(guint), g_slist_length(server->indicators) - server->num_hidden); + *indicators = g_array_sized_new(FALSE, FALSE, sizeof(guint), g_slist_length(priv->indicators) - priv->num_hidden); GSList * iter; int i; - for (iter = server->indicators, i = 0; iter != NULL; iter = iter->next) { + for (iter = priv->indicators, i = 0; iter != NULL; iter = iter->next) { IndicateIndicator * indicator = INDICATE_INDICATOR(iter->data); if (indicate_indicator_is_visible(indicator)) { const gchar * itype = indicate_indicator_get_indicator_type(indicator); @@ -369,9 +418,10 @@ static IndicateIndicator * get_indicator (IndicateServer * server, guint id, GError **error) { g_return_val_if_fail(INDICATE_IS_SERVER(server), NULL); + IndicateServerPrivate * priv = INDICATE_SERVER_GET_PRIVATE(server); GSList * iter; - for (iter = server->indicators; iter != NULL; iter = iter->next) { + for (iter = priv->indicators; iter != NULL; iter = iter->next) { IndicateIndicator * indicator = INDICATE_INDICATOR(iter->data); if (indicate_indicator_get_id(indicator) == id) { return indicator; diff --git a/libindicate/server.h b/libindicate/server.h index bc4522d..482fb9a 100644 --- a/libindicate/server.h +++ b/libindicate/server.h @@ -5,6 +5,8 @@ #include <glib.h> #include <glib-object.h> +#include "indicator.h" + G_BEGIN_DECLS /* Boilerplate */ @@ -16,19 +18,8 @@ G_BEGIN_DECLS #define INDICATE_SERVER_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS((object), INDICATE_TYPE_SERVER, IndicateServerClass)) typedef struct _IndicateServer IndicateServer; - -#include "indicator.h" - struct _IndicateServer { GObject parent; - - gchar * path; - GSList * indicators; - gboolean visible; - guint current_id; - - // TODO: Should have a more robust way to track this, but this'll work for now - guint num_hidden; }; typedef struct _IndicateServerClass IndicateServerClass; diff --git a/tests/im-client.c b/tests/im-client.c index cdf3484..43635f0 100644 --- a/tests/im-client.c +++ b/tests/im-client.c @@ -13,7 +13,9 @@ main (int argc, char ** argv) indicate_indicator_set_property(INDICATE_INDICATOR(indicator), "subtype", "im"); indicate_indicator_set_property(INDICATE_INDICATOR(indicator), "sender", "Ted Gould"); indicate_indicator_set_property(INDICATE_INDICATOR(indicator), "time", "11:11"); - indicate_indicator_show(indicator); + indicate_indicator_show(INDICATE_INDICATOR(indicator)); + + indicate_indicator_set_property(INDICATE_INDICATOR(indicator), "time", "11:12"); g_main_loop_run(g_main_loop_new(NULL, FALSE)); diff --git a/tests/listen-and-print.c b/tests/listen-and-print.c index 9ad2cc8..b12fd3d 100644 --- a/tests/listen-and-print.c +++ b/tests/listen-and-print.c @@ -5,31 +5,31 @@ static void indicator_added (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gchar * type, gpointer data) { - g_debug("Indicator Added: %s %d %s", (gchar *)server, (guint)indicator, type); + g_debug("Indicator Added: %s %d %s", INDICATE_LISTENER_SERVER_DBUS_NAME(server), INDICATE_LISTENER_INDICATOR_ID(indicator), type); } static void indicator_removed (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gchar * type, gpointer data) { - g_debug("Indicator Removed: %s %d %s", (gchar *)server, (guint)indicator, type); + g_debug("Indicator Removed: %s %d %s", INDICATE_LISTENER_SERVER_DBUS_NAME(server), INDICATE_LISTENER_INDICATOR_ID(indicator), type); } static void indicator_modified (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gchar * type, gchar * property, gpointer data) { - g_debug("Indicator Modified: %s %d %s %s", (gchar *)server, (guint)indicator, type, property); + g_debug("Indicator Modified: %s %d %s %s", INDICATE_LISTENER_SERVER_DBUS_NAME(server), INDICATE_LISTENER_INDICATOR_ID(indicator), type, property); } static void server_added (IndicateListener * listener, IndicateListenerServer * server, gpointer data) { - g_debug("Indicator Server Added: %s", (gchar *)server); + g_debug("Indicator Server Added: %s", INDICATE_LISTENER_SERVER_DBUS_NAME(server)); } static void server_removed (IndicateListener * listener, IndicateListenerServer * server, gpointer data) { - g_debug("Indicator Server Removed: %s", (gchar *)server); + g_debug("Indicator Server Removed: %s", INDICATE_LISTENER_SERVER_DBUS_NAME(server)); } int @@ -39,11 +39,11 @@ main (int argc, char ** argv) IndicateListener * listener = indicate_listener_new(); - g_signal_connect(listener, "indicator-added", G_CALLBACK(indicator_added), NULL); - g_signal_connect(listener, "indicator-removed", G_CALLBACK(indicator_removed), NULL); - g_signal_connect(listener, "indicator-modified", G_CALLBACK(indicator_modified), NULL); - g_signal_connect(listener, "server-added", G_CALLBACK(server_added), NULL); - g_signal_connect(listener, "server-removed", G_CALLBACK(server_removed), NULL); + g_signal_connect(listener, INDICATE_LISTENER_SIGNAL_INDICATOR_ADDED, G_CALLBACK(indicator_added), NULL); + g_signal_connect(listener, INDICATE_LISTENER_SIGNAL_INDICATOR_REMOVED, G_CALLBACK(indicator_removed), NULL); + g_signal_connect(listener, INDICATE_LISTENER_SIGNAL_INDICATOR_MODIFIED, G_CALLBACK(indicator_modified), NULL); + g_signal_connect(listener, INDICATE_LISTENER_SIGNAL_SERVER_ADDED, G_CALLBACK(server_added), NULL); + g_signal_connect(listener, INDICATE_LISTENER_SIGNAL_SERVER_REMOVED, G_CALLBACK(server_removed), NULL); g_main_loop_run(g_main_loop_new(NULL, FALSE)); |