ayatana-commits team mailing list archive
-
ayatana-commits team
-
Mailing list archive
-
Message #00799
[Merge] lp:~ted/libindicate/discovery-and-love into lp:libindicate
Ted Gould has proposed merging lp:~ted/libindicate/discovery-and-love into lp:libindicate.
Requested reviews:
Indicator Applet Developers (indicator-applet-developers)
This merge removes all of the introspection of people coming on the bus.
Instead it sets up a signal when new listeners come on the bus and has
all servers respond with a show signal when they hear it. Much, much
cleaner.
--
https://code.launchpad.net/~ted/libindicate/discovery-and-love/+merge/18503
Your team ayatana-commits is subscribed to branch lp:libindicate.
=== modified file 'configure.ac'
--- configure.ac 2010-02-02 08:15:17 +0000
+++ configure.ac 2010-02-03 05:46:11 +0000
@@ -52,14 +52,21 @@
DBUS_REQUIRED_VERSION=0.76
GLIB_REQUIRED_VERSION=2.18
GIO_REQUIRED_VERSION=2.18
+<<<<<<< TREE
XML_REQUIRED_VERSION=2.6
DBUSMENU_REQUIRED_VERSION=0.2.0
+=======
+>>>>>>> MERGE-SOURCE
PKG_CHECK_MODULES(LIBINDICATE, glib-2.0 >= $GLIB_REQUIRED_VERSION
gio-2.0 >= $GIO_REQUIRED_VERSION
+<<<<<<< TREE
dbus-glib-1 >= $DBUS_REQUIRED_VERSION
dbusmenu-glib >= $DBUSMENU_REQUIRED_VERSION
libxml-2.0 >= $XML_REQUIRED_VERSION)
+=======
+ dbus-glib-1 >= $DBUS_REQUIRED_VERSION)
+>>>>>>> MERGE-SOURCE
AC_SUBST(LIBINDICATE_CFLAGS)
AC_SUBST(LIBINDICATE_LIBS)
=== modified file 'libindicate/indicate-listener.xml'
--- libindicate/indicate-listener.xml 2009-02-23 04:59:44 +0000
+++ libindicate/indicate-listener.xml 2010-02-03 05:46:11 +0000
@@ -35,6 +35,10 @@
<arg type="as" name="server_ids" direction="out" />
</method>
+<!-- Signals -->
+ <signal name="IndicatorServersReport">
+ </signal>
+
<!-- End of interesting stuff -->
</interface>
=== modified file 'libindicate/listener-private.h'
--- libindicate/listener-private.h 2009-08-28 21:59:26 +0000
+++ libindicate/listener-private.h 2010-02-03 05:46:11 +0000
@@ -48,11 +48,7 @@
DBusGConnection * session_bus;
DBusGConnection * system_bus;
- DBusGProxy * dbus_proxy_session;
- DBusGProxy * dbus_proxy_system;
-
- GList * proxies_working;
- GList * proxies_possible;
+ GList * proxies;
GArray * proxy_todo;
guint todo_idle;
=== modified file 'libindicate/listener.c'
--- libindicate/listener.c 2010-02-01 06:13:31 +0000
+++ libindicate/listener.c 2010-02-03 05:46:11 +0000
@@ -27,12 +27,11 @@
<http://www.gnu.org/licenses/>
*/
-#include <libxml/parser.h>
-#include <libxml/tree.h>
-
+#include <stdlib.h>
#include "listener.h"
#include "listener-marshal.h"
#include <dbus/dbus-glib-bindings.h>
+#include <dbus/dbus-glib-lowlevel.h>
#include "dbus-indicate-client.h"
#include "dbus-listener-client.h"
#include "interests-priv.h"
@@ -50,6 +49,7 @@
SERVER_ADDED,
SERVER_REMOVED,
SERVER_COUNT_CHANGED,
+ INDICATOR_SERVERS_REPORT,
LAST_SIGNAL
};
@@ -62,10 +62,12 @@
DBusGProxy * property_proxy;
DBusGConnection * connection;
gchar * name;
+ gchar * path;
gchar * type;
IndicateListener * listener;
GHashTable * indicators;
guint introspect_level;
+ gboolean hidden;
IndicateListenerServer server;
} proxy_t;
@@ -86,28 +88,27 @@
typedef struct {
DBusGConnection * bus;
gchar * name;
- gboolean startup;
+ gchar * path;
} proxy_todo_t;
G_DEFINE_TYPE (IndicateListener, indicate_listener, G_TYPE_OBJECT);
/* Prototypes */
static void indicate_listener_finalize (GObject * obj);
-static void dbus_owner_change (DBusGProxy * proxy, const gchar * name, const gchar * prev, const gchar * new, IndicateListener * listener);
+static DBusHandlerResult dbus_filter_show_server (DBusConnection * connection, DBusMessage * message, void * user_data);
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 void todo_list_add (const gchar * name, const gchar * path, IndicateListener * listener);
static gboolean todo_idle (gpointer data);
+void set_max_indicators_cb (DBusGProxy * proxy, GError * error, gpointer userdata);
+static void get_type_initial_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_indicator_added_legacy (DBusGProxy * proxy, guint id, gchar * type, proxy_t * proxyt);
-static void proxy_server_added (DBusGProxy * proxy, const gchar * type, proxy_t * proxyt);
static void proxy_indicator_added (DBusGProxy * proxy, guint id, proxy_t * proxyt);
static void proxy_indicator_removed_legacy (DBusGProxy * proxy, guint id, gchar * type, proxy_t * proxyt);
static void proxy_indicator_removed (DBusGProxy * proxy, guint id, proxy_t * proxyt);
static void proxy_indicator_modified (DBusGProxy * proxy, guint id, const gchar * property, proxy_t * proxyt);
static void proxy_server_count_changed (DBusGProxy * proxy, guint count, proxy_t * proxyt);
static void proxy_get_indicator_list (DBusGProxy * proxy, GArray * indicators, GError * error, gpointer data);
-static void introspect_this (DBusGProxy * proxy, char * OUT_data, GError * error, gpointer data);
/* DBus interface */
gboolean _indicate_listener_get_indicator_servers (IndicateListener * listener, GList * servers);
@@ -169,6 +170,13 @@
NULL, NULL,
_indicate_listener_marshal_VOID__POINTER_UINT,
G_TYPE_NONE, 2, INDICATE_TYPE_LISTENER_SERVER, G_TYPE_UINT);
+ signals[INDICATOR_SERVERS_REPORT] = g_signal_new("indicator-servers-report",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (IndicateListenerClass, indicator_servers_report),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0, G_TYPE_NONE);
dbus_g_object_register_marshaller(_indicate_listener_marshal_VOID__UINT_STRING,
G_TYPE_NONE,
@@ -176,6 +184,9 @@
G_TYPE_STRING,
G_TYPE_INVALID);
+ dbus_g_object_type_install_info(INDICATE_TYPE_LISTENER,
+ &dbus_glib__indicate_listener_object_info);
+
return;
}
@@ -194,28 +205,8 @@
return;
}
- /* Set up the DBUS service proxies */
- priv->dbus_proxy_session = dbus_g_proxy_new_for_name_owner (priv->session_bus,
- DBUS_SERVICE_DBUS,
- DBUS_PATH_DBUS,
- DBUS_INTERFACE_DBUS,
- &error);
- if (error != NULL) {
- g_error("Unable to get dbus proxy on session bus: %s", error->message);
- g_error_free(error);
- return;
- }
-
- /* Set up name change signals */
- 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(priv->dbus_proxy_session, "NameOwnerChanged",
- G_CALLBACK(dbus_owner_change), listener, NULL);
-
/* Initialize Data structures */
- priv->proxies_working = NULL;
- priv->proxies_possible = NULL;
+ priv->proxies = 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));
@@ -227,8 +218,15 @@
/* Starting massive asynchronisity */
/* */
- /* Build todo list */
- org_freedesktop_DBus_list_names_async (priv->dbus_proxy_session, build_todo_list_cb, listener);
+ dbus_connection_add_filter(dbus_g_connection_get_connection(priv->session_bus), dbus_filter_show_server, listener, NULL);
+ dbus_bus_add_match(dbus_g_connection_get_connection(priv->session_bus), "type='signal',interface='org.freedesktop.indicator',member='ServerShow'", NULL);
+
+ dbus_g_connection_register_g_object(priv->session_bus,
+ "/org/freedesktop/indicator/listener",
+// dbus_bus_get_unique_name(dbus_g_connection_get_connection(priv->session_bus)),
+ G_OBJECT(listener));
+
+ g_signal_emit(G_OBJECT(listener), signals[INDICATOR_SERVERS_REPORT], 0, TRUE);
return;
}
@@ -239,32 +237,27 @@
IndicateListener * listener = INDICATE_LISTENER(obj);
IndicateListenerPrivate * priv = INDICATE_LISTENER_GET_PRIVATE(listener);
- dbus_g_proxy_disconnect_signal(priv->dbus_proxy_session, "NameOwnerChanged",
- G_CALLBACK(dbus_owner_change), listener);
- dbus_g_proxy_disconnect_signal(priv->dbus_proxy_system, "NameOwnerChanged",
- G_CALLBACK(dbus_owner_change), listener);
-
if (priv->todo_idle != 0) {
g_idle_remove_by_data(obj);
}
/* Hack: proxy_struct_destroy() lacks a user_data parameter, but since the
* caller is responsible for handling params on the stack, it works
*/
- g_list_foreach(priv->proxies_possible, (GFunc)proxy_struct_destroy, NULL);
- g_list_free(priv->proxies_possible);
- g_list_foreach(priv->proxies_working, (GFunc)proxy_struct_destroy, NULL);
- g_list_free(priv->proxies_working);
-
- g_object_unref(priv->dbus_proxy_session);
- g_object_unref(priv->dbus_proxy_system);
-
- dbus_g_connection_unref(priv->session_bus);
- dbus_g_connection_unref(priv->system_bus);
+ g_list_foreach(priv->proxies, (GFunc)proxy_struct_destroy, NULL);
+ g_list_free(priv->proxies);
G_OBJECT_CLASS (indicate_listener_parent_class)->finalize (obj);
return;
}
+/**
+ indicate_listener_new:
+
+ Creates a new Listener object. Does not set this to the default
+ listener object.
+
+ Return value: A new listener object.
+*/
IndicateListener *
indicate_listener_new (void)
{
@@ -273,8 +266,22 @@
return listener;
}
+/* The pointer to the default listener object */
static IndicateListener * default_indicate_listener = NULL;
+/**
+ indcate_listener_ref_default:
+
+ Looks for the default listener, and if it doesn't exist it'll
+ allocate a new one and mark it the default. This is what most
+ programs should use rather than #indicate_listener_new because
+ it is rare that anyone would need more than a single listener.
+ This function does increase the ref count on the object so anyone
+ calling it should unref thier instance of the default listener.
+
+ Return value: The default instance of #IndicateListener for the
+ program.
+*/
IndicateListener *
indicate_listener_ref_default (void)
{
@@ -289,43 +296,26 @@
return default_indicate_listener;
}
-/* Function to track when people get on and off the bus. */
-static void
-dbus_owner_change (DBusGProxy * proxy, const gchar * name, const gchar * prev, const gchar * new, IndicateListener * listener)
+/* A small filter function that notices when someone sends
+ a ServerShow signal and creates an entry for us to investigate
+ them more in an idle loop lookup. */
+static DBusHandlerResult
+dbus_filter_show_server (DBusConnection * connection, DBusMessage * message, void * user_data)
{
- g_return_if_fail(INDICATE_IS_LISTENER(listener));
- IndicateListenerPrivate * priv = INDICATE_LISTENER_GET_PRIVATE(listener);
-
- /* If someone is getting on the bus we add them to the
- todo list to see if they come up with something interesting */
- if (prev != NULL && prev[0] == '\0') {
- todo_list_add(name, proxy, listener, FALSE);
- }
-
- /* If they're leaving the bus we need to figure out if we
- were tracking them or not, and remove them from the
- appropriate lists. */
- if (new != NULL && new[0] == '\0') {
- proxy_t searchitem;
- searchitem.connection = priv->session_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_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);
- }
- }
-
- return;
+ if (!dbus_message_is_signal(message, "org.freedesktop.indicator", "ServerShow")) {
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
+
+ const char * sender = dbus_message_get_sender(message);
+ const char * path = dbus_message_get_path(message);
+
+ todo_list_add(sender, path, INDICATE_LISTENER(user_data));
+
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
+/* A hashtable for each function to look at all of the indicators
+ on a proxy_t object and signal their destruction */
static void
proxy_struct_destroy_indicators (gpointer key, gpointer value, gpointer data)
{
@@ -337,12 +327,13 @@
return;
}
+/* Cleans up a proxy_t struct after allocation. It signals that
+ all of the indicators are going away and the server itself. */
static void
proxy_struct_destroy (gpointer data)
{
proxy_t * proxy_data = data;
- /* TODO: Clear the indicators by signaling */
if (proxy_data->indicators != NULL) {
g_hash_table_foreach(proxy_data->indicators,
proxy_struct_destroy_indicators,
@@ -361,7 +352,14 @@
g_object_unref(G_OBJECT(proxy_data->proxy));
}
- g_free(proxy_data->name);
+ if (proxy_data->name != NULL) {
+ g_free(proxy_data->name);
+ }
+
+ if (proxy_data->path != NULL) {
+ g_free(proxy_data->path);
+ }
+
if (proxy_data->type != NULL) {
g_free(proxy_data->type);
}
@@ -370,26 +368,11 @@
return;
}
-static void
-build_todo_list_cb (DBusGProxy * proxy, char ** names, GError * error, void * data)
-{
- IndicateListener * listener = INDICATE_LISTENER(data);
-
- if (error != NULL) {
- g_warning("Unable to get names: %s", error->message);
- return;
- }
-
- guint i = 0;
- for (i = 0; names[i] != NULL; i++) {
- todo_list_add(names[i], proxy, listener, TRUE);
- }
-
- return;
-}
-
-static void
-todo_list_add (const gchar * name, DBusGProxy * proxy, IndicateListener * listener, gboolean startup)
+/* Creates a todo list item for the particular server and
+ path as they've signaled that they're on DBus and like
+ talking about indicators. */
+static void
+todo_list_add (const gchar * name, const gchar * path, IndicateListener * listener)
{
if (name == NULL || name[0] != ':') {
return;
@@ -399,8 +382,8 @@
proxy_todo_t todo;
todo.name = g_strdup(name);
+ todo.path = g_strdup(path);
todo.bus = priv->session_bus;
- todo.startup = startup;
g_array_append_val(priv->proxy_todo, todo);
@@ -431,44 +414,131 @@
}
proxy_todo_t * todo = &g_array_index(priv->proxy_todo, proxy_todo_t, priv->proxy_todo->len - 1);
+ /* Remove the todo list */
+ priv->proxy_todo = g_array_remove_index(priv->proxy_todo, priv->proxy_todo->len - 1);
+
+ /* Check to see if we already have this item, if so,
+ we assume that it's signal handler will handle the
+ ServerShow signal. We're just going to exit this
+ function. */
+ if (TRUE) {
+ proxy_t searchitem;
+ searchitem.name = todo->name;
+ searchitem.connection = todo->bus;
+
+ GList * proxyitem = g_list_find_custom(priv->proxies, &searchitem, proxy_t_equal);
+ if (proxyitem != NULL) {
+ g_free(todo->name);
+ g_free(todo->path);
+ g_free(todo);
+ return TRUE;
+ }
+ }
proxy_t * proxyt = g_new0(proxy_t, 1);
proxyt->name = todo->name;
+ proxyt->path = todo->path;
proxyt->type = NULL;
- proxyt->proxy = dbus_g_proxy_new_for_name(todo->bus,
- proxyt->name,
- "/org/freedesktop/indicate",
- "org.freedesktop.indicator");
proxyt->property_proxy = NULL;
+ proxyt->proxy = NULL;
proxyt->listener = listener;
proxyt->indicators = NULL;
+ proxyt->hidden = FALSE;
proxyt->connection = todo->bus;
proxyt->server.name = todo->name;
- proxyt->server.proxy = proxyt->proxy;
+ proxyt->server.proxy = NULL;
proxyt->server.connection = proxyt->connection;
proxyt->server.max_indicators = priv->max_indicators;
- priv->proxy_todo = g_array_remove_index(priv->proxy_todo, priv->proxy_todo->len - 1);
-
- if (proxyt->proxy == NULL) {
+ /* Build the indicators hash */
+ proxyt->indicators = g_hash_table_new(g_direct_hash, g_direct_equal);
+
+ /* Build the proxy and ensure that it gets created. If
+ it gets created we're all happy. */
+ GError * error = NULL;
+ proxyt->proxy = dbus_g_proxy_new_for_name_owner(todo->bus,
+ proxyt->name,
+ todo->path,
+ "org.freedesktop.indicator",
+ &error);
+
+ g_free(todo);
+
+ if (error != NULL) {
g_warning("Unable to create proxy for %s", proxyt->name);
+ g_error_free(error);
return TRUE;
}
- dbus_g_proxy_add_signal(proxyt->proxy, "ServerShow",
- G_TYPE_STRING, G_TYPE_INVALID);
- dbus_g_proxy_connect_signal(proxyt->proxy, "ServerShow",
- G_CALLBACK(proxy_server_added), proxyt, NULL);
-
- priv->proxies_possible = g_list_prepend(priv->proxies_possible, proxyt);
-
- /* Look through the introspection data to see if this
- is already a server */
- introspect_this (NULL, NULL, NULL, proxyt);
+ /* Making sure the server has the proxy as well */
+ proxyt->server.proxy = proxyt->proxy;
+
+ /* Adding into the list of proxies */
+ priv->proxies = g_list_prepend(priv->proxies, proxyt);
+
+ /* Setup all the signals that we need off of this
+ proxy. Lot's of fun signals. */
+ dbus_g_proxy_add_signal(proxyt->proxy, "IndicatorAdded",
+ G_TYPE_UINT, G_TYPE_STRING, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal(proxyt->proxy, "IndicatorAdded",
+ G_CALLBACK(proxy_indicator_added_legacy), proxyt, NULL);
+ dbus_g_proxy_add_signal(proxyt->proxy, "IndicatorNew",
+ G_TYPE_UINT, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal(proxyt->proxy, "IndicatorNew",
+ G_CALLBACK(proxy_indicator_added), proxyt, NULL);
+ dbus_g_proxy_add_signal(proxyt->proxy, "IndicatorRemoved",
+ G_TYPE_UINT, G_TYPE_STRING, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal(proxyt->proxy, "IndicatorRemoved",
+ G_CALLBACK(proxy_indicator_removed_legacy), proxyt, NULL);
+ dbus_g_proxy_add_signal(proxyt->proxy, "IndicatorDelete",
+ G_TYPE_UINT, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal(proxyt->proxy, "IndicatorDelete",
+ G_CALLBACK(proxy_indicator_removed), proxyt, NULL);
+ dbus_g_proxy_add_signal(proxyt->proxy, "IndicatorModified",
+ G_TYPE_UINT, G_TYPE_STRING, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal(proxyt->proxy, "IndicatorModified",
+ G_CALLBACK(proxy_indicator_modified), proxyt, NULL);
+ dbus_g_proxy_add_signal(proxyt->proxy, "ServerCountChanged",
+ G_TYPE_UINT, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal(proxyt->proxy, "ServerCountChanged",
+ G_CALLBACK(proxy_server_count_changed), proxyt, NULL);
+
+ /* We're setting the max number of indicators from the default
+ when we detect it. This should give a reasonable amount of
+ time for listeners to set the default if they want something
+ different from infinite. Otherwise it'd be easy to miss the
+ first couple. */
+ proxyt->server.max_indicators = priv->max_indicators;
+ if (proxyt->server.max_indicators != -1) {
+ org_freedesktop_indicator_set_max_indicators_async(proxyt->proxy, proxyt->server.max_indicators, set_max_indicators_cb, proxyt->name);
+ }
+
+ indicate_listener_server_get_type(proxyt->listener, &proxyt->server, get_type_initial_cb, proxyt);
+ org_freedesktop_indicator_get_indicator_list_async(proxyt->proxy, proxy_get_indicator_list, proxyt);
return TRUE;
}
+/* A callback function for the getting the type when it is looked
+ at initially. So that we'll send a signal that the server has
+ been added so that everyone knows. */
+static void
+get_type_initial_cb (IndicateListener * listener, IndicateListenerServer * server, gchar * type, gpointer data)
+{
+ get_type_cb(listener, server, type, data);
+
+ proxy_t * proxyt = (proxy_t *)data;
+
+ if (!proxyt->hidden && proxyt->type != NULL) {
+ g_signal_emit(proxyt->listener, signals[SERVER_ADDED], 0, &proxyt->server, proxyt->type, TRUE);
+ }
+
+ return;
+}
+
+/* Callback from getting the type of the server. We're not using
+ this directly now, only through get_type_initial_cb right now
+ though we might use it more directly later. */
static void
get_type_cb (IndicateListener * listener, IndicateListenerServer * server, gchar * type, gpointer data)
{
@@ -480,8 +550,11 @@
proxy_t * proxyt = (proxy_t *)data;
- proxy_server_added (proxyt->proxy, type, proxyt);
- org_freedesktop_indicator_get_indicator_list_async(proxyt->proxy, proxy_get_indicator_list, proxyt);
+ if (proxyt->type != NULL) {
+ g_free(proxyt->type);
+ proxyt->type = NULL;
+ }
+ proxyt->type = g_strdup(type);
return;
}
@@ -519,85 +592,6 @@
return;
}
-/* Function called on the ServerShow signal from the bus, which is
- usually when a DBus client says that they have some indicators
- that we could be interested in. Also, this function is called
- in the discovery phase of starting up a new listener if we find
- some indicators on the client. */
-static void
-proxy_server_added (DBusGProxy * proxy, const gchar * type, proxy_t * proxyt)
-{
- g_debug("Proxy Server Added");
- /* Check to see if we have an indicators table. If we
- do this function's probably already been run. If not
- we need to trick this server out. */
- if (proxyt->indicators == NULL) {
- proxyt->indicators = g_hash_table_new(g_direct_hash, g_direct_equal);
-
- IndicateListenerPrivate * priv = INDICATE_LISTENER_GET_PRIVATE(proxyt->listener);
-
- /* Move the proxy from 'possible' to 'working'. */
- 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);
-
- /* Connect to all the indicator based signals
- that are coming from this server */
- dbus_g_proxy_add_signal(proxyt->proxy, "IndicatorAdded",
- G_TYPE_UINT, G_TYPE_STRING, G_TYPE_INVALID);
- dbus_g_proxy_connect_signal(proxyt->proxy, "IndicatorAdded",
- G_CALLBACK(proxy_indicator_added_legacy), proxyt, NULL);
- dbus_g_proxy_add_signal(proxyt->proxy, "IndicatorNew",
- G_TYPE_UINT, G_TYPE_INVALID);
- dbus_g_proxy_connect_signal(proxyt->proxy, "IndicatorNew",
- G_CALLBACK(proxy_indicator_added), proxyt, NULL);
- dbus_g_proxy_add_signal(proxyt->proxy, "IndicatorRemoved",
- G_TYPE_UINT, G_TYPE_STRING, G_TYPE_INVALID);
- dbus_g_proxy_connect_signal(proxyt->proxy, "IndicatorRemoved",
- G_CALLBACK(proxy_indicator_removed_legacy), proxyt, NULL);
- dbus_g_proxy_add_signal(proxyt->proxy, "IndicatorDelete",
- G_TYPE_UINT, G_TYPE_INVALID);
- dbus_g_proxy_connect_signal(proxyt->proxy, "IndicatorDelete",
- G_CALLBACK(proxy_indicator_removed), proxyt, NULL);
- dbus_g_proxy_add_signal(proxyt->proxy, "IndicatorModified",
- G_TYPE_UINT, G_TYPE_STRING, G_TYPE_INVALID);
- dbus_g_proxy_connect_signal(proxyt->proxy, "IndicatorModified",
- G_CALLBACK(proxy_indicator_modified), proxyt, NULL);
- dbus_g_proxy_add_signal(proxyt->proxy, "ServerCountChanged",
- G_TYPE_UINT, G_TYPE_INVALID);
- dbus_g_proxy_connect_signal(proxyt->proxy, "ServerCountChanged",
- G_CALLBACK(proxy_server_count_changed), proxyt, NULL);
-
- /* If we've got a type let it override the type
- we had here before */
- if (type != NULL) {
- if (proxyt->type != NULL) {
- g_free(proxyt->type);
- }
- proxyt->type = g_strdup(type);
- }
-
- /* We're setting the max number of indicators from the default
- when we detect it. This should give a reasonable amount of
- time for listeners to set the default if they want something
- different from infinite. Otherwise it'd be easy to miss the
- first couple. */
- proxyt->server.max_indicators = priv->max_indicators;
- if (proxyt->server.max_indicators != -1) {
- org_freedesktop_indicator_set_max_indicators_async(proxyt->proxy, proxyt->server.max_indicators, set_max_indicators_cb, proxyt->name);
- }
-
- /* Signal to clients of the listener that there's a new
- server. Note the server parameter here is the pointer
- to the server struct in the proxy data structure. */
- g_signal_emit(proxyt->listener, signals[SERVER_ADDED], 0, &proxyt->server, proxyt->type, TRUE);
- }
-
- return;
-}
/* A fun little wrapper so that we can support the
signals on the indicator v1 interface. It just drops
@@ -619,10 +613,6 @@
g_debug("Proxy Indicator Added");
g_return_if_fail(proxyt != NULL);
- if (proxyt->indicators == NULL) {
- proxy_server_added (proxy, NULL, proxyt);
- }
-
if (!g_hash_table_lookup(proxyt->indicators, GUINT_TO_POINTER(id))) {
g_hash_table_insert(proxyt->indicators, GUINT_TO_POINTER(id), GUINT_TO_POINTER(TRUE));
g_signal_emit(proxyt->listener, signals[INDICATOR_ADDED], 0, &proxyt->server, GUINT_TO_POINTER(id), TRUE);
@@ -1038,11 +1028,7 @@
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);
- }
-
+ GList * proxyitem = g_list_find_custom(priv->proxies, &searchitem, proxy_t_equal);
if (proxyitem == NULL) {
g_warning("Can not find a proxy for the server at all.");
return;
@@ -1053,7 +1039,7 @@
if (proxyt->property_proxy == NULL) {
proxyt->property_proxy = dbus_g_proxy_new_for_name(proxyt->connection,
proxyt->name,
- "/org/freedesktop/indicate",
+ proxyt->path,
DBUS_INTERFACE_PROPERTIES);
}
@@ -1195,101 +1181,6 @@
return our_type;
}
-static const gchar * _introspector_path[] = {"", "org", "freedesktop", "indicate", NULL};
-static const gchar * _introspector_fullpath[] = {"/", "/org", "/org/freedesktop", "/org/freedesktop/indicate", NULL};
-static const gchar * _introspector_interface = "org.freedesktop.indicator";
-
-static void
-introspect_this (DBusGProxy * proxy, char * OUT_data, GError * error, gpointer data)
-{
- /* g_debug("Introspect this:\n%s", OUT_data); */
- proxy_t * server = (proxy_t *)data;
- if (proxy != NULL) {
- g_object_unref(proxy);
- }
- if (error != NULL) {
- /* We probably couldn't introspect that far up. That's
- life, it happens. Or there's a timeout, that happens
- too, I guess some apps are too busy for us. */
- /* g_debug("Introspection error on %s object %s: %s", server->name, _introspector_fullpath[server->introspect_level], error->message); */
- return;
- }
-
- if (OUT_data != NULL) {
- xmlDocPtr xmldoc;
- /* Parse the XML */
- xmldoc = xmlReadMemory(OUT_data, g_utf8_strlen(OUT_data, 16*1024), "introspection.xml", NULL, 0);
-
- /* Check for root being "node" */
- xmlNodePtr root = xmlDocGetRootElement(xmldoc);
- if (g_strcmp0((gchar *)root->name, "node") != 0) {
- xmlFreeDoc(xmldoc);
- g_warning("Introspection data from %s is not valid: %s", server->name, OUT_data);
- return;
- }
-
- server->introspect_level += 1;
- const gchar * nodename = NULL;
- const gchar * nameval = NULL;
- if (_introspector_path[server->introspect_level] == NULL) {
- /* We're looking for our interface */
- nodename = "interface";
- nameval = _introspector_interface;
- } else {
- /* We're looking for our next node */
- nodename = "node";
- nameval = _introspector_path[server->introspect_level];
- }
-
- gboolean found = FALSE;
- xmlNodePtr children;
- for (children = root->children; children != NULL; children = children->next) {
- gchar * xmlnameval = NULL;
- if (g_strcmp0((gchar *)children->name, nodename) == 0) {
- xmlAttrPtr attrib;
- for (attrib = children->properties; attrib != NULL; attrib = attrib->next) {
- if (g_strcmp0((gchar *)attrib->name, "name") == 0) {
- if (attrib->children != NULL) {
- xmlnameval = (gchar *)attrib->children->content;
- }
- break;
- }
- }
-
- if (!g_strcmp0(nameval, xmlnameval)) {
- found = TRUE;
- break;
- }
- }
- }
-
- xmlFreeDoc(xmldoc);
-
- if (!found) {
- /* Ah, nothing we're interested in */
- return;
- }
-
- if (_introspector_path[server->introspect_level] == NULL) {
- /* If we've found the interface at the end of the tree, whoo! hoo! */
- /* Now we know it's safe to get the type on it */
- indicate_listener_server_get_type(server->listener, &server->server, get_type_cb, server);
- return;
- }
- } else {
- server->introspect_level = 0;
- }
-
- DBusGProxy * newproxy = dbus_g_proxy_new_for_name(server->connection,
- server->name,
- _introspector_fullpath[server->introspect_level],
- DBUS_INTERFACE_INTROSPECTABLE);
-
- org_freedesktop_DBus_Introspectable_introspect_async(newproxy, introspect_this, server);
-
- return;
-}
-
/**
indicate_listener_set_default_max_indicators:
@listener: Instance of #IndicateListener to set on.
=== modified file 'libindicate/listener.h'
--- libindicate/listener.h 2010-02-01 02:31:17 +0000
+++ libindicate/listener.h 2010-02-03 05:46:11 +0000
@@ -79,10 +79,10 @@
@server_added: Slot for IndicateListener::server-added.
@server_removed: Slot for IndicateListener::server-removed.
@server_count_changed: Slot for IndicateListener::server-count-changed.
+ @indicator_servers_report: Slot for IndicateListener::indicator-servers-report.
@indicate_listener_reserved1: Reserved for future use
@indicate_listener_reserved2: Reserved for future use
@indicate_listener_reserved3: Reserved for future use
- @indicate_listener_reserved4: Reserved for future use
The class has all of the signals that are supplied by
the listener about what is happening on the server.
@@ -101,11 +101,12 @@
void (* server_removed) (IndicateListenerServer * server, gchar * type);
void (* server_count_changed) (IndicateListenerServer * server, guint count);
+ void (* indicator_servers_report) (void);
+
/* Future Use */
void (*indicate_listener_reserved1)(void);
void (*indicate_listener_reserved2)(void);
void (*indicate_listener_reserved3)(void);
- void (*indicate_listener_reserved4)(void);
};
GType indicate_listener_get_type (void) G_GNUC_CONST;
=== modified file 'libindicate/server.c'
--- libindicate/server.c 2010-02-01 05:59:25 +0000
+++ libindicate/server.c 2010-02-03 05:46:11 +0000
@@ -129,7 +129,11 @@
G_DEFINE_TYPE (IndicateServer, indicate_server, G_TYPE_OBJECT);
/* Prototypes */
+<<<<<<< TREE
static void indicate_server_dispose (GObject * obj);
+=======
+static DBusHandlerResult dbus_filter_new_listener (DBusConnection * connection, DBusMessage * message, void * user_data);
+>>>>>>> MERGE-SOURCE
static void indicate_server_finalize (GObject * obj);
static gboolean get_indicator_count (IndicateServer * server, guint * count, GError **error);
static gboolean get_indicator_list (IndicateServer * server, GArray ** indicators, GError ** error);
@@ -408,6 +412,11 @@
priv->interestedfolks = NULL;
priv->max_indicators = MAX_INDICATORS_UNSET;
+ priv->connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
+
+ dbus_connection_add_filter(dbus_g_connection_get_connection(priv->connection), dbus_filter_new_listener, server, NULL);
+ dbus_bus_add_match(dbus_g_connection_get_connection(priv->connection), "type='signal',interface='org.freedesktop.indicator.listener',member='IndicatorServersReport'", NULL);
+
return;
}
@@ -526,6 +535,27 @@
return;
}
+/* A small dbus filter that waits on the IndicatorServersReport
+ signal and sends the Show signal if this server is not hidden. */
+static DBusHandlerResult
+dbus_filter_new_listener (DBusConnection * connection, DBusMessage * message, void * user_data)
+{
+ if (!dbus_message_is_signal(message, "org.freedesktop.indicator.listener", "IndicatorServersReport")) {
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
+
+ IndicateServer * server = INDICATE_SERVER(user_data);
+
+ if (server != NULL) {
+ IndicateServerPrivate * priv = INDICATE_SERVER_GET_PRIVATE(server);
+ if (priv->visible) {
+ g_signal_emit(server, signals[SERVER_SHOW], 0, priv->type ? priv->type : "", TRUE);
+ }
+ }
+
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
/* Small little function to get an error quark for usage
with the GError errors back across DBus */
static GQuark
Follow ups