2005-01-30 Havoc Pennington <hp@redhat.com>

* tools/dbus-names-model.c: dynamically watch NameOwnerChanged

	* autogen.sh: change to autotools 1.9

	* glib/dbus-gproxy.c: completely change how signals work
	(dbus_g_proxy_add_signal): new function to specify signature of a
	signal
	(dbus_g_proxy_emit_received): marshal the dbus message to GValues,
	and g_warning if the incoming message has the wrong signature.
This commit is contained in:
Havoc Pennington 2005-01-31 02:55:12 +00:00
parent d5b7d7a78c
commit d2c1a633d1
11 changed files with 510 additions and 88 deletions

View file

@ -1,3 +1,15 @@
2005-01-30 Havoc Pennington <hp@redhat.com>
* tools/dbus-names-model.c: dynamically watch NameOwnerChanged
* autogen.sh: change to autotools 1.9
* glib/dbus-gproxy.c: completely change how signals work
(dbus_g_proxy_add_signal): new function to specify signature of a
signal
(dbus_g_proxy_emit_received): marshal the dbus message to GValues,
and g_warning if the incoming message has the wrong signature.
2005-01-30 Havoc Pennington <hp@redhat.com>
* tools/dbus-names-model.c (have_names_notify): fix this

View file

@ -21,8 +21,8 @@ DIE=0
DIE=1
}
AUTOMAKE=automake-1.7
ACLOCAL=aclocal-1.7
AUTOMAKE=automake-1.9
ACLOCAL=aclocal-1.9
($AUTOMAKE --version) < /dev/null > /dev/null 2>&1 || {
AUTOMAKE=automake

View file

@ -819,6 +819,13 @@ fi
AM_CONDITIONAL(HAVE_GLIB, test x$have_glib = xyes)
AM_CONDITIONAL(HAVE_GLIB_THREADS, test x$have_glib_threads = xyes)
if test x$have_glib = xyes; then
GLIB_GENMARSHAL=`$PKG_CONFIG --variable=glib_genmarshal glib-2.0`
else
GLIB_GENMARSHAL=glib-not-enabled-so-there-is-no-genmarshal
fi
AC_SUBST(GLIB_GENMARSHAL)
dnl GLib flags
AC_SUBST(DBUS_GLIB_CFLAGS)
AC_SUBST(DBUS_GLIB_LIBS)

View file

@ -149,6 +149,9 @@ DBusGProxy* dbus_g_proxy_new_for_name_owner (DBusGConnection *connect
DBusGProxy* dbus_g_proxy_new_for_peer (DBusGConnection *connection,
const char *path_name,
const char *interface_name);
void dbus_g_proxy_add_signal (DBusGProxy *proxy,
const char *signal_name,
const char *signature);
void dbus_g_proxy_connect_signal (DBusGProxy *proxy,
const char *signal_name,
GCallback handler,

View file

@ -55,9 +55,9 @@ Important for 1.0 GLib Bindings
dbus_malloc() memory, only g_malloc().
dbus_g_proxy_end_call() is the major offender.
- dbus_gproxy_connect_signal() has to take a signature for the signal
so it can figure out how to invoke the callback, or we have to rely
on having introspection data.
- DBusGProxy signals feature is a complete fiasco;
right now the problem is that it dynamically creates
signals on the global DBusGProxy class and never frees them
- DBusGProxy doesn't emit "destroy" when it should

View file

@ -5,6 +5,8 @@ lib_LTLIBRARIES=libdbus-glib-1.la
libdbus_glib_1_la_SOURCES = \
dbus-glib.c \
dbus-gmain.c \
dbus-gmarshal.c \
dbus-gmarshal.h \
dbus-gobject.c \
dbus-gproxy.c \
dbus-gtest.c \
@ -41,6 +43,15 @@ dbus_binding_tool_SOURCES = \
dbus_binding_tool_LDADD= -lexpat libdbus-gtool.la
## we just rebuilt these manually and check them into cvs; easier than
## convincing automake/make to do this properly
regenerate-built-sources:
@GLIB_GENMARSHAL@ --prefix=_dbus_g_marshal dbus-gmarshal.list --header > dbus-gmarshal.h && \
echo '#include "dbus-gmarshal.h"' > dbus-gmarshal.c && \
@GLIB_GENMARSHAL@ --prefix=_dbus_g_marshal dbus-gmarshal.list --body >> dbus-gmarshal.c
EXTRA_DIST=dbus-gmarshal.list
if DBUS_BUILD_TESTS
## we use noinst_PROGRAMS not check_PROGRAMS for TESTS so that we

89
glib/dbus-gmarshal.c Normal file
View file

@ -0,0 +1,89 @@
#include "dbus-gmarshal.h"
#include <glib-object.h>
#ifdef G_ENABLE_DEBUG
#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v)
#define g_marshal_value_peek_char(v) g_value_get_char (v)
#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v)
#define g_marshal_value_peek_int(v) g_value_get_int (v)
#define g_marshal_value_peek_uint(v) g_value_get_uint (v)
#define g_marshal_value_peek_long(v) g_value_get_long (v)
#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v)
#define g_marshal_value_peek_int64(v) g_value_get_int64 (v)
#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v)
#define g_marshal_value_peek_enum(v) g_value_get_enum (v)
#define g_marshal_value_peek_flags(v) g_value_get_flags (v)
#define g_marshal_value_peek_float(v) g_value_get_float (v)
#define g_marshal_value_peek_double(v) g_value_get_double (v)
#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v)
#define g_marshal_value_peek_param(v) g_value_get_param (v)
#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v)
#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v)
#define g_marshal_value_peek_object(v) g_value_get_object (v)
#else /* !G_ENABLE_DEBUG */
/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API.
* Do not access GValues directly in your code. Instead, use the
* g_value_get_*() functions
*/
#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int
#define g_marshal_value_peek_char(v) (v)->data[0].v_int
#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint
#define g_marshal_value_peek_int(v) (v)->data[0].v_int
#define g_marshal_value_peek_uint(v) (v)->data[0].v_uint
#define g_marshal_value_peek_long(v) (v)->data[0].v_long
#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong
#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64
#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64
#define g_marshal_value_peek_enum(v) (v)->data[0].v_long
#define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong
#define g_marshal_value_peek_float(v) (v)->data[0].v_float
#define g_marshal_value_peek_double(v) (v)->data[0].v_double
#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer
#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer
#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer
#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer
#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer
#endif /* !G_ENABLE_DEBUG */
/* NONE:STRING,STRING,STRING (dbus-gmarshal.list:1) */
void
_dbus_g_marshal_VOID__STRING_STRING_STRING (GClosure *closure,
GValue *return_value,
guint n_param_values,
const GValue *param_values,
gpointer invocation_hint,
gpointer marshal_data)
{
typedef void (*GMarshalFunc_VOID__STRING_STRING_STRING) (gpointer data1,
gpointer arg_1,
gpointer arg_2,
gpointer arg_3,
gpointer data2);
register GMarshalFunc_VOID__STRING_STRING_STRING callback;
register GCClosure *cc = (GCClosure*) closure;
register gpointer data1, data2;
g_return_if_fail (n_param_values == 4);
if (G_CCLOSURE_SWAP_DATA (closure))
{
data1 = closure->data;
data2 = g_value_peek_pointer (param_values + 0);
}
else
{
data1 = g_value_peek_pointer (param_values + 0);
data2 = closure->data;
}
callback = (GMarshalFunc_VOID__STRING_STRING_STRING) (marshal_data ? marshal_data : cc->callback);
callback (data1,
g_marshal_value_peek_string (param_values + 1),
g_marshal_value_peek_string (param_values + 2),
g_marshal_value_peek_string (param_values + 3),
data2);
}

21
glib/dbus-gmarshal.h Normal file
View file

@ -0,0 +1,21 @@
#ifndef ___dbus_g_marshal_MARSHAL_H__
#define ___dbus_g_marshal_MARSHAL_H__
#include <glib-object.h>
G_BEGIN_DECLS
/* NONE:STRING,STRING,STRING (dbus-gmarshal.list:1) */
extern void _dbus_g_marshal_VOID__STRING_STRING_STRING (GClosure *closure,
GValue *return_value,
guint n_param_values,
const GValue *param_values,
gpointer invocation_hint,
gpointer marshal_data);
#define _dbus_g_marshal_NONE__STRING_STRING_STRING _dbus_g_marshal_VOID__STRING_STRING_STRING
G_END_DECLS
#endif /* ___dbus_g_marshal_MARSHAL_H__ */

1
glib/dbus-gmarshal.list Normal file
View file

@ -0,0 +1 @@
NONE:STRING,STRING,STRING

View file

@ -23,6 +23,8 @@
#include <dbus/dbus-glib.h>
#include <dbus/dbus-glib-lowlevel.h>
#include "dbus-gutils.h"
#include "dbus-gmarshal.h"
#include "dbus-gvalue.h"
#include <string.h>
/**
@ -48,6 +50,8 @@ struct DBusGProxy
char *name; /**< Name messages go to or NULL */
char *path; /**< Path messages go to or NULL */
char *interface; /**< Interface messages go to or NULL */
GData *signal_signatures; /**< D-BUS signatures for each signal */
};
/**
@ -58,14 +62,13 @@ struct DBusGProxyClass
GObjectClass parent_class; /**< Parent class */
};
static void dbus_g_proxy_init (DBusGProxy *proxy);
static void dbus_g_proxy_class_init (DBusGProxyClass *klass);
static void dbus_g_proxy_finalize (GObject *object);
static void dbus_g_proxy_dispose (GObject *object);
static void dbus_g_proxy_destroy (DBusGProxy *proxy);
static void dbus_g_proxy_emit_received (DBusGProxy *proxy,
DBusMessage *message);
static void dbus_g_proxy_init (DBusGProxy *proxy);
static void dbus_g_proxy_class_init (DBusGProxyClass *klass);
static void dbus_g_proxy_finalize (GObject *object);
static void dbus_g_proxy_dispose (GObject *object);
static void dbus_g_proxy_destroy (DBusGProxy *proxy);
static void dbus_g_proxy_emit_remote_signal (DBusGProxy *proxy,
DBusMessage *message);
/**
* A list of proxies with a given name+path+interface, used to
@ -641,7 +644,7 @@ dbus_g_proxy_manager_filter (DBusConnection *connection,
proxy = DBUS_G_PROXY (tmp->data);
UNLOCK_MANAGER (manager);
dbus_g_proxy_emit_received (proxy, message);
dbus_g_proxy_emit_remote_signal (proxy, message);
g_object_unref (G_OBJECT (proxy));
LOCK_MANAGER (manager);
@ -670,7 +673,6 @@ dbus_g_proxy_manager_filter (DBusConnection *connection,
enum
{
DESTROY,
RECEIVED,
LAST_SIGNAL
};
@ -680,7 +682,7 @@ static guint signals[LAST_SIGNAL] = { 0 };
static void
dbus_g_proxy_init (DBusGProxy *proxy)
{
/* Nothing */
g_datalist_init (&proxy->signal_signatures);
}
static void
@ -701,16 +703,6 @@ dbus_g_proxy_class_init (DBusGProxyClass *klass)
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
signals[RECEIVED] =
g_signal_new ("received",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
0,
NULL, NULL,
g_cclosure_marshal_VOID__BOXED,
G_TYPE_NONE, 1,
DBUS_TYPE_MESSAGE);
}
@ -721,6 +713,8 @@ dbus_g_proxy_dispose (GObject *object)
proxy = DBUS_G_PROXY (object);
g_datalist_clear (&proxy->signal_signatures);
g_signal_emit (object, signals[DESTROY], 0);
G_OBJECT_CLASS (parent_class)->dispose (object);
@ -755,28 +749,102 @@ dbus_g_proxy_destroy (DBusGProxy *proxy)
g_object_run_dispose (G_OBJECT (proxy));
}
/* this is to avoid people using g_signal_connect() directly,
* to avoid confusion with local signal names, and because
* of the horribly broken current setup (signals are added
* globally to all proxies)
*/
static char*
create_signal_detail (const char *interface,
const char *signal)
create_signal_name (const char *interface,
const char *signal)
{
GString *str;
char *p;
str = g_string_new (interface);
g_string_append (str, ".");
g_string_append (str, "-");
g_string_append (str, signal);
/* GLib will silently barf on '.' in signal names */
p = str->str;
while (*p)
{
if (*p == '.')
*p = '-';
++p;
}
return g_string_free (str, FALSE);
}
static void
dbus_g_proxy_emit_received (DBusGProxy *proxy,
DBusMessage *message)
emit_remote_internal (DBusGProxy *proxy,
DBusMessage *message,
guint signal_id,
gboolean marshal_args)
{
#define MAX_SIGNATURE_ARGS 20
GValue values[MAX_SIGNATURE_ARGS];
int arg;
int i;
memset (&values[0], 0, sizeof (values));
arg = 0;
g_value_init (&values[arg], G_TYPE_FROM_INSTANCE (proxy));
g_value_set_instance (&values[arg], proxy);
++arg;
if (marshal_args)
{
DBusMessageIter iter;
int dtype;
dbus_message_iter_init (message, &iter);
while ((dtype = dbus_message_iter_get_arg_type (&iter)) != DBUS_TYPE_INVALID)
{
if (arg == MAX_SIGNATURE_ARGS)
{
g_warning ("Don't support more than %d signal args\n", MAX_SIGNATURE_ARGS);
goto out;
}
if (!dbus_gvalue_demarshal (&iter, &values[arg]))
{
g_warning ("Unable to convert arg type %d to GValue to emit DBusGProxy signal", dtype);
goto out;
}
++arg;
dbus_message_iter_next (&iter);
}
}
g_signal_emitv (&values[0],
signal_id,
0,
NULL);
out:
i = 0;
while (i < arg)
{
g_value_unset (&values[i]);
++i;
}
}
static void
dbus_g_proxy_emit_remote_signal (DBusGProxy *proxy,
DBusMessage *message)
{
const char *interface;
const char *signal;
char *detail;
char *name;
GQuark q;
interface = dbus_message_get_interface (message);
@ -785,21 +853,43 @@ dbus_g_proxy_emit_received (DBusGProxy *proxy,
g_assert (interface != NULL);
g_assert (signal != NULL);
detail = create_signal_detail (interface, signal);
name = create_signal_name (interface, signal);
/* If the quark isn't preexisting, there's no way there
* are any handlers connected. We don't want to create
* extra quarks for every possible signal.
*/
q = g_quark_try_string (detail);
q = g_quark_try_string (name);
if (q != 0)
g_signal_emit (G_OBJECT (proxy),
signals[RECEIVED],
q,
message);
{
const char *signature;
g_free (detail);
signature = g_datalist_id_get_data (&proxy->signal_signatures, q);
if (signature == NULL)
{
g_warning ("Signal '%s' has not been added to this proxy object\n",
name);
}
else if (!dbus_message_has_signature (message, signature))
{
g_warning ("Signature '%s' expected for signal '%s', actual signature '%s'\n",
signature,
name,
dbus_message_get_signature (message));
}
else
{
guint signal_id;
signal_id = g_signal_lookup (name, G_OBJECT_TYPE (proxy));
g_assert (signal_id != 0); /* because we have the signature */
emit_remote_internal (proxy, message, signal_id, signature != NULL);
}
}
g_free (name);
}
/** @} End of DBusGLibInternals */
@ -1264,8 +1354,8 @@ dbus_g_proxy_call_no_reply (DBusGProxy *proxy,
* @param client_serial return location for message's serial, or #NULL */
void
dbus_g_proxy_send (DBusGProxy *proxy,
DBusMessage *message,
dbus_uint32_t *client_serial)
DBusMessage *message,
dbus_uint32_t *client_serial)
{
g_return_if_fail (DBUS_IS_G_PROXY (proxy));
@ -1289,15 +1379,103 @@ dbus_g_proxy_send (DBusGProxy *proxy,
g_error ("Out of memory\n");
}
static gboolean
siginfo_from_signature (const char *signature,
GSignalCMarshaller *c_marshaller,
GType *return_type,
guint *n_params,
GType **param_types)
{
/* FIXME (which marshalers should we include?
* probably need public API to add your own
*/
if (strcmp (signature, "sss") == 0)
{
*c_marshaller = _dbus_g_marshal_NONE__STRING_STRING_STRING;
*return_type = G_TYPE_NONE;
*n_params = 3;
*param_types = g_new0 (GType, *n_params);
(*param_types)[0] = G_TYPE_STRING;
(*param_types)[1] = G_TYPE_STRING;
(*param_types)[2] = G_TYPE_STRING;
return TRUE;
}
return FALSE;
}
/**
* Specifies the signature of a signal, such that it's possible to
* connect to the signal on this proxy.
*
* @param proxy the proxy for a remote interface
* @param signal_name the name of the signal
* @param signature D-BUS signature of the signal
*/
void
dbus_g_proxy_add_signal (DBusGProxy *proxy,
const char *signal_name,
const char *signature)
{
GSignalCMarshaller c_marshaller;
GType return_type;
int n_params;
GType *params;
g_return_if_fail (DBUS_IS_G_PROXY (proxy));
g_return_if_fail (signal_name != NULL);
g_return_if_fail (signature != NULL);
if (siginfo_from_signature (signature,
&c_marshaller,
&return_type,
&n_params,
&params))
{
GQuark q;
char *name;
name = create_signal_name (proxy->interface, signal_name);
q = g_quark_from_string (name);
g_return_if_fail (g_datalist_id_get_data (&proxy->signal_signatures, q) == NULL);
g_datalist_id_set_data_full (&proxy->signal_signatures,
q, g_strdup (signature),
g_free);
/* hackaround global nature of g_signal_newv()... this whole thing needs unhosing */
if (g_signal_lookup (name,
G_OBJECT_TYPE (proxy)) == 0)
{
g_signal_newv (name,
G_OBJECT_TYPE (proxy),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
c_marshaller,
return_type, n_params, params);
}
g_free (params);
g_free (name);
}
else
{
g_warning ("DBusGProxy doesn't know how to create a signal with signature '%s'\n",
signature);
}
}
/**
* Connect a signal handler to a proxy for a remote interface. When
* the remote interface emits the specified signal, the proxy will
* emit a corresponding GLib signal.
*
* @todo Right now there's no way to specify the signature to use
* for invoking the GCallback. Need to either rely on introspection,
* or require signature here.
*
* @param proxy a proxy for a remote interface
* @param signal_name the DBus signal name to listen for
* @param handler the handler to connect
@ -1306,27 +1484,40 @@ dbus_g_proxy_send (DBusGProxy *proxy,
*/
void
dbus_g_proxy_connect_signal (DBusGProxy *proxy,
const char *signal_name,
GCallback handler,
void *data,
GClosureNotify free_data_func)
const char *signal_name,
GCallback handler,
void *data,
GClosureNotify free_data_func)
{
GClosure *closure;
char *detail;
char *name;
guint signal_id;
g_return_if_fail (DBUS_IS_G_PROXY (proxy));
g_return_if_fail (signal_name != NULL);
g_return_if_fail (handler != NULL);
detail = create_signal_detail (proxy->interface, signal_name);
closure = g_cclosure_new (G_CALLBACK (handler), data, free_data_func);
g_signal_connect_closure_by_id (G_OBJECT (proxy),
signals[RECEIVED],
g_quark_from_string (detail),
closure, FALSE);
name = create_signal_name (proxy->interface, signal_name);
g_free (detail);
g_printerr ("Looking up signal '%s'\n", name);
signal_id = g_signal_lookup (name,
G_OBJECT_TYPE (proxy));
if (signal_id != 0)
{
GClosure *closure;
closure = g_cclosure_new (G_CALLBACK (handler), data, free_data_func);
g_signal_connect_closure_by_id (G_OBJECT (proxy),
signal_id,
0,
closure, FALSE);
}
else
{
g_warning ("You have to add signal '%s' with dbus_g_proxy_add_signal() before you can connect to it\n",
name);
}
g_free (name);
}
/**
@ -1340,38 +1531,38 @@ dbus_g_proxy_connect_signal (DBusGProxy *proxy,
*/
void
dbus_g_proxy_disconnect_signal (DBusGProxy *proxy,
const char *signal_name,
GCallback handler,
void *data)
const char *signal_name,
GCallback handler,
void *data)
{
char *detail;
GQuark q;
char *name;
guint signal_id;
g_return_if_fail (DBUS_IS_G_PROXY (proxy));
g_return_if_fail (signal_name != NULL);
g_return_if_fail (handler != NULL);
detail = create_signal_detail (proxy->interface, signal_name);
q = g_quark_try_string (detail);
g_free (detail);
name = create_signal_name (proxy->interface, signal_name);
#ifndef G_DISABLE_CHECKS
if (q == 0)
signal_id = g_signal_lookup (name, G_OBJECT_TYPE (proxy));
if (signal_id != 0)
{
g_warning ("%s: No signal handlers for %s found on this DBusGProxy",
G_GNUC_FUNCTION, signal_name);
return;
g_signal_handlers_disconnect_matched (G_OBJECT (proxy),
G_SIGNAL_MATCH_DETAIL |
G_SIGNAL_MATCH_FUNC |
G_SIGNAL_MATCH_DATA,
signal_id,
0,
NULL,
G_CALLBACK (handler), data);
}
else
{
g_warning ("Attempt to disconnect from signal '%s' which is not registered\n",
name);
}
#endif
g_signal_handlers_disconnect_matched (G_OBJECT (proxy),
G_SIGNAL_MATCH_DETAIL |
G_SIGNAL_MATCH_FUNC |
G_SIGNAL_MATCH_DATA,
signals[RECEIVED],
q,
NULL,
G_CALLBACK (handler), data);
g_free (name);
}
/** @} End of DBusGLib public */

