summaryrefslogtreecommitdiff
path: root/dbind
diff options
context:
space:
mode:
authorMark Doffman <mdoff@silver-wind.(none)>2008-12-07 23:13:13 +0000
committerMark Doffman <mdoff@silver-wind.(none)>2008-12-07 23:13:13 +0000
commitb37f0b74994912dea13f33d63d3f1395554944b2 (patch)
tree39eab0fbdbfb6700f31b5519c0203651346492ef /dbind
parent23b0b74622ee824e48793967555cdb2a50af039d (diff)
downloadat-spi2-core-b37f0b74994912dea13f33d63d3f1395554944b2.tar.gz
2008-12-07 Mark Doffman <mark.doffman@codethink.co.uk>
* dbind/* droute/* Complete refactoring droute to add api for creating single objects and object classes. Minor refactor of dbind, adding interface for marshalling signals.
Diffstat (limited to 'dbind')
-rw-r--r--dbind/Makefile.am4
-rw-r--r--dbind/dbind-any.c438
-rw-r--r--dbind/dbind-any.h15
-rw-r--r--dbind/dbind.c321
-rw-r--r--dbind/dbind.h48
-rw-r--r--dbind/dbtest.c28
6 files changed, 439 insertions, 415 deletions
diff --git a/dbind/Makefile.am b/dbind/Makefile.am
index 97365b85..cc2849e6 100644
--- a/dbind/Makefile.am
+++ b/dbind/Makefile.am
@@ -1,6 +1,6 @@
lib_LTLIBRARIES = libdbind.la
-INCLUDES = \
+AM_CPPFLAGS = \
-DG_LOG_DOMAIN=\"dbind\" \
-I$(top_srcdir) \
$(WARN_CFLAGS) \
@@ -21,4 +21,4 @@ TESTS = dbtest
check_PROGRAMS = dbtest
dbtest_SOURCES = dbtest.c
-dbtest_LDFLAGS = libdbind.la \ No newline at end of file
+dbtest_LDFLAGS = libdbind.la
diff --git a/dbind/dbind-any.c b/dbind/dbind-any.c
index 1f784e5e..83a87ba6 100644
--- a/dbind/dbind-any.c
+++ b/dbind/dbind-any.c
@@ -1,9 +1,9 @@
/* type driven marshalling */
-#include "config.h"
-#include "dbind-config.h"
-#define DBUS_API_SUBJECT_TO_CHANGE
#include <stdio.h>
#include <glib.h>
+
+#include "config.h"
+#include "dbind-config.h"
#include "dbind-any.h"
#undef DEBUG
@@ -24,10 +24,20 @@
((gpointer)ALIGN_VALUE(this, boundary))
#define PTR_PLUS(ptr, offset) \
- ((gpointer) (((guchar *)(ptr)) + (offset)))
+ ((gpointer) (((guchar *)(ptr)) + (offset)))
+
+#define DBIND_POD_CASES \
+ DBUS_TYPE_BYTE: \
+ case DBUS_TYPE_INT16: \
+ case DBUS_TYPE_UINT16: \
+ case DBUS_TYPE_INT32: \
+ case DBUS_TYPE_UINT32: \
+ case DBUS_TYPE_BOOLEAN: \
+ case DBUS_TYPE_INT64: \
+ case DBUS_TYPE_UINT64: \
+ case DBUS_TYPE_DOUBLE
-unsigned int dbind_find_c_alignment_r (char **type);
-unsigned int dbind_find_c_alignment (char *type);
+/*---------------------------------------------------------------------------*/
static void
warn_braces ()
@@ -36,26 +46,87 @@ warn_braces ()
" an explicit type member of 'struct'\n");
}
+/*---------------------------------------------------------------------------*/
+
+static unsigned int
+dbind_find_c_alignment_r (char **type)
+{
+ unsigned int retval = 1;
+
+ char t = **type;
+ (*type)++;
+
+#ifdef DEBUG
+ fprintf (stderr, "\tfind align for %c (0x%x)\n", t, t);
+#endif
+
+ switch (t) {
+ case DBUS_TYPE_BYTE:
+ return DBIND_ALIGNOF_CHAR;
+ case DBUS_TYPE_BOOLEAN:
+ return DBIND_ALIGNOF_DBUS_BOOL_T;
+ case DBUS_TYPE_INT16:
+ case DBUS_TYPE_UINT16:
+ return DBIND_ALIGNOF_DBUS_INT16_T;
+ case DBUS_TYPE_INT32:
+ case DBUS_TYPE_UINT32:
+ return DBIND_ALIGNOF_DBUS_INT32_T;
+ case DBUS_TYPE_INT64:
+ case DBUS_TYPE_UINT64:
+ return DBIND_ALIGNOF_DBUS_INT64_T;
+ case DBUS_TYPE_DOUBLE:
+ return DBIND_ALIGNOF_DOUBLE;
+ /* ptr types */
+ case DBUS_TYPE_STRING:
+ case DBUS_TYPE_OBJECT_PATH:
+ case DBUS_TYPE_SIGNATURE:
+ case DBUS_TYPE_ARRAY:
+ return DBIND_ALIGNOF_DBIND_POINTER;
+ case DBUS_STRUCT_BEGIN_CHAR:
+#if DBIND_ALIGNOF_DBIND_STRUCT > 1
+ retval = MAX (retval, DBIND_ALIGNOF_DBIND_STRUCT);
+#endif
+ while (**type != DBUS_STRUCT_END_CHAR) {
+ int elem_align = dbind_find_c_alignment_r (type);
+ retval = MAX (retval, elem_align);
+ }
+ (*type)++;
+ return retval;
+ case DBUS_TYPE_STRUCT:
+ case DBUS_TYPE_DICT_ENTRY:
+ warn_braces ();
+ return DBIND_ALIGNOF_DBIND_POINTER;
+ case '\0':
+ g_assert_not_reached();
+ break;
+ default:
+ return 1;
+ }
+}
+
+/*---------------------------------------------------------------------------*/
+
/* gather immediate allocation information for this type */
-size_t dbind_gather_alloc_info_r (char **type)
+static size_t
+dbind_gather_alloc_info_r (char **type)
{
char t = **type;
(*type)++;
if (t == DBUS_TYPE_ARRAY) {
- switch (**type) {
- case DBUS_STRUCT_BEGIN_CHAR:
- while (**type != DBUS_STRUCT_END_CHAR && **type != '\0') (*type)++;
- if (**type != '\0') (*type)++;
- break;
- case '\0':
- break;
- default:
- (*type)++;
- break;
- }
- }
-
- switch (t) {
+ switch (**type) {
+ case DBUS_STRUCT_BEGIN_CHAR:
+ while (**type != DBUS_STRUCT_END_CHAR && **type != '\0') (*type)++;
+ if (**type != '\0') (*type)++;
+ break;
+ case '\0':
+ break;
+ default:
+ (*type)++;
+ break;
+ }
+ }
+
+ switch (t) {
case DBUS_TYPE_BYTE:
return sizeof (char);
case DBUS_TYPE_BOOLEAN:
@@ -78,106 +149,114 @@ size_t dbind_gather_alloc_info_r (char **type)
case DBUS_TYPE_ARRAY:
return sizeof (void *);
case DBUS_STRUCT_BEGIN_CHAR: {
- int sum = 0, stralign;
+ int sum = 0, stralign;
stralign = dbind_find_c_alignment (*type - 1);
while (**type != DBUS_STRUCT_END_CHAR) {
- sum = ALIGN_VALUE (sum, dbind_find_c_alignment (*type));
- sum += dbind_gather_alloc_info_r (type);
+ sum = ALIGN_VALUE (sum, dbind_find_c_alignment (*type));
+ sum += dbind_gather_alloc_info_r (type);
}
- sum = ALIGN_VALUE (sum, stralign);
+ sum = ALIGN_VALUE (sum, stralign);
g_assert (**type == DBUS_STRUCT_END_CHAR);
(*type)++;
- return sum;
+ return sum;
}
case DBUS_TYPE_STRUCT:
case DBUS_TYPE_DICT_ENTRY:
warn_braces ();
- default:
- return 0;
- }
+ default:
+ return 0;
+ }
}
-size_t dbind_gather_alloc_info (char *type)
+static size_t
+dbind_gather_alloc_info (char *type)
{
return dbind_gather_alloc_info_r (&type);
}
-unsigned int
-dbind_find_c_alignment_r (char **type)
-{
- unsigned int retval = 1;
+/*---------------------------------------------------------------------------*/
- char t = **type;
- (*type)++;
+static void
+dbind_any_free_r (char **type, void **data)
+{
+ size_t len;
#ifdef DEBUG
- fprintf (stderr, "\tfind align for %c (0x%x)\n", t, t);
+ fprintf (stderr, "any free '%c' to %p\n", **type, *data);
#endif
- switch (t) {
- case DBUS_TYPE_BYTE:
- return DBIND_ALIGNOF_CHAR;
- case DBUS_TYPE_BOOLEAN:
- return DBIND_ALIGNOF_DBUS_BOOL_T;
- case DBUS_TYPE_INT16:
- case DBUS_TYPE_UINT16:
- return DBIND_ALIGNOF_DBUS_INT16_T;
- case DBUS_TYPE_INT32:
- case DBUS_TYPE_UINT32:
- return DBIND_ALIGNOF_DBUS_INT32_T;
- case DBUS_TYPE_INT64:
- case DBUS_TYPE_UINT64:
- return DBIND_ALIGNOF_DBUS_INT64_T;
- case DBUS_TYPE_DOUBLE:
- return DBIND_ALIGNOF_DOUBLE;
- /* ptr types */
+ switch (**type) {
+ case DBIND_POD_CASES:
+ *data = ((guchar *)*data) + dbind_gather_alloc_info (*type);
+ (*type)++;
+ break;
case DBUS_TYPE_STRING:
case DBUS_TYPE_OBJECT_PATH:
case DBUS_TYPE_SIGNATURE:
- case DBUS_TYPE_ARRAY:
- return DBIND_ALIGNOF_DBIND_POINTER;
- case DBUS_STRUCT_BEGIN_CHAR:
-#if DBIND_ALIGNOF_DBIND_STRUCT > 1
- retval = MAX (retval, DBIND_ALIGNOF_DBIND_STRUCT);
+#ifdef DEBUG
+ fprintf (stderr, "string free %p\n", **(void ***)data);
#endif
+ g_free (**(void ***)data);
+ *data = ((guchar *)*data) + dbind_gather_alloc_info (*type);
+ (*type)++;
+ break;
+ case DBUS_TYPE_ARRAY: {
+ int i;
+ GArray *vals = **(void ***)data;
+ size_t elem_size, elem_align;
+ char *saved_child_type, *child_type_string;
+
+ (*type)++;
+ saved_child_type = *type;
+
+ elem_size = dbind_gather_alloc_info (*type);
+ elem_align = dbind_find_c_alignment_r (type);
+
+ for (i = 0; i < vals->len; i++) {
+ void *ptr = vals->data + elem_size * i;
+ *type = saved_child_type; /* rewind type info */
+ ptr = ALIGN_ADDRESS (ptr, elem_align);
+ dbind_any_free_r (type, &ptr);
+ }
+ g_array_free (vals, TRUE);
+ break;
+ }
+ case DBUS_STRUCT_BEGIN_CHAR: {
+ gconstpointer data0 = *data;
+ int offset = 0, stralign;
+
+ stralign = dbind_find_c_alignment (*type);
+ (*type)++;
+
+ offset = 0 ;
while (**type != DBUS_STRUCT_END_CHAR) {
- int elem_align = dbind_find_c_alignment_r (type);
- retval = MAX (retval, elem_align);
+ char *subt = *type;
+ offset = ALIGN_VALUE (offset, dbind_find_c_alignment (*type));
+ *data = PTR_PLUS (data0, offset);
+ dbind_any_free_r (type, data);
+ offset += dbind_gather_alloc_info (subt);
}
+
+ offset = ALIGN_VALUE (offset, stralign);
+ *data = PTR_PLUS (data0, offset);
+
+ g_assert (**type == DBUS_STRUCT_END_CHAR);
(*type)++;
- return retval;
+
+ break;
+ }
case DBUS_TYPE_STRUCT:
case DBUS_TYPE_DICT_ENTRY:
warn_braces ();
- return DBIND_ALIGNOF_DBIND_POINTER;
- case '\0':
- g_assert_not_reached();
break;
- default:
- return 1;
- }
+ }
}
-unsigned int
-dbind_find_c_alignment (char *type)
-{
- return dbind_find_c_alignment_r (&type);
-}
-
-#define DBIND_POD_CASES \
- DBUS_TYPE_BYTE: \
- case DBUS_TYPE_INT16: \
- case DBUS_TYPE_UINT16: \
- case DBUS_TYPE_INT32: \
- case DBUS_TYPE_UINT32: \
- case DBUS_TYPE_BOOLEAN: \
- case DBUS_TYPE_INT64: \
- case DBUS_TYPE_UINT64: \
- case DBUS_TYPE_DOUBLE
+/*---------------------------------------------------------------------------*/
void
dbind_any_marshal (DBusMessageIter *iter,
@@ -215,7 +294,7 @@ dbind_any_marshal (DBusMessageIter *iter,
/* wow this part of the API sucks too ... */
child_type_string = g_strndup (saved_child_type, *type - saved_child_type);
-/* fprintf (stderr, "array child type '%s'\n", child_type_string); */
+ /* fprintf (stderr, "array child type '%s'\n", child_type_string); */
dbus_message_iter_open_container (iter, DBUS_TYPE_ARRAY,
child_type_string, &sub);
for (i = 0; i < vals->len; i++) {
@@ -230,8 +309,8 @@ dbind_any_marshal (DBusMessageIter *iter,
break;
}
case DBUS_STRUCT_BEGIN_CHAR: {
- gconstpointer data0 = *data;
- int offset = 0, stralign;
+ gconstpointer data0 = *data;
+ int offset = 0, stralign;
DBusMessageIter sub;
stralign = dbind_find_c_alignment (*type);
@@ -243,14 +322,14 @@ dbind_any_marshal (DBusMessageIter *iter,
offset = 0 ;
while (**type != DBUS_STRUCT_END_CHAR) {
char *subt = *type;
- offset = ALIGN_VALUE (offset, dbind_find_c_alignment (*type));
- *data = PTR_PLUS (data0, offset);
+ offset = ALIGN_VALUE (offset, dbind_find_c_alignment (*type));
+ *data = PTR_PLUS (data0, offset);
dbind_any_marshal (&sub, type, data);
offset += dbind_gather_alloc_info (subt);
}
- offset = ALIGN_VALUE (offset, stralign);
- *data = PTR_PLUS (data0, offset);
+ offset = ALIGN_VALUE (offset, stralign);
+ *data = PTR_PLUS (data0, offset);
dbus_message_iter_close_container (iter, &sub);
@@ -266,6 +345,73 @@ dbind_any_marshal (DBusMessageIter *iter,
}
}
+/*---------------------------------------------------------------------------*/
+
+void
+dbind_any_marshal_va (DBusMessageIter *iter,
+ char **arg_types,
+ va_list args)
+{
+ char *p = *arg_types;
+ {
+ /* special case base-types since we need to walk the stack worse-luck */
+ for (;*p != '\0' && *p != '=';) {
+ int intarg;
+ void *ptrarg;
+ double doublearg;
+ dbus_int64_t int64arg;
+ void *arg = NULL;
+
+ switch (*p) {
+ case DBUS_TYPE_BYTE:
+ case DBUS_TYPE_BOOLEAN:
+ case DBUS_TYPE_INT16:
+ case DBUS_TYPE_UINT16:
+ case DBUS_TYPE_INT32:
+ case DBUS_TYPE_UINT32:
+ intarg = va_arg (args, int);
+ arg = &intarg;
+ break;
+ case DBUS_TYPE_INT64:
+ case DBUS_TYPE_UINT64:
+ int64arg = va_arg (args, dbus_int64_t);
+ arg = &int64arg;
+ break;
+ case DBUS_TYPE_DOUBLE:
+ doublearg = va_arg (args, double);
+ arg = &doublearg;
+ break;
+ /* ptr types */
+ case DBUS_TYPE_STRING:
+ case DBUS_TYPE_OBJECT_PATH:
+ case DBUS_TYPE_SIGNATURE:
+ case DBUS_TYPE_ARRAY:
+ case DBUS_TYPE_DICT_ENTRY:
+ ptrarg = va_arg (args, void *);
+ arg = &ptrarg;
+ break;
+ case DBUS_STRUCT_BEGIN_CHAR:
+ ptrarg = va_arg (args, void *);
+ arg = ptrarg;
+ break;
+
+ case DBUS_TYPE_VARIANT:
+ fprintf (stderr, "No variant support yet - very toolkit specific\n");
+ ptrarg = va_arg (args, void *);
+ arg = &ptrarg;
+ break;
+ default:
+ fprintf (stderr, "Unknown / invalid arg type %c\n", *p);
+ break;
+ }
+ if (arg != NULL)
+ dbind_any_marshal (iter, &p, &arg);
+ }
+ }
+}
+
+/*---------------------------------------------------------------------------*/
+
void
dbind_any_demarshal (DBusMessageIter *iter,
char **type,
@@ -305,13 +451,13 @@ dbind_any_demarshal (DBusMessageIter *iter,
(*type)++;
stored_child_type = *type;
-
+
elem_size = dbind_gather_alloc_info (*type);
elem_align = dbind_find_c_alignment_r (type);
vals = g_array_new (FALSE, FALSE, elem_size);
(**(void ***)data) = vals;
*data = ((guchar *)*data) + sizeof (void *);
-
+
i = 0;
dbus_message_iter_recurse (iter, &child);
while (dbus_message_iter_get_arg_type (&child) != DBUS_TYPE_INVALID) {
@@ -326,8 +472,8 @@ dbind_any_demarshal (DBusMessageIter *iter,
break;
}
case DBUS_STRUCT_BEGIN_CHAR: {
- gconstpointer data0 = *data;
- int offset = 0, stralign;
+ gconstpointer data0 = *data;
+ int offset = 0, stralign;
DBusMessageIter child;
stralign = dbind_find_c_alignment (*type);
@@ -338,14 +484,14 @@ dbind_any_demarshal (DBusMessageIter *iter,
while (**type != DBUS_STRUCT_END_CHAR) {
char *subt = *type;
- offset = ALIGN_VALUE (offset, dbind_find_c_alignment (*type));
- *data = PTR_PLUS (data0, offset);
+ offset = ALIGN_VALUE (offset, dbind_find_c_alignment (*type));
+ *data = PTR_PLUS (data0, offset);
dbind_any_demarshal (&child, type, data);
offset += dbind_gather_alloc_info (subt);
}
- offset = ALIGN_VALUE (offset, stralign);
- *data = PTR_PLUS (data0, offset);
+ offset = ALIGN_VALUE (offset, stralign);
+ *data = PTR_PLUS (data0, offset);
g_assert (**type == DBUS_STRUCT_END_CHAR);
(*type)++;
@@ -360,82 +506,22 @@ dbind_any_demarshal (DBusMessageIter *iter,
dbus_message_iter_next (iter);
}
-static void
-dbind_any_free_r (char **type, void **data)
-{
- size_t len;
-
-#ifdef DEBUG
- fprintf (stderr, "any free '%c' to %p\n", **type, *data);
-#endif
-
- switch (**type) {
- case DBIND_POD_CASES:
- *data = ((guchar *)*data) + dbind_gather_alloc_info (*type);
- (*type)++;
- break;
- case DBUS_TYPE_STRING:
- case DBUS_TYPE_OBJECT_PATH:
- case DBUS_TYPE_SIGNATURE:
-#ifdef DEBUG
- fprintf (stderr, "string free %p\n", **(void ***)data);
-#endif
- g_free (**(void ***)data);
- *data = ((guchar *)*data) + dbind_gather_alloc_info (*type);
- (*type)++;
- break;
- case DBUS_TYPE_ARRAY: {
- int i;
- GArray *vals = **(void ***)data;
- size_t elem_size, elem_align;
- char *saved_child_type, *child_type_string;
-
- (*type)++;
- saved_child_type = *type;
-
- elem_size = dbind_gather_alloc_info (*type);
- elem_align = dbind_find_c_alignment_r (type);
-
- for (i = 0; i < vals->len; i++) {
- void *ptr = vals->data + elem_size * i;
- *type = saved_child_type; /* rewind type info */
- ptr = ALIGN_ADDRESS (ptr, elem_align);
- dbind_any_free_r (type, &ptr);
- }
- g_array_free (vals, TRUE);
- break;
- }
- case DBUS_STRUCT_BEGIN_CHAR: {
- gconstpointer data0 = *data;
- int offset = 0, stralign;
+/*---------------------------------------------------------------------------*/
- stralign = dbind_find_c_alignment (*type);
- (*type)++;
-
- offset = 0 ;
- while (**type != DBUS_STRUCT_END_CHAR) {
- char *subt = *type;
- offset = ALIGN_VALUE (offset, dbind_find_c_alignment (*type));
- *data = PTR_PLUS (data0, offset);
- dbind_any_free_r (type, data);
- offset += dbind_gather_alloc_info (subt);
- }
-
- offset = ALIGN_VALUE (offset, stralign);
- *data = PTR_PLUS (data0, offset);
-
- g_assert (**type == DBUS_STRUCT_END_CHAR);
- (*type)++;
-
- break;
- }
- case DBUS_TYPE_STRUCT:
- case DBUS_TYPE_DICT_ENTRY:
- warn_braces ();
- break;
+void
+dbind_any_demarshal_va (DBusMessageIter *iter,
+ char **arg_types,
+ va_list args)
+{
+ char *p = *arg_types;
+ for (;*p != '\0';) {
+ void *arg = va_arg (args, void *);
+ dbind_any_demarshal (iter, &p, &arg);
}
}
+/*---------------------------------------------------------------------------*/
+
/* nice deep free ... */
void
dbind_any_free (char *type,
@@ -450,3 +536,13 @@ dbind_any_free_ptr (char *type, void *ptr)
{
dbind_any_free (type, &ptr);
}
+
+/*---------------------------------------------------------------------------*/
+
+unsigned int
+dbind_find_c_alignment (char *type)
+{
+ return dbind_find_c_alignment_r (&type);
+}
+
+/*END------------------------------------------------------------------------*/
diff --git a/dbind/dbind-any.h b/dbind/dbind-any.h
index ce6482e7..975b244b 100644
--- a/dbind/dbind-any.h
+++ b/dbind/dbind-any.h
@@ -1,17 +1,30 @@
#ifndef _DBIND_ANY_H_
#define _DBIND_ANY_H_
+#define DBUS_API_SUBJECT_TO_CHANGE
#include <dbus/dbus.h>
-size_t dbind_gather_alloc_info (char *type);
+unsigned int dbind_find_c_alignment (char *type);
+
void dbind_any_marshal (DBusMessageIter *iter,
char **type,
void **val);
+
+void dbind_any_marshal_va (DBusMessageIter *iter,
+ char **arg_types,
+ va_list args);
+
void dbind_any_demarshal (DBusMessageIter *iter,
char **type,
void **val);
+
+void dbind_any_demarshal_va (DBusMessageIter *iter,
+ char **arg_types,
+ va_list args);
+
void dbind_any_free (char *type,
void *ptr_to_ptr);
+
void dbind_any_free_ptr (char *type,
void *ptr);
diff --git a/dbind/dbind.c b/dbind/dbind.c
index 1bbf0b0f..f34bcc47 100644
--- a/dbind/dbind.c
+++ b/dbind/dbind.c
@@ -1,143 +1,80 @@
-#include "config.h"
+
+
#include <stdio.h>
-#define DBUS_API_SUBJECT_TO_CHANGE
-#include <dbind/dbind.h>
-#include <dbind/dbind-any.h>
-#include <glib.h>
#include <stdarg.h>
+#include <glib.h>
+
+#include "config.h"
+#include "dbind/dbind.h"
/*
* FIXME: compare types - to ensure they match &
* do dynamic padding of structures etc.
*/
-struct _DBindContext {
- DBusConnection *cnx;
-};
-
-DBindContext *
-dbind_create_context (DBusBusType type, DBusError *opt_error)
-{
- DBindContext *ctx = NULL;
- DBusConnection *cnx;
- DBusError *err, real_err;
-
- if (opt_error)
- err = opt_error;
- else {
- dbus_error_init (&real_err);
- err = &real_err;
- }
-
- cnx = dbus_bus_get (DBUS_BUS_SESSION, err);
- if (!cnx)
- goto out;
-
- ctx = g_new0 (DBindContext, 1);
- ctx->cnx = cnx;
-
-out:
- if (err == &real_err)
- dbus_error_free (err);
-
- return ctx;
-}
-
-void
-dbind_context_free (DBindContext *ctx)
-{
- if (!ctx)
- return;
- dbus_connection_unref (ctx->cnx);
- g_free (ctx);
-}
-
-dbus_bool_t
-dbind_context_method_call (DBindContext *ctx,
- const char *bus_name,
- const char *path,
- const char *interface,
- const char *method,
- DBusError *opt_error,
- const char *arg_types,
- ...)
-{
- dbus_bool_t success;
- va_list args;
-
- va_start (args, arg_types);
-
- success = dbind_connection_method_call_va
- (ctx->cnx, bus_name, path, interface, method, opt_error, arg_types, args);
-
- va_end (args);
-
- return success;
-}
-
-dbus_bool_t
-dbind_connection_method_call (DBusConnection *cnx,
- const char *bus_name,
- const char *path,
- const char *interface,
- const char *method,
- DBusError *opt_error,
- const char *arg_types,
- ...)
-{
- dbus_bool_t success;
- va_list args;
-
- va_start (args, arg_types);
-
- success = dbind_connection_method_call_va
- (cnx, bus_name, path, interface, method, opt_error, arg_types, args);
+/*---------------------------------------------------------------------------*/
- va_end (args);
-
- return success;
-}
-
-static void set_reply (DBusPendingCall *pending, void *user_data)
+static void
+set_reply (DBusPendingCall *pending, void *user_data)
{
- void **replyptr = (void **)user_data;
+ void **replyptr = (void **)user_data;
- *replyptr = dbus_pending_call_steal_reply (pending);
+ *replyptr = dbus_pending_call_steal_reply (pending);
}
static DBusMessage *
-send_and_allow_reentry (DBusConnection *bus, DBusMessage *message, int timeout, DBusError *error)
+send_and_allow_reentry (DBusConnection *bus, DBusMessage *message, DBusError *error)
{
- DBusPendingCall *pending;
- DBusMessage *reply = NULL;
-
- if (!dbus_connection_send_with_reply (bus, message, &pending, timeout))
- {
- return NULL;
- }
- dbus_pending_call_set_notify (pending, set_reply, (void *)&reply, NULL);
- while (!reply)
- {
- if (!dbus_connection_read_write_dispatch (bus, timeout)) return NULL;
- }
- return reply;
+ DBusPendingCall *pending;
+ DBusMessage *reply = NULL;
+
+ if (!dbus_connection_send_with_reply (bus, message, &pending, -1))
+ {
+ return NULL;
+ }
+ dbus_pending_call_set_notify (pending, set_reply, (void *)&reply, NULL);
+ while (!reply)
+ {
+ if (!dbus_connection_read_write_dispatch (bus, -1)) return NULL;
+ }
+ return reply;
}
+/**
+ * dbind_method_call_reentrant:
+ *
+ * @cnx: A D-Bus Connection used to make the method call.
+ * @bus_name: The D-Bus bus name of the program where the method call should
+ * be made.
+ * @path: The D-Bus object path that should handle the method.
+ * @interface: The D-Bus interface used to scope the method name.
+ * @method: Method to be invoked.
+ * @opt_error: D-Bus error.
+ * @arg_types: Variable length arguments interleaving D-Bus argument types
+ * and pointers to argument data.
+ *
+ * Makes a D-Bus method call using the supplied location data, method name and
+ * argument data.This function is re-entrant. It continuously reads from the D-Bus
+ * bus and dispatches messages until a reply has been recieved.
+ **/
dbus_bool_t
-dbind_connection_method_call_va (DBusConnection *cnx,
- const char *bus_name,
- const char *path,
- const char *interface,
- const char *method,
- DBusError *opt_error,
- const char *arg_types,
- va_list args)
+dbind_method_call_reentrant (DBusConnection *cnx,
+ const char *bus_name,
+ const char *path,
+ const char *interface,
+ const char *method,
+ DBusError *opt_error,
+ const char *arg_types,
+ ...)
{
dbus_bool_t success = FALSE;
DBusMessage *msg = NULL, *reply = NULL;
+ DBusMessageIter iter;
DBusError *err, real_err;
char *p;
- char *dest;
+ va_list args;
+
+ va_start (args, arg_types);
if (opt_error)
err = opt_error;
@@ -149,88 +86,17 @@ dbind_connection_method_call_va (DBusConnection *cnx,
msg = dbus_message_new_method_call (bus_name, path, interface, method);
if (!msg)
goto out;
- dbus_message_set_auto_start (msg, TRUE);
- /* marshal */
- p = (char *)arg_types;
- {
- DBusMessageIter iter;
-
- dbus_message_iter_init_append (msg, &iter);
- /* special case base-types since we need to walk the stack worse-luck */
- for (;*p != '\0' && *p != '=';) {
- int intarg;
- void *ptrarg;
- double doublearg;
- dbus_int64_t int64arg;
- void *arg = NULL;
-
- switch (*p) {
- case DBUS_TYPE_BYTE:
- case DBUS_TYPE_BOOLEAN:
- case DBUS_TYPE_INT16:
- case DBUS_TYPE_UINT16:
- case DBUS_TYPE_INT32:
- case DBUS_TYPE_UINT32:
- intarg = va_arg (args, int);
- arg = &intarg;
- break;
- case DBUS_TYPE_INT64:
- case DBUS_TYPE_UINT64:
- int64arg = va_arg (args, dbus_int64_t);
- arg = &int64arg;
- break;
- case DBUS_TYPE_DOUBLE:
- doublearg = va_arg (args, double);
- arg = &doublearg;
- break;
- /* ptr types */
- case DBUS_TYPE_STRING:
- case DBUS_TYPE_OBJECT_PATH:
- case DBUS_TYPE_SIGNATURE:
- case DBUS_TYPE_ARRAY:
- case DBUS_TYPE_DICT_ENTRY:
- ptrarg = va_arg (args, void *);
- arg = &ptrarg;
- break;
- case DBUS_STRUCT_BEGIN_CHAR:
- ptrarg = va_arg (args, void *);
- arg = ptrarg;
- break;
-
- case DBUS_TYPE_VARIANT:
- fprintf (stderr, "No variant support yet - very toolkit specific\n");
- ptrarg = va_arg (args, void *);
- arg = &ptrarg;
- break;
- default:
- fprintf (stderr, "Unknown / invalid arg type %c\n", *p);
- break;
- }
- if (arg != NULL)
- dbind_any_marshal (&iter, &p, &arg);
- }
- }
+ dbus_message_iter_init (msg, &iter);
+ dbind_any_marshal_va (&iter, &p, args);
- dest = dbus_message_get_destination(msg);
- if (!dest)
- goto out;
- if (!strcmp (dbus_bus_get_unique_name(cnx), dest))
- {
- /* Can't use dbus_message_send_with_reply_and_block because it will
- * not pass messages on to the provider side, causing deadlock */
- reply = send_and_allow_reentry (cnx, msg, -1, err);
- }
- else
- {
- reply = dbus_connection_send_with_reply_and_block (cnx, msg, -1, err);
- }
+ reply = send_and_allow_reentry (cnx, msg, err);
if (!reply)
goto out;
if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR)
{
- char *name = dbus_message_get_error_name (reply);
+ const char *name = dbus_message_get_error_name (reply);
dbus_set_error (err, name, g_strdup (""));
goto out;
}
@@ -240,14 +106,13 @@ dbind_connection_method_call_va (DBusConnection *cnx,
DBusMessageIter iter;
p += 2;
dbus_message_iter_init (reply, &iter);
- for (;*p != '\0';) {
- void *arg = va_arg (args, void *);
- dbind_any_demarshal (&iter, &p, &arg);
- }
+ dbind_any_demarshal_va (&iter, &p, args);
}
success = TRUE;
out:
+ va_end (args);
+
if (msg)
dbus_message_unref (msg);
@@ -260,3 +125,67 @@ out:
return success;
}
+/*---------------------------------------------------------------------------*/
+
+/**
+ * dbind_emit_signal:
+ *
+ * @cnx: A D-Bus Connection used to make the method call.
+ * @path: The D-Bus object path that this signal is emitted from.
+ * @interface: The D-Bus interface used to scope the method name.
+ * @signal: Name of signal to emit.
+ * @opt_error: D-Bus error.
+ * @arg_types: Variable length arguments interleaving D-Bus argument types
+ * and pointers to argument data.
+ *
+ * Emits a D-Bus signal using the supplied signal name and argument data.
+ **/
+dbus_bool_t
+dbind_emit_signal (DBusConnection *cnx,
+ const char *path,
+ const char *interface,
+ const char *signal,
+ DBusError *opt_error,
+ const char *arg_types,
+ ...)
+{
+ dbus_bool_t success = FALSE;
+ DBusMessage *msg = NULL;
+ DBusMessageIter iter;
+ DBusError *err, real_err;
+ char *p;
+ va_list args;
+
+ va_start (args, arg_types);
+
+ if (opt_error)
+ err = opt_error;
+ else {
+ dbus_error_init (&real_err);
+ err = &real_err;
+ }
+
+ msg = dbus_message_new_signal (path, interface, signal);
+ if (!msg)
+ goto out;
+
+ dbus_message_iter_init (msg, &iter);
+ dbind_any_marshal_va (&iter, &p, args);
+
+ if (!dbus_connection_send (cnx, msg, NULL))
+ goto out;
+
+ success = TRUE;
+out:
+ va_end (args);
+
+ if (msg)
+ dbus_message_unref (msg);
+
+ if (err == &real_err)
+ dbus_error_free (err);
+
+ return success;
+}
+
+/*END------------------------------------------------------------------------*/
diff --git a/dbind/dbind.h b/dbind/dbind.h
index 4e663594..0f6cec85 100644
--- a/dbind/dbind.h
+++ b/dbind/dbind.h
@@ -1,39 +1,27 @@
#ifndef _DBIND_H_
#define _DBIND_H_
-
#define DBUS_API_SUBJECT_TO_CHANGE
#include <dbus/dbus.h>
+#include <dbind/dbind-any.h>
-typedef struct _DBindContext DBindContext;
-
-DBindContext *dbind_create_context (DBusBusType type, DBusError *opt_error);
-void dbind_context_free (DBindContext *ctx);
-dbus_bool_t dbind_context_method_call (DBindContext *ctx,
- const char *bus_name,
- const char *path,
- const char *interface,
- const char *method,
- DBusError *opt_error,
- const char *arg_types,
- ...);
+dbus_bool_t
+dbind_method_call_reentrant (DBusConnection *cnx,
+ const char *bus_name,
+ const char *path,
+ const char *interface,
+ const char *method,
+ DBusError *opt_error,
+ const char *arg_types,
+ ...);
-/* dbus connection variants */
-dbus_bool_t dbind_connection_method_call (DBusConnection *cnx,
- const char *bus_name,
- const char *path,
- const char *interface,
- const char *method,
- DBusError *opt_error,
- const char *arg_types,
- ...);
-dbus_bool_t dbind_connection_method_call_va (DBusConnection *cnx,
- const char *bus_name,
- const char *path,
- const char *interface,
- const char *method,
- DBusError *opt_error,
- const char *arg_types,
- va_list args);
+dbus_bool_t
+dbind_emit_signal (DBusConnection *cnx,
+ const char *path,
+ const char *interface,
+ const char *signal,
+ DBusError *opt_error,
+ const char *arg_types,
+ ...);
#endif /* _DBIND_H_ */
diff --git a/dbind/dbtest.c b/dbind/dbtest.c
index 9a3ae869..8203c275 100644
--- a/dbind/dbtest.c
+++ b/dbind/dbtest.c
@@ -1,9 +1,7 @@
#include <stdio.h>
#include <glib.h>
#include <string.h>
-#define DBUS_API_SUBJECT_TO_CHANGE
#include <dbind/dbind.h>
-#include <dbind/dbind-any.h>
/* Wow! dbus is unpleasant to use */
@@ -341,7 +339,7 @@ void test_marshalling ()
fprintf (stderr, "Marshalling ok\n");
}
-void test_teamspaces (DBindContext *ctx)
+void test_teamspaces (DBusConnection *bus)
{
GArray *spaces;
DBusError error;
@@ -353,9 +351,14 @@ void test_teamspaces (DBindContext *ctx)
} TeamSpace;
dbus_error_init (&error);
- if (!dbind_context_method_call (ctx, NULL, DESKICE_PATH, DESKICE_NAMESPACE,
- "GetTeamList", &error,
- "=>a(sss)", &spaces)) {
+ if (!dbind_method_call_reentrant (bus,
+ NULL,
+ DESKICE_PATH,
+ DESKICE_NAMESPACE,
+ "GetTeamList",
+ &error,
+ "=>a(sss)",
+ &spaces)) {
fprintf (stderr, "Error getting team spaces %s: %s\n",
error.name, error.message);
dbus_error_free (&error);
@@ -375,8 +378,6 @@ void test_teamspaces (DBindContext *ctx)
dbind_any_free_ptr ("a(sss)", spaces);
}
-extern dbind_find_c_alignment (char *type);
-
void test_helpers ()
{
dbind_find_c_alignment ("(sss)");
@@ -387,17 +388,14 @@ void test_helpers ()
int main (int argc, char **argv)
{
- DBindContext *ctx;
+ DBusConnection *bus;
+ DBusError err;
- ctx = dbind_create_context (DBUS_BUS_SESSION, NULL);
- if (!ctx)
- return 1;
+ bus = dbus_bus_get (DBUS_BUS_SESSION, &err);
test_helpers ();
test_marshalling ();
- test_teamspaces (ctx);
-
- dbind_context_free (ctx);
+ test_teamspaces (bus);
return 0;
}