X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dbind%2Fdbind.c;h=f405888d9a16bc151dddcda42ed135d6b0d6939a;hb=c0a05e32cc6569d245747d192352ce2be3b4cddd;hp=1bbf0b0f5628fea1b3484e82cbdb70c11742b4dc;hpb=ab7d6456dca045823c928aedbb716748ea62885b;p=platform%2Fcore%2Fuifw%2Fat-spi2-atk.git diff --git a/dbind/dbind.c b/dbind/dbind.c index 1bbf0b0..f405888 100644 --- a/dbind/dbind.c +++ b/dbind/dbind.c @@ -1,143 +1,169 @@ -#include "config.h" + + #include -#define DBUS_API_SUBJECT_TO_CHANGE -#include -#include -#include #include +#include + +#include "config.h" +#include "dbind/dbind.h" /* * FIXME: compare types - to ensure they match & * do dynamic padding of structures etc. */ -struct _DBindContext { - DBusConnection *cnx; -}; +/*---------------------------------------------------------------------------*/ + +static void +set_reply (DBusPendingCall *pending, void *user_data) +{ + void **replyptr = (void **)user_data; + + *replyptr = dbus_pending_call_steal_reply (pending); +} + +static DBusMessage * +send_and_allow_reentry (DBusConnection *bus, DBusMessage *message, DBusError *error) +{ + 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; +} -DBindContext * -dbind_create_context (DBusBusType type, DBusError *opt_error) +dbus_bool_t +dbind_method_call_reentrant_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) { - DBindContext *ctx = NULL; - DBusConnection *cnx; + dbus_bool_t success = FALSE; + DBusMessage *msg = NULL, *reply = NULL; + DBusMessageIter iter; DBusError *err, real_err; - + const char *p; + 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); + msg = dbus_message_new_method_call (bus_name, path, interface, method); + if (!msg) + goto out; - return ctx; -} + p = arg_types; + dbus_message_iter_init_append (msg, &iter); + dbind_any_marshal_va (&iter, &p, args); -void -dbind_context_free (DBindContext *ctx) -{ - if (!ctx) - return; - dbus_connection_unref (ctx->cnx); - g_free (ctx); -} + reply = send_and_allow_reentry (cnx, msg, err); + if (!reply) + goto out; -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; + if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR) + { + const char *name = dbus_message_get_error_name (reply); + dbus_set_error (err, name, g_strdup ("")); + goto out; + } + /* demarshal */ + if (p[0] == '=' && p[1] == '>') + { + DBusMessageIter iter; + p += 2; + dbus_message_iter_init (reply, &iter); + dbind_any_demarshal_va (&iter, &p, args); + } - va_start (args, arg_types); + success = TRUE; +out: + if (msg) + dbus_message_unref (msg); - success = dbind_connection_method_call_va - (ctx->cnx, bus_name, path, interface, method, opt_error, arg_types, args); + if (reply) + dbus_message_unref (reply); - va_end (args); + if (err == &real_err) + dbus_error_free (err); return success; } +/** + * 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 (DBusConnection *cnx, - const char *bus_name, - const char *path, - const char *interface, - const char *method, - DBusError *opt_error, - const char *arg_types, - ...) +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; + dbus_bool_t success = FALSE; 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); - + success = dbind_method_call_reentrant_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) -{ - void **replyptr = (void **)user_data; - - *replyptr = dbus_pending_call_steal_reply (pending); -} - -static DBusMessage * -send_and_allow_reentry (DBusConnection *bus, DBusMessage *message, int timeout, 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; -} +/*---------------------------------------------------------------------------*/ 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_emit_signal_va (DBusConnection *cnx, + const char *path, + const char *interface, + const char *signal, + DBusError *opt_error, + const char *arg_types, + va_list args) { dbus_bool_t success = FALSE; - DBusMessage *msg = NULL, *reply = NULL; + DBusMessage *msg = NULL; + DBusMessageIter iter; DBusError *err, real_err; char *p; - char *dest; if (opt_error) err = opt_error; @@ -146,117 +172,59 @@ dbind_connection_method_call_va (DBusConnection *cnx, err = &real_err; } - msg = dbus_message_new_method_call (bus_name, path, interface, method); + msg = dbus_message_new_signal (path, interface, signal); 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); - } - } - 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); - } - if (!reply) - goto out; + p = arg_types; + dbus_message_iter_init_append (msg, &iter); + dbind_any_marshal_va (&iter, &p, args); - if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR) - { - char *name = dbus_message_get_error_name (reply); - dbus_set_error (err, name, g_strdup ("")); - goto out; - } - /* demarshal */ - if (p[0] == '=' && p[1] == '>') - { - 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); - } - } + if (!dbus_connection_send (cnx, msg, NULL)) + goto out; success = TRUE; out: + if (msg) dbus_message_unref (msg); - if (reply) - dbus_message_unref (reply); - if (err == &real_err) dbus_error_free (err); 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; + va_list args; + + va_start (args, arg_types); + success = dbind_emit_signal_va (cnx, path, interface, signal, opt_error, arg_types, args); + va_end (args); + + return success; +} + +/*END------------------------------------------------------------------------*/