View file

@ -22,6 +22,7 @@
*/
#include "dbus-names-model.h"
#include <glib/gi18n.h>
#include <string.h>
enum
{
@ -112,6 +113,81 @@ have_names_notify (DBusGPendingCall *call,
g_strfreev (names);
}
static gboolean
names_model_find_name (NamesModel *names_model,
const char *name,
GtkTreeIter *iter_p)
{
GtkTreeIter iter;
if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (names_model),
&iter))
return FALSE;
do
{
char *s;
gtk_tree_model_get (GTK_TREE_MODEL (names_model),
&iter,
MODEL_COLUMN_NAME, &s,
-1);
if (s && strcmp (s, name) == 0)
{
*iter_p = iter;
g_free (s);
return TRUE;
}
g_free (s);
}
while (gtk_tree_model_iter_next (GTK_TREE_MODEL (names_model),
&iter));
return FALSE;
}
static void
name_owner_changed (DBusGProxy *driver_proxy,
const char *name,
const char *old_owner,
const char *new_owner,
void *data)
{
NamesModel *names_model = NAMES_MODEL (data);
#if 0
g_printerr ("Name '%s' changed owner '%s' -> '%s'\n",
name, old_owner, new_owner);
#endif
if (*new_owner == '\0')
{
/* this name has vanished */
GtkTreeIter iter;
if (names_model_find_name (names_model, name, &iter))
gtk_tree_store_remove (GTK_TREE_STORE (names_model),
&iter);
}
else if (*old_owner == '\0')
{
/* this name has been added */
GtkTreeIter iter;
if (!names_model_find_name (names_model, name, &iter))
{
gtk_tree_store_append (GTK_TREE_STORE (names_model),
&iter, NULL);
gtk_tree_store_set (GTK_TREE_STORE (names_model),
&iter,
MODEL_COLUMN_NAME, name,
-1);
}
}
}
static void
names_model_reload (NamesModel *names_model)
{
@ -144,8 +220,6 @@ static void
names_model_set_connection (NamesModel *names_model,
DBusGConnection *connection)
{
const char *match_rule = "type='signal',member='NameOwnerChanged'";
g_return_if_fail (IS_NAMES_MODEL (names_model));
if (connection == names_model->connection)
@ -153,10 +227,11 @@ names_model_set_connection (NamesModel *names_model,
if (names_model->connection)
{
dbus_g_proxy_call_no_reply (names_model->driver_proxy,
"RemoveMatch",
DBUS_TYPE_STRING, &match_rule,
DBUS_TYPE_INVALID);
dbus_g_proxy_disconnect_signal (names_model->driver_proxy,
"NameOwnerChanged",
G_CALLBACK (name_owner_changed),
names_model);
g_object_unref (names_model->driver_proxy);
names_model->driver_proxy = NULL;
dbus_g_connection_unref (names_model->connection);
@ -174,6 +249,18 @@ names_model_set_connection (NamesModel *names_model,
DBUS_PATH_ORG_FREEDESKTOP_DBUS,
DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS);
g_assert (names_model->driver_proxy);
dbus_g_proxy_add_signal (names_model->driver_proxy,
"NameOwnerChanged",
DBUS_TYPE_STRING_AS_STRING
DBUS_TYPE_STRING_AS_STRING
DBUS_TYPE_STRING_AS_STRING);
dbus_g_proxy_connect_signal (names_model->driver_proxy,
"NameOwnerChanged",
G_CALLBACK (name_owner_changed),
names_model,
NULL);
}
names_model_reload (names_model);