[PATCH] Dbus glib
Andre Magalhaes
andrunko at gmail.com
Mon Jan 23 10:39:09 PST 2006
Hi all,
Attached there is a patch for dbus glib to enable objects to use
parent objects methods/signals set with
dbus_g_object_type_install_info. Don't know if this is the best way to
do it, as this is the first time i ever touched dbus codebase, so feel
free to comment.
With this patch i can do something like:
object_base.xml
define methods and signals
object_child1.xml
define another methods and signals
object_base.c
object_base_class_init (ObjectBaseClass *klass)
....
dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (klass),
&dbus_glib_object_base_object_info);
....
object_child1.c
object_child1_class_init (ObjectChild1Class *klass)
....
dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (klass),
&dbus_glib_object_child1_object_info);
....
and use the dbus interface provided by the base class trough the child
object class.
BR,
Andrunko
-------------- next part --------------
Index: glib/dbus-gobject.c
===================================================================
RCS file: /cvs/dbus/dbus/glib/dbus-gobject.c,v
retrieving revision 1.53
diff -u -3 -p -r1.53 dbus-gobject.c
--- glib/dbus-gobject.c 27 Nov 2005 16:55:09 -0000 1.53
+++ glib/dbus-gobject.c 23 Jan 2006 18:19:00 -0000
@@ -295,28 +295,23 @@ dbus_g_object_type_dbus_metadata_quark (
return quark;
}
-static const DBusGObjectInfo *
+static GList *
lookup_object_info (GObject *object)
{
- const DBusGObjectInfo *ret;
+ GList *info_list = NULL;
+ const DBusGObjectInfo *info;
GType classtype;
-
- ret = NULL;
-
+
for (classtype = G_TYPE_FROM_INSTANCE (object); classtype != 0; classtype = g_type_parent (classtype))
{
- const DBusGObjectInfo *info;
-
info = g_type_get_qdata (classtype, dbus_g_object_type_dbus_metadata_quark ());
-
if (info != NULL && info->format_version >= 0)
- {
- ret = info;
- break;
- }
+ {
+ info_list = g_list_append (info_list, (gpointer) info);
+ }
}
- return ret;
+ return info_list;
}
static void
@@ -509,6 +504,8 @@ lookup_values (GHashTable *interfaces, c
static void
introspect_interfaces (GObject *object, GString *xml)
{
+ GList *info_list;
+ const GList *info_list_walk;
const DBusGObjectInfo *info;
DBusGLibWriteIterfaceData data;
int i;
@@ -516,60 +513,69 @@ introspect_interfaces (GObject *object,
DBusGLibWriteInterfaceValues *values;
const char *propsig;
- info = lookup_object_info (object);
+ info_list = lookup_object_info (object);
- g_assert (info != NULL);
+ g_assert (info_list != NULL);
/* Gather a list of all interfaces, indexed into their methods */
interfaces = g_hash_table_new (g_str_hash, g_str_equal);
- for (i = 0; i < info->n_method_infos; i++)
+ for (info_list_walk = info_list; info_list_walk != NULL; info_list_walk = g_list_next (info_list_walk))
{
- const char *method_name;
- const char *method_interface;
- const char *method_args;
- const DBusGMethodInfo *method;
-
- method = &(info->method_infos[i]);
+ info = (DBusGObjectInfo *) info_list_walk->data;
+
+ g_assert (info != NULL);
+
+ for (i = 0; i < info->n_method_infos; i++)
+ {
+ const char *method_name;
+ const char *method_interface;
+ const char *method_args;
+ const DBusGMethodInfo *method;
+
+ method = &(info->method_infos[i]);
+
+ method_interface = method_interface_from_object_info (info, method);
+ method_name = method_name_from_object_info (info, method);
+ method_args = method_arg_info_from_object_info (info, method);
- method_interface = method_interface_from_object_info (info, method);
- method_name = method_name_from_object_info (info, method);
- method_args = method_arg_info_from_object_info (info, method);
+ values = lookup_values (interfaces, method_interface);
+ values->methods = g_slist_prepend (values->methods, (gpointer) method);
+ }
- values = lookup_values (interfaces, method_interface);
- values->methods = g_slist_prepend (values->methods, (gpointer) method);
- }
+ propsig = info->exported_signals;
+ while (*propsig)
+ {
+ const char *iface;
+ const char *signame;
- propsig = info->exported_signals;
- while (*propsig)
- {
- const char *iface;
- const char *signame;
+ propsig = propsig_iterate (propsig, &iface, &signame);
- propsig = propsig_iterate (propsig, &iface, &signame);
+ values = lookup_values (interfaces, iface);
+ values->signals = g_slist_prepend (values->signals, (gpointer) signame);
+ }
- values = lookup_values (interfaces, iface);
- values->signals = g_slist_prepend (values->signals, (gpointer) signame);
- }
+ propsig = info->exported_properties;
+ while (*propsig)
+ {
+ const char *iface;
+ const char *propname;
- propsig = info->exported_properties;
- while (*propsig)
- {
- const char *iface;
- const char *propname;
+ propsig = propsig_iterate (propsig, &iface, &propname);
- propsig = propsig_iterate (propsig, &iface, &propname);
+ values = lookup_values (interfaces, iface);
+ values->properties = g_slist_prepend (values->properties, (gpointer) propname);
+ }
+
+ memset (&data, 0, sizeof (data));
+ data.xml = xml;
+ data.gtype = G_TYPE_FROM_INSTANCE (object);
+ data.object_info = info;
+ g_hash_table_foreach (interfaces, write_interface, &data);
+
+ g_hash_table_destroy (interfaces);
+ }
- values = lookup_values (interfaces, iface);
- values->properties = g_slist_prepend (values->properties, (gpointer) propname);
- }
-
- memset (&data, 0, sizeof (data));
- data.xml = xml;
- data.gtype = G_TYPE_FROM_INSTANCE (object);
- data.object_info = info;
- g_hash_table_foreach (interfaces, write_interface, &data);
-
- g_hash_table_destroy (interfaces);
+ g_list_free (info_list);
}
static DBusHandlerResult
@@ -749,45 +755,54 @@ lookup_object_and_method (GObject *
const char *interface;
const char *member;
const char *signature;
- gboolean ret;
+ GList *info_list;
+ const GList *info_list_walk;
const DBusGObjectInfo *info;
int i;
interface = dbus_message_get_interface (message);
member = dbus_message_get_member (message);
signature = dbus_message_get_signature (message);
- ret = FALSE;
- info = lookup_object_info (object);
- *object_ret = info;
+ info_list = lookup_object_info (object);
- for (i = 0; i < info->n_method_infos; i++)
+ for (info_list_walk = info_list; info_list_walk != NULL; info_list_walk = g_list_next (info_list_walk))
{
- const char *expected_member;
- const char *expected_interface;
- char *expected_signature;
- const DBusGMethodInfo *method;
-
- method = &(info->method_infos[i]);
-
- /* Check method interface/name and input signature */
- expected_interface = method_interface_from_object_info (*object_ret, method);
- expected_member = method_name_from_object_info (*object_ret, method);
- expected_signature = method_input_signature_from_object_info (*object_ret, method);
-
- if ((interface == NULL
- || strcmp (expected_interface, interface) == 0)
- && strcmp (expected_member, member) == 0
- && strcmp (expected_signature, signature) == 0)
- {
- g_free (expected_signature);
- *method_ret = method;
- return TRUE;
- }
- g_free (expected_signature);
+ info = (DBusGObjectInfo *) info_list_walk->data;
+ *object_ret = info;
+
+ for (i = 0; i < info->n_method_infos; i++)
+ {
+ const char *expected_member;
+ const char *expected_interface;
+ char *expected_signature;
+ const DBusGMethodInfo *method;
+
+ method = &(info->method_infos[i]);
+
+ /* Check method interface/name and input signature */
+ expected_interface = method_interface_from_object_info (*object_ret, method);
+ expected_member = method_name_from_object_info (*object_ret, method);
+ expected_signature = method_input_signature_from_object_info (*object_ret, method);
+
+ if ((interface == NULL
+ || strcmp (expected_interface, interface) == 0)
+ && strcmp (expected_member, member) == 0
+ && strcmp (expected_signature, signature) == 0)
+ {
+ g_free (expected_signature);
+ *method_ret = method;
+ g_list_free (info_list);
+ return TRUE;
+ }
+ g_free (expected_signature);
+ }
}
- return ret;
+ if (info_list)
+ g_list_free (info_list);
+
+ return FALSE;
}
static char *
@@ -1442,59 +1457,65 @@ signal_emitter_marshaller (GClosure
}
static void
-export_signals (DBusGConnection *connection, const DBusGObjectInfo *info, GObject *object)
+export_signals (DBusGConnection *connection, const GList *info_list, GObject *object)
{
GType gtype;
const char *sigdata;
const char *iface;
const char *signame;
+ const DBusGObjectInfo *info;
gtype = G_TYPE_FROM_INSTANCE (object);
- sigdata = info->exported_signals;
-
- while (*sigdata != '\0')
+ for (; info_list != NULL; info_list = g_list_next (info_list))
{
- guint id;
- GSignalQuery query;
- GClosure *closure;
- char *s;
-
- sigdata = propsig_iterate (sigdata, &iface, &signame);
+ info = (DBusGObjectInfo *) info_list->data;
- s = _dbus_gutils_wincaps_to_uscore (signame);
+ sigdata = info->exported_signals;
+
+ while (*sigdata != '\0')
+ {
+ guint id;
+ GSignalQuery query;
+ GClosure *closure;
+ char *s;
- id = g_signal_lookup (s, gtype);
- if (id == 0)
- {
- g_warning ("signal \"%s\" (from \"%s\") exported but not found in object class \"%s\"",
- s, signame, g_type_name (gtype));
- g_free (s);
- continue;
- }
+ sigdata = propsig_iterate (sigdata, &iface, &signame);
+
+ s = _dbus_gutils_wincaps_to_uscore (signame);
- g_signal_query (id, &query);
+ id = g_signal_lookup (s, gtype);
+ if (id == 0)
+ {
+ g_warning ("signal \"%s\" (from \"%s\") exported but not found in object class \"%s\"",
+ s, signame, g_type_name (gtype));
+ g_free (s);
+ continue;
+ }
- if (query.return_type != G_TYPE_NONE)
- {
- g_warning ("Not exporting signal \"%s\" for object class \"%s\" as it has a return type \"%s\"",
- s, g_type_name (gtype), g_type_name (query.return_type));
- g_free (s);
- continue; /* FIXME: these could be listed as methods ? */
- }
-
- closure = dbus_g_signal_closure_new (connection, object, signame, (char*) iface);
- g_closure_set_marshal (closure, signal_emitter_marshaller);
+ g_signal_query (id, &query);
- g_signal_connect_closure_by_id (object,
- id,
- 0,
- closure,
- FALSE);
+ if (query.return_type != G_TYPE_NONE)
+ {
+ g_warning ("Not exporting signal \"%s\" for object class \"%s\" as it has a return type \"%s\"",
+ s, g_type_name (gtype), g_type_name (query.return_type));
+ g_free (s);
+ continue; /* FIXME: these could be listed as methods ? */
+ }
+
+ closure = dbus_g_signal_closure_new (connection, object, signame, (char*) iface);
+ g_closure_set_marshal (closure, signal_emitter_marshaller);
- g_closure_add_finalize_notifier (closure, NULL,
- dbus_g_signal_closure_finalize);
- g_free (s);
+ g_signal_connect_closure_by_id (object,
+ id,
+ 0,
+ closure,
+ FALSE);
+
+ g_closure_add_finalize_notifier (closure, NULL,
+ dbus_g_signal_closure_finalize);
+ g_free (s);
+ }
}
}
@@ -1640,13 +1661,13 @@ dbus_g_connection_register_g_object (DBu
const char *at_path,
GObject *object)
{
- const DBusGObjectInfo *info;
+ GList *info_list;
g_return_if_fail (connection != NULL);
g_return_if_fail (at_path != NULL);
g_return_if_fail (G_IS_OBJECT (object));
- info = lookup_object_info (object);
- if (info == NULL)
+ info_list = lookup_object_info (object);
+ if (info_list == NULL)
{
g_warning ("No introspection data registered for object class \"%s\"",
g_type_name (G_TYPE_FROM_INSTANCE (object)));
@@ -1662,7 +1683,8 @@ dbus_g_connection_register_g_object (DBu
return;
}
- export_signals (connection, info, object);
+ export_signals (connection, info_list, object);
+ g_list_free (info_list);
g_object_set_data (object, "dbus_glib_object_path", g_strdup (at_path));
g_object_weak_ref (object, (GWeakNotify)unregister_gobject, connection);
More information about the dbus
mailing list