diff options
author | Mark Doffman <mdoff@silver-wind.(none)> | 2008-12-07 23:13:13 +0000 |
---|---|---|
committer | Mark Doffman <mdoff@silver-wind.(none)> | 2008-12-07 23:13:13 +0000 |
commit | b37f0b74994912dea13f33d63d3f1395554944b2 (patch) | |
tree | 39eab0fbdbfb6700f31b5519c0203651346492ef /dbind | |
parent | 23b0b74622ee824e48793967555cdb2a50af039d (diff) | |
download | at-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.am | 4 | ||||
-rw-r--r-- | dbind/dbind-any.c | 438 | ||||
-rw-r--r-- | dbind/dbind-any.h | 15 | ||||
-rw-r--r-- | dbind/dbind.c | 321 | ||||
-rw-r--r-- | dbind/dbind.h | 48 | ||||
-rw-r--r-- | dbind/dbtest.c | 28 |
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; } |