Release v2.5.91
[platform/core/uifw/at-spi2-atk.git] / dbind / dbind.c
index 1bbf0b0..e186e98 100644 (file)
-#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;
-};
+/*---------------------------------------------------------------------------*/
+
+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;
+    const char *p;
 
     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------------------------------------------------------------------------*/