summaryrefslogtreecommitdiffstats
path: root/glib
diff options
context:
space:
mode:
authorHavoc Pennington <hp@redhat.com>2003-09-17 03:52:07 +0000
committerHavoc Pennington <hp@redhat.com>2003-09-17 03:52:07 +0000
commit583994cb3b7f5562fb7b8c37b4cb0d5af78e4ce2 (patch)
treed61f39d2ccb581f3a46d03f58bca93c2ac229afd /glib
parent85ab0327d82e4945ad16630e583d8cc68df25a90 (diff)
2003-09-15 Havoc Pennington <hp@pobox.com>
* dbus/dbus-pending-call.c: add the get/set object data boilerplate as for DBusConnection, etc. Use generic object data for the notify callback. * glib/dbus-gparser.c (parse_node): parse child nodes * tools/dbus-viewer.c: more hacking on the dbus-viewer * glib/dbus-gutils.c (_dbus_gutils_split_path): add a file to contain functions shared between the convenience lib and the installed lib * glib/Makefile.am (libdbus_glib_1_la_LDFLAGS): add -export-symbols-regex to the GLib library * dbus/dbus-object-tree.c (_dbus_object_tree_dispatch_and_unlock): fix the locking in here, and add a default handler for Introspect() that just returns sub-nodes. 2003-09-14 Havoc Pennington <hp@pobox.com> * glib/dbus-gthread.c (dbus_g_thread_init): rename to make g_foo rather than gfoo consistent * glib/dbus-gproxy.h: delete for now, move contents to dbus-glib.h, because the include files don't work right since we aren't in the dbus/ subdir. * glib/dbus-gproxy.c (dbus_gproxy_send): finish implementing (dbus_gproxy_end_call): finish (dbus_gproxy_begin_call): finish * glib/dbus-gmain.c (dbus_set_g_error): new * glib/dbus-gobject.c (handle_introspect): include information about child nodes in the introspection * dbus/dbus-connection.c (dbus_connection_list_registered): new function to help in implementation of introspection * dbus/dbus-object-tree.c (_dbus_object_tree_list_registered_and_unlock): new function 2003-09-12 Havoc Pennington <hp@pobox.com> * glib/dbus-gidl.h: add common base class for all the foo_info types * tools/dbus-viewer.c: add GTK-based introspection UI thingy similar to kdcop * test/Makefile.am: try test srcdir -ef . in addition to test srcdir = ., one of them should work (yeah lame) * glib/Makefile.am: build the "idl" parser stuff as a convenience library * glib/dbus-gparser.h: make description_load routines return NodeInfo* not Parser* * Makefile.am (SUBDIRS): build test dir after all library dirs * configure.in: add GTK+ detection
Diffstat (limited to 'glib')
-rw-r--r--glib/Makefile.am29
-rw-r--r--glib/dbus-gidl.c226
-rw-r--r--glib/dbus-gidl.h26
-rw-r--r--glib/dbus-glib.h71
-rw-r--r--glib/dbus-gloader-expat.c19
-rw-r--r--glib/dbus-gmain.c41
-rw-r--r--glib/dbus-gobject.c89
-rw-r--r--glib/dbus-gparser.c8
-rw-r--r--glib/dbus-gparser.h10
-rw-r--r--glib/dbus-gproxy.c101
-rw-r--r--glib/dbus-gtest.c4
-rw-r--r--glib/dbus-gtest.h1
-rw-r--r--glib/dbus-gthread.c2
13 files changed, 471 insertions, 156 deletions
diff --git a/glib/Makefile.am b/glib/Makefile.am
index 65d71cfd..a45aa593 100644
--- a/glib/Makefile.am
+++ b/glib/Makefile.am
@@ -5,8 +5,7 @@ dbusincludedir=$(includedir)/dbus-1.0/dbus
lib_LTLIBRARIES=libdbus-glib-1.la
dbusinclude_HEADERS= \
- dbus-glib.h \
- dbus-gproxy.h
+ dbus-glib.h
libdbus_glib_1_la_SOURCES = \
dbus-gmain.c \
@@ -14,23 +13,36 @@ libdbus_glib_1_la_SOURCES = \
dbus-gproxy.c \
dbus-gtest.c \
dbus-gtest.h \
- dbus-gthread.c
+ dbus-gthread.c \
+ dbus-gutils.c \
+ dbus-gutils.h
libdbus_glib_1_la_LIBADD= $(DBUS_GLIB_LIBS) $(top_builddir)/dbus/libdbus-1.la
+## don't export symbols that start with "_" (we use this
+## convention for internal symbols)
+libdbus_glib_1_la_LDFLAGS= -export-symbols-regex "^[^_].*"
-bin_PROGRAMS=dbus-glib-tool
+# convenience lib used here and by dbus-viewer
+noinst_LTLIBRARIES=libdbus-gtool.la
-dbus_glib_tool_SOURCES = \
+libdbus_gtool_la_SOURCES = \
dbus-gidl.c \
dbus-gidl.h \
- dbus-glib-tool.c \
dbus-gloader-expat.c \
dbus-gparser.c \
dbus-gparser.h \
- dbus-gtool-test.h
+ dbus-gutils.c \
+ dbus-gutils.h
+libdbus_gtool_la_LIBADD = libdbus-glib-1.la
-dbus_glib_tool_LDADD= $(DBUS_GLIB_TOOL_LIBS) libdbus-glib-1.la $(top_builddir)/dbus/libdbus-1.la
+bin_PROGRAMS=dbus-glib-tool
+
+dbus_glib_tool_SOURCES = \
+ dbus-glib-tool.c \
+ dbus-gtool-test.h
+
+dbus_glib_tool_LDADD= $(DBUS_GLIB_TOOL_LIBS) libdbus-gtool.la
if DBUS_BUILD_TESTS
@@ -54,3 +66,4 @@ else
TESTS=
endif
+
diff --git a/glib/dbus-gidl.c b/glib/dbus-gidl.c
index b867d178..596b43ca 100644
--- a/glib/dbus-gidl.c
+++ b/glib/dbus-gidl.c
@@ -26,43 +26,131 @@
#ifndef DOXYGEN_SHOULD_SKIP_THIS
-struct NodeInfo
+struct BaseInfo
{
- int refcount;
+ unsigned int refcount : 28;
+ unsigned int type : 4;
char *name;
+};
+
+struct NodeInfo
+{
+ BaseInfo base;
GSList *interfaces;
+ GSList *nodes;
};
struct InterfaceInfo
{
- int refcount;
- char *name;
+ BaseInfo base;
+ /* Since we have BaseInfo now these could be one list */
GSList *methods;
GSList *signals;
};
struct MethodInfo
{
- int refcount;
+ BaseInfo base;
GSList *args;
- char *name;
};
struct SignalInfo
{
- int refcount;
+ BaseInfo base;
GSList *args;
- char *name;
};
struct ArgInfo
{
- int refcount;
- char *name;
+ BaseInfo base;
int type;
ArgDirection direction;
};
+void
+base_info_ref (BaseInfo *info)
+{
+ g_return_if_fail (info != NULL);
+ g_return_if_fail (info->refcount > 0);
+
+ info->refcount += 1;
+}
+
+static void
+base_info_free (void *ptr)
+{
+ BaseInfo *info;
+
+ info = ptr;
+
+ g_free (info->name);
+ g_free (info);
+}
+
+void
+base_info_unref (BaseInfo *info)
+{
+ g_return_if_fail (info != NULL);
+ g_return_if_fail (info->refcount > 0);
+
+ /* This is sort of bizarre, BaseInfo was tacked on later */
+
+ switch (info->type)
+ {
+ case INFO_TYPE_NODE:
+ node_info_unref ((NodeInfo*) info);
+ break;
+ case INFO_TYPE_INTERFACE:
+ interface_info_unref ((InterfaceInfo*) info);
+ break;
+ case INFO_TYPE_SIGNAL:
+ signal_info_unref ((SignalInfo*) info);
+ break;
+ case INFO_TYPE_METHOD:
+ method_info_unref ((MethodInfo*) info);
+ break;
+ case INFO_TYPE_ARG:
+ arg_info_unref ((ArgInfo*) info);
+ break;
+ }
+}
+
+InfoType
+base_info_get_type (BaseInfo *info)
+{
+ return info->type;
+}
+
+const char*
+base_info_get_name (BaseInfo *info)
+{
+ return info->name;
+}
+
+void
+base_info_set_name (BaseInfo *info,
+ const char *name)
+{
+ char *old;
+
+ old = info->name;
+ info->name = g_strdup (name);
+ g_free (old);
+}
+
+GType
+base_info_get_gtype (void)
+{
+ static GType our_type = 0;
+
+ if (our_type == 0)
+ our_type = g_boxed_type_register_static ("BaseInfo",
+ (GBoxedCopyFunc) base_info_ref,
+ (GBoxedFreeFunc) base_info_unref);
+
+ return our_type;
+}
+
static void
free_interface_list (GSList **interfaces_p)
{
@@ -78,6 +166,20 @@ free_interface_list (GSList **interfaces_p)
}
static void
+free_node_list (GSList **nodes_p)
+{
+ GSList *tmp;
+ tmp = *nodes_p;
+ while (tmp != NULL)
+ {
+ node_info_unref (tmp->data);
+ tmp = tmp->next;
+ }
+ g_slist_free (*nodes_p);
+ *nodes_p = NULL;
+}
+
+static void
free_method_list (GSList **methods_p)
{
GSList *tmp;
@@ -113,34 +215,35 @@ node_info_new (const char *name)
/* name can be NULL */
info = g_new0 (NodeInfo, 1);
- info->refcount = 1;
- info->name = g_strdup (name);
-
+ info->base.refcount = 1;
+ info->base.name = g_strdup (name);
+ info->base.type = INFO_TYPE_NODE;
+
return info;
}
void
node_info_ref (NodeInfo *info)
{
- info->refcount += 1;
+ info->base.refcount += 1;
}
void
node_info_unref (NodeInfo *info)
{
- info->refcount -= 1;
- if (info->refcount == 0)
+ info->base.refcount -= 1;
+ if (info->base.refcount == 0)
{
free_interface_list (&info->interfaces);
- g_free (info->name);
- g_free (info);
+ free_node_list (&info->nodes);
+ base_info_free (info);
}
}
const char*
node_info_get_name (NodeInfo *info)
{
- return info->name;
+ return info->base.name;
}
GSList*
@@ -157,6 +260,19 @@ node_info_add_interface (NodeInfo *info,
info->interfaces = g_slist_append (info->interfaces, interface);
}
+GSList*
+node_info_get_nodes (NodeInfo *info)
+{
+ return info->nodes;
+}
+
+void
+node_info_add_node (NodeInfo *info,
+ NodeInfo *node)
+{
+ node_info_ref (node);
+ info->nodes = g_slist_append (info->nodes, node);
+}
InterfaceInfo*
interface_info_new (const char *name)
@@ -164,35 +280,35 @@ interface_info_new (const char *name)
InterfaceInfo *info;
info = g_new0 (InterfaceInfo, 1);
- info->refcount = 1;
- info->name = g_strdup (name);
-
+ info->base.refcount = 1;
+ info->base.name = g_strdup (name);
+ info->base.type = INFO_TYPE_INTERFACE;
+
return info;
}
void
interface_info_ref (InterfaceInfo *info)
{
- info->refcount += 1;
+ info->base.refcount += 1;
}
void
interface_info_unref (InterfaceInfo *info)
{
- info->refcount -= 1;
- if (info->refcount == 0)
+ info->base.refcount -= 1;
+ if (info->base.refcount == 0)
{
free_method_list (&info->methods);
free_signal_list (&info->signals);
- g_free (info->name);
- g_free (info);
+ base_info_free (info);
}
}
const char*
interface_info_get_name (InterfaceInfo *info)
{
- return info->name;
+ return info->base.name;
}
GSList*
@@ -243,34 +359,34 @@ method_info_new (const char *name)
MethodInfo *info;
info = g_new0 (MethodInfo, 1);
- info->refcount = 1;
- info->name = g_strdup (name);
-
+ info->base.refcount = 1;
+ info->base.name = g_strdup (name);
+ info->base.type = INFO_TYPE_METHOD;
+
return info;
}
void
method_info_ref (MethodInfo *info)
{
- info->refcount += 1;
+ info->base.refcount += 1;
}
void
method_info_unref (MethodInfo *info)
{
- info->refcount -= 1;
- if (info->refcount == 0)
+ info->base.refcount -= 1;
+ if (info->base.refcount == 0)
{
free_arg_list (&info->args);
- g_free (info->name);
- g_free (info);
+ base_info_free (info);
}
}
const char*
method_info_get_name (MethodInfo *info)
{
- return info->name;
+ return info->base.name;
}
GSList*
@@ -293,34 +409,34 @@ signal_info_new (const char *name)
SignalInfo *info;
info = g_new0 (SignalInfo, 1);
- info->refcount = 1;
- info->name = g_strdup (name);
-
+ info->base.refcount = 1;
+ info->base.name = g_strdup (name);
+ info->base.type = INFO_TYPE_SIGNAL;
+
return info;
}
void
signal_info_ref (SignalInfo *info)
{
- info->refcount += 1;
+ info->base.refcount += 1;
}
void
signal_info_unref (SignalInfo *info)
{
- info->refcount -= 1;
- if (info->refcount == 0)
+ info->base.refcount -= 1;
+ if (info->base.refcount == 0)
{
free_arg_list (&info->args);
- g_free (info->name);
- g_free (info);
+ base_info_free (info);
}
}
const char*
signal_info_get_name (SignalInfo *info)
{
- return info->name;
+ return info->base.name;
}
GSList*
@@ -345,10 +461,11 @@ arg_info_new (const char *name,
ArgInfo *info;
info = g_new0 (ArgInfo, 1);
- info->refcount = 1;
-
+ info->base.refcount = 1;
+ info->base.type = INFO_TYPE_ARG;
+
/* name can be NULL */
- info->name = g_strdup (name);
+ info->base.name = g_strdup (name);
info->direction = direction;
info->type = type;
@@ -358,23 +475,22 @@ arg_info_new (const char *name,
void
arg_info_ref (ArgInfo *info)
{
- info->refcount += 1;
+ info->base.refcount += 1;
}
void
arg_info_unref (ArgInfo *info)
{
- info->refcount -= 1;
- if (info->refcount == 0)
+ info->base.refcount -= 1;
+ if (info->base.refcount == 0)
{
- g_free (info->name);
- g_free (info);
+ base_info_free (info);
}
}
const char*
arg_info_get_name (ArgInfo *info)
{
- return info->name;
+ return info->base.name;
}
int
diff --git a/glib/dbus-gidl.h b/glib/dbus-gidl.h
index 7a667240..f95abfbd 100644
--- a/glib/dbus-gidl.h
+++ b/glib/dbus-gidl.h
@@ -27,10 +27,11 @@
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#include <dbus/dbus.h>
-#include <glib.h>
+#include <glib-object.h>
G_BEGIN_DECLS
+typedef struct BaseInfo BaseInfo;
typedef struct NodeInfo NodeInfo;
typedef struct InterfaceInfo InterfaceInfo;
typedef struct MethodInfo MethodInfo;
@@ -43,13 +44,36 @@ typedef enum
ARG_OUT
} ArgDirection;
+typedef enum
+{
+ INFO_TYPE_NODE,
+ INFO_TYPE_INTERFACE,
+ INFO_TYPE_METHOD,
+ INFO_TYPE_SIGNAL,
+ INFO_TYPE_ARG
+
+} InfoType;
+
+void base_info_ref (BaseInfo *info);
+void base_info_unref (BaseInfo *info);
+InfoType base_info_get_type (BaseInfo *info);
+const char* base_info_get_name (BaseInfo *info);
+void base_info_set_name (BaseInfo *info,
+ const char *name);
+GType base_info_get_gtype (void);
+#define BASE_INFO_TYPE (base_info_get_gtype ())
+
+
NodeInfo* node_info_new (const char *name);
void node_info_ref (NodeInfo *info);
void node_info_unref (NodeInfo *info);
const char* node_info_get_name (NodeInfo *info);
GSList* node_info_get_interfaces (NodeInfo *info);
+GSList* node_info_get_nodes (NodeInfo *info);
void node_info_add_interface (NodeInfo *info,
InterfaceInfo *interface);
+void node_info_add_node (NodeInfo *info,
+ NodeInfo *child);
InterfaceInfo* interface_info_new (const char *name);
void interface_info_ref (InterfaceInfo *info);
diff --git a/glib/dbus-glib.h b/glib/dbus-glib.h
index 4015dd99..63d34485 100644
--- a/glib/dbus-glib.h
+++ b/glib/dbus-glib.h
@@ -2,6 +2,7 @@
/* dbus-glib.h GLib integration
*
* Copyright (C) 2002, 2003 CodeFactory AB
+ * Copyright (C) 2003 Red Hat, Inc.
*
* Licensed under the Academic Free License version 1.2
*
@@ -30,7 +31,22 @@ G_BEGIN_DECLS
#define DBUS_INSIDE_DBUS_GLIB_H 1
-void dbus_gthread_init (void);
+GQuark dbus_g_error_quark (void);
+#define DBUS_GERROR dbus_g_error_quark ()
+
+typedef enum
+{
+ /* FIXME map all the DBUS_ERROR to DBUS_GERROR, should
+ * probably be automated in some way, perhaps
+ * via lame perl script
+ */
+ DBUS_GERROR_FAILED
+} DBusGError;
+
+void dbus_set_g_error (GError **gerror,
+ DBusError *derror);
+
+void dbus_g_thread_init (void);
void dbus_connection_setup_with_g_main (DBusConnection *connection,
GMainContext *context);
void dbus_server_setup_with_g_main (DBusServer *server,
@@ -63,14 +79,57 @@ struct DBusGObjectInfo
void *dbus_internal_padding2; /**< Reserved for expansion */
};
-void dbus_gobject_class_install_info (GObjectClass *object_class,
- const DBusGObjectInfo *info);
-void dbus_connection_register_gobject (DBusConnection *connection,
- const char *at_path,
- GObject *object);
+void dbus_g_object_class_install_info (GObjectClass *object_class,
+ const DBusGObjectInfo *info);
+void dbus_connection_register_g_object (DBusConnection *connection,
+ const char *at_path,
+ GObject *object);
+
+
+typedef struct DBusGProxy DBusGProxy;
+
+DBusGProxy* dbus_gproxy_new_for_service (DBusConnection *connection,
+ const char *service_name,
+ const char *interface_name);
+DBusGProxy* dbus_gproxy_new_for_service_owner (DBusConnection *connection,
+ const char *service_name,
+ const char *interface_name,
+ GError **error);
+DBusGProxy* dbus_gproxy_new_for_object_path (DBusConnection *connection,
+ const char *path,
+ const char *interface_name);
+DBusGProxy* dbus_gproxy_new_for_interface (DBusConnection *connection,
+ const char *interface_name);
+void dbus_gproxy_ref (DBusGProxy *proxy);
+void dbus_gproxy_unref (DBusGProxy *proxy);
+gboolean dbus_gproxy_connect_signal (DBusGProxy *proxy,
+ const char *signal_name,
+ GCallback callback,
+ void *data,
+ GFreeFunc free_data_func,
+ GError **error);
+DBusPendingCall* dbus_gproxy_begin_call (DBusGProxy *proxy,
+ const char *method,
+ int first_arg_type,
+ ...);
+gboolean dbus_gproxy_end_call (DBusGProxy *proxy,
+ DBusPendingCall *pending,
+ GError **error,
+ int first_arg_type,
+ ...);
+void dbus_gproxy_oneway_call (DBusGProxy *proxy,
+ const char *method,
+ int first_arg_type,
+ ...);
+void dbus_gproxy_send (DBusGProxy *proxy,
+ DBusMessage *message,
+ dbus_uint32_t *client_serial);
#undef DBUS_INSIDE_DBUS_GLIB_H
G_END_DECLS
#endif /* DBUS_GLIB_H */
+
+
+
diff --git a/glib/dbus-gloader-expat.c b/glib/dbus-gloader-expat.c
index 149e7117..01587d21 100644
--- a/glib/dbus-gloader-expat.c
+++ b/glib/dbus-gloader-expat.c
@@ -163,31 +163,32 @@ expat_CharacterDataHandler (void *userData,
s, len);
}
-Parser*
+NodeInfo*
description_load_from_file (const char *filename,
GError **error)
{
char *contents;
gsize len;
- Parser *parser;
+ NodeInfo *nodes;
contents = NULL;
if (!g_file_get_contents (filename, &contents, &len, error))
return NULL;
- parser = description_load_from_string (contents, len, error);
+ nodes = description_load_from_string (contents, len, error);
g_free (contents);
- return parser;
+ return nodes;
}
-Parser*
+NodeInfo*
description_load_from_string (const char *str,
int len,
GError **error)
{
XML_Parser expat;
ExpatParseContext context;
+ NodeInfo *nodes;
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
@@ -242,8 +243,11 @@ description_load_from_string (const char *str,
XML_ParserFree (expat);
g_string_free (context.content, TRUE);
- g_return_val_if_fail (error == NULL || *error == NULL, NULL);
- return context.parser;
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+ nodes = parser_get_nodes (context.parser);
+ node_info_ref (nodes);
+ parser_unref (context.parser);
+ return nodes;
failed:
g_return_val_if_fail (error == NULL || *error != NULL, NULL);
@@ -255,3 +259,4 @@ description_load_from_string (const char *str,
parser_unref (context.parser);
return NULL;
}
+
diff --git a/glib/dbus-gmain.c b/glib/dbus-gmain.c
index c33f47e8..2e5604dc 100644
--- a/glib/dbus-gmain.c
+++ b/glib/dbus-gmain.c
@@ -25,6 +25,10 @@
#include "dbus-glib.h"
#include "dbus-gtest.h"
+#include <libintl.h>
+#define _(x) dgettext (GETTEXT_PACKAGE, x)
+#define N_(x) x
+
/**
* @defgroup DBusGLib GLib bindings
* @ingroup DBus
@@ -494,6 +498,43 @@ dbus_server_setup_with_g_main (DBusServer *server,
g_error ("Not enough memory to set up DBusServer for use with GLib");
}
+/**
+ * The implementation of DBUS_GERROR error domain. See documentation
+ * for GError in GLib reference manual.
+ *
+ * @returns the error domain quark for use with GError
+ */
+GQuark
+dbus_g_error_quark (void)
+{
+ static GQuark quark = 0;
+ if (quark == 0)
+ quark = g_quark_from_static_string ("g-exec-error-quark");
+ return quark;
+}
+
+
+/**
+ * Set a GError return location from a DBusError.
+ *
+ * @todo expand the DBUS_GERROR enum and take advantage of it here
+ *
+ * @param gerror location to store a GError, or #NULL
+ * @param derror the DBusError
+ */
+void
+dbus_set_g_error (GError **gerror,
+ DBusError *derror)
+{
+ g_return_if_fail (derror != NULL);
+ g_return_if_fail (dbus_error_is_set (derror));
+
+ g_set_error (gerror, DBUS_GERROR,
+ DBUS_GERROR_FAILED,
+ _("D-BUS error %s: %s"),
+ derror->name, derror->message);
+}
+
/** @} */ /* end of public API */
#ifdef DBUS_BUILD_TESTS
diff --git a/glib/dbus-gobject.c b/glib/dbus-gobject.c
index b0f6c139..6e65770f 100644
--- a/glib/dbus-gobject.c
+++ b/glib/dbus-gobject.c
@@ -24,6 +24,7 @@
#include <config.h>
#include "dbus-glib.h"
#include "dbus-gtest.h"
+#include "dbus-gutils.h"
#include <string.h>
/**
@@ -102,6 +103,7 @@ gobject_unregister_function (DBusConnection *connection,
object = G_OBJECT (user_data);
+ /* FIXME */
}
@@ -187,6 +189,15 @@ handle_introspect (DBusConnection *connection,
unsigned int i;
GType last_type;
DBusMessage *ret;
+ char **path;
+ char **children;
+
+ if (!dbus_message_get_path_decomposed (message, &path))
+ g_error ("Out of memory");
+
+ if (!dbus_connection_list_registered (connection, (const char**) path,
+ &children))
+ g_error ("Out of memory");
xml = g_string_new (NULL);
@@ -268,13 +279,23 @@ handle_introspect (DBusConnection *connection,
g_free (specs);
+ /* Append child nodes */
+
+ i = 0;
+ while (children[i])
+ {
+ g_string_append_printf (xml, " <node name=\"%s\"/>\n",
+ children[i]);
+ ++i;
+ }
+
/* Close the XML, and send it to the requesting app */
g_string_append (xml, "</node>\n");
ret = dbus_message_new_method_return (message);
if (ret == NULL)
- g_error ("out of memory");
+ g_error ("Out of memory");
dbus_message_append_args (message,
DBUS_TYPE_STRING, xml->str,
@@ -285,6 +306,9 @@ handle_introspect (DBusConnection *connection,
g_string_free (xml, TRUE);
+ dbus_free_string_array (path);
+ dbus_free_string_array (children);
+
return DBUS_HANDLER_RESULT_HANDLED;
}
@@ -642,15 +666,15 @@ static DBusObjectPathVTable gobject_dbus_vtable = {
* class_init() for the object class.
*
* Once introspection information has been installed, instances of the
- * object registered with dbus_connection_register_gobject() can have
+ * object registered with dbus_connection_register_g_object() can have
* their methods invoked remotely.
*
* @param object_class class struct of the object
* @param info introspection data generated by dbus-glib-tool
*/
void
-dbus_gobject_class_install_info (GObjectClass *object_class,
- const DBusGObjectInfo *info)
+dbus_g_object_class_install_info (GObjectClass *object_class,
+ const DBusGObjectInfo *info)
{
g_return_if_fail (G_IS_OBJECT_CLASS (object_class));
@@ -666,55 +690,6 @@ dbus_gobject_class_install_info (GObjectClass *object_class,
g_static_mutex_unlock (&info_hash_mutex);
}
-static char**
-split_path (const char *path)
-{
- int len;
- char **split;
- int n_components;
- int i, j, comp;
-
- len = strlen (path);
-
- n_components = 0;
- i = 0;
- while (i < len)
- {
- if (path[i] == '/')
- n_components += 1;
- ++i;
- }
-
- split = g_new0 (char*, n_components + 1);
-
- comp = 0;
- i = 0;
- while (i < len)
- {
- if (path[i] == '/')
- ++i;
- j = i;
-
- while (j < len && path[j] != '/')
- ++j;
-
- /* Now [i, j) is the path component */
- g_assert (i < j);
- g_assert (path[i] != '/');
- g_assert (j == len || path[j] == '/');
-
- split[comp] = g_strndup (&path[i], j - i + 1);
-
- split[comp][j-i] = '\0';
-
- ++comp;
- i = j;
- }
- g_assert (i == len);
-
- return split;
-}
-
/**
* Registers a GObject at the given path. Properties, methods, and signals
* of the object can then be accessed remotely. Methods are only available
@@ -729,9 +704,9 @@ split_path (const char *path)
* @param object the object
*/
void
-dbus_connection_register_gobject (DBusConnection *connection,
- const char *at_path,
- GObject *object)
+dbus_connection_register_g_object (DBusConnection *connection,
+ const char *at_path,
+ GObject *object)
{
char **split;
@@ -739,7 +714,7 @@ dbus_connection_register_gobject (DBusConnection *connection,
g_return_if_fail (at_path != NULL);
g_return_if_fail (G_IS_OBJECT (object));
- split = split_path (at_path);
+ split = _dbus_gutils_split_path (at_path);
if (!dbus_connection_register_object_path (connection,
(const char**) split,
diff --git a/glib/dbus-gparser.c b/glib/dbus-gparser.c
index f7264b5e..16d17f3d 100644
--- a/glib/dbus-gparser.c
+++ b/glib/dbus-gparser.c
@@ -262,7 +262,15 @@ parse_node (Parser *parser,
return FALSE;
}
+
node = node_info_new (name);
+
+ if (parser->node_stack != NULL)
+ {
+ node_info_add_node (parser->node_stack->data,
+ node);
+ }
+
parser->node_stack = g_slist_prepend (parser->node_stack,
node);
diff --git a/glib/dbus-gparser.h b/glib/dbus-gparser.h
index 3e87165b..cc58e5e0 100644
--- a/glib/dbus-gparser.h
+++ b/glib/dbus-gparser.h
@@ -52,11 +52,11 @@ gboolean parser_content (Parser *parser,
gboolean parser_finished (Parser *parser,
GError **error);
-Parser* description_load_from_file (const char *filename,
- GError **error);
-Parser* description_load_from_string (const char *str,
- int len,
- GError **error);
+NodeInfo* description_load_from_file (const char *filename,
+ GError **error);
+NodeInfo* description_load_from_string (const char *str,
+ int len,
+ GError **error);
NodeInfo* parser_get_nodes (Parser *parser);
diff --git a/glib/dbus-gproxy.c b/glib/dbus-gproxy.c
index 8951707b..59d86a31 100644
--- a/glib/dbus-gproxy.c
+++ b/glib/dbus-gproxy.c
@@ -20,7 +20,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
-#include "dbus-gproxy.h"
+#include "dbus-glib.h"
/**
* @addtogroup DBusGLibInternals
@@ -165,23 +165,59 @@ dbus_gproxy_unref (DBusGProxy *proxy)
* To collect the results of the call (which may be an error,
* or a reply), use dbus_gproxy_end_call().
*
+ * @todo this particular function shouldn't die on out of memory,
+ * since you should be able to do a call with large arguments.
+ *
* @param proxy a proxy for a remote interface
* @param method the name of the method to invoke
* @param first_arg_type type of the first argument
*
* @returns opaque pending call object
- *
- */
+ * */
DBusPendingCall*
dbus_gproxy_begin_call (DBusGProxy *proxy,
const char *method,
int first_arg_type,
...)
{
+ DBusPendingCall *pending;
+ DBusMessage *message;
+ va_list args;
+
g_return_val_if_fail (proxy != NULL, NULL);
LOCK_PROXY (proxy);
+ message = dbus_message_new_method_call (proxy->service,
+ proxy->interface,
+ proxy->path,
+ method);
+ if (message == NULL)
+ goto oom;
+
+ va_start (args, first_arg_type);
+ if (!dbus_message_append_args_valist (message, first_arg_type,
+ args))
+ goto oom;
+ va_end (args);
+
+ if (!dbus_connection_send_with_reply (proxy->connection,
+ message,
+ &pending,
+ -1))
+ goto oom;
+
UNLOCK_PROXY (proxy);
+
+ return pending;
+
+ oom:
+ /* FIXME we should create a pending call that's
+ * immediately completed with an error status without
+ * ever going on the wire.
+ */
+
+ g_error ("Out of memory");
+ return NULL;
}
/**
@@ -189,7 +225,9 @@ dbus_gproxy_begin_call (DBusGProxy *proxy,
* initiated with dbus_gproxy_end_call(). This function will block if
* the results haven't yet been received; use
* dbus_pending_call_set_notify() to be notified asynchronously that a
- * pending call has been completed.
+ * pending call has been completed. Use
+ * dbus_pending_call_get_completed() to check whether a call has been
+ * completed. If it's completed, it will not block.
*
* If the call results in an error, the error is set as normal for
* GError and the function returns #FALSE.
@@ -198,12 +236,15 @@ dbus_gproxy_begin_call (DBusGProxy *proxy,
* method are stored in the provided varargs list.
* The list should be terminated with DBUS_TYPE_INVALID.
*
+ * This function doesn't affect the reference count of the
+ * #DBusPendingCall, the caller of dbus_gproxy_begin_call() still owns
+ * a reference.
+ *
* @param proxy a proxy for a remote interface
* @param pending the pending call from dbus_gproxy_begin_call()
* @param error return location for an error
* @param first_arg_type type of first "out" argument
- * @returns #FALSE if an error is set
- */
+ * @returns #FALSE if an error is set */
gboolean
dbus_gproxy_end_call (DBusGProxy *proxy,
DBusPendingCall *pending,
@@ -211,10 +252,37 @@ dbus_gproxy_end_call (DBusGProxy *proxy,
int first_arg_type,
...)
{
+ DBusMessage *message;
+ va_list args;
+ DBusError derror;
+
g_return_val_if_fail (proxy != NULL, FALSE);
+ g_return_val_if_fail (pending != NULL, FALSE);
+
LOCK_PROXY (proxy);
+ dbus_pending_call_block (pending);
+ message = dbus_pending_call_get_reply (pending);
+
+ g_assert (message != NULL);
+
+ dbus_error_init (&derror);
+ va_start (args, first_arg_type);
+ if (!dbus_message_get_args_valist (message, &derror, first_arg_type, args))
+ {
+ va_end (args);
+ goto error;
+ }
+ va_end (args);
+
UNLOCK_PROXY (proxy);
+
+ return TRUE;
+
+ error:
+ dbus_set_g_error (error, &derror);
+ dbus_error_free (&derror);
+ return FALSE;
}
/**
@@ -224,18 +292,17 @@ dbus_gproxy_end_call (DBusGProxy *proxy,
* dbus_connection_flush().
*
* The message is modified to be addressed to the target interface.
- * That is, a destination service field or whatever is needed
- * will be added to the message.
+ * That is, a destination service field or whatever is needed will be
+ * added to the message. The basic point of this function is to add
+ * the necessary header fields, otherwise it's equivalent to
+ * dbus_connection_send().
*
* This function adds a reference to the message, so the caller
* still owns its original reference.
- *
- * @todo fix for sending to interfaces and object IDs
*
* @param proxy a proxy for a remote interface
* @param message the message to address and send
- * @param client_serial return location for message's serial, or #NULL
- */
+ * @param client_serial return location for message's serial, or #NULL */
void
dbus_gproxy_send (DBusGProxy *proxy,
DBusMessage *message,
@@ -247,17 +314,19 @@ dbus_gproxy_send (DBusGProxy *proxy,
if (proxy->service)
{
if (!dbus_message_set_destination (message, proxy->service))
- g_error ("Out of memory\n");
+ g_error ("Out of memory");
}
if (proxy->interface)
{
- /* FIXME */
+ if (!dbus_message_set_interface (message, proxy->interface))
+ g_error ("Out of memory");
}
if (proxy->path)
{
- /* FIXME */
+ if (!dbus_message_set_path (message, proxy->path))
+ g_error ("Out of memory");
}
-
+
if (!dbus_connection_send (proxy->connection, message, client_serial))
g_error ("Out of memory\n");
diff --git a/glib/dbus-gtest.c b/glib/dbus-gtest.c
index b853d3ed..48cd13f0 100644
--- a/glib/dbus-gtest.c
+++ b/glib/dbus-gtest.c
@@ -56,6 +56,10 @@ dbus_glib_internal_do_not_use_run_tests (const char *test_data_dir)
else
printf ("No test data!\n");
+ printf ("%s: running utils tests\n", "dbus-glib-test");
+ if (!_dbus_gutils_test (test_data_dir))
+ die ("gutils");
+
printf ("%s: running mainloop integration tests\n", "dbus-glib-test");
if (!_dbus_gmain_test (test_data_dir))
die ("gmain");
diff --git a/glib/dbus-gtest.h b/glib/dbus-gtest.h
index 6a33bdae..1174eb0a 100644
--- a/glib/dbus-gtest.h
+++ b/glib/dbus-gtest.h
@@ -28,6 +28,7 @@
dbus_bool_t _dbus_gmain_test (const char *test_data_dir);
dbus_bool_t _dbus_gobject_test (const char *test_data_dir);
+dbus_bool_t _dbus_gutils_test (const char *test_data_dir);
void dbus_glib_internal_do_not_use_run_tests (const char *test_data_dir);
diff --git a/glib/dbus-gthread.c b/glib/dbus-gthread.c
index 71a3c1f5..eb3e5572 100644
--- a/glib/dbus-gthread.c
+++ b/glib/dbus-gthread.c
@@ -165,7 +165,7 @@ dbus_gcondvar_wake_all (DBusCondVar *cond)
* other function in the D-BUS API.
*/
void
-dbus_gthread_init (void)
+dbus_g_thread_init (void)
{
if (!g_thread_supported ())
g_error ("g_thread_init() must be called before dbus_threads_init()");