[seed] Start implementing the method call machinery for DBus module
- From: Robert Carr <racarr src gnome org>
- To: svn-commits-list gnome org
- Subject: [seed] Start implementing the method call machinery for DBus module
- Date: Sat, 9 May 2009 17:46:24 -0400 (EDT)
commit d7f083d8f653f333501b58765ad1460db0aaff1b
Author: Robert Carr <racarr svn gnome org>
Date: Sat May 9 17:46:09 2009 -0400
Start implementing the method call machinery for DBus module
---
modules/dbus/module.c | 190 +++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 190 insertions(+), 0 deletions(-)
diff --git a/modules/dbus/module.c b/modules/dbus/module.c
index 1a6599d..b0cf493 100644
--- a/modules/dbus/module.c
+++ b/modules/dbus/module.c
@@ -24,6 +24,196 @@ get_bus_type_from_object (SeedContext ctx,
return seed_value_to_int (ctx, jsbus_type, exception);
}
+
+static gboolean
+bus_check(SeedContext ctx, DBusBusType bus_type, SeedException *exception)
+{
+ gboolean bus_weakref_added;
+ DBusConnection **bus_connection;
+
+ bus_weakref_added = bus_type == DBUS_BUS_SESSION ? session_bus_weakref_added :
+ system_bus_weakref_added;
+
+ bus_connection = bus_type == DBUS_BUS_SESSION ? &session_bus : &system_bus;
+
+ /* This is all done lazily only if a dbus-related method is actually invoked */
+
+ if (!bus_weakref_added) {
+ big_dbus_add_bus_weakref(bus_type, bus_connection);
+ }
+
+ if (*bus_connection == NULL)
+ big_dbus_try_connecting_now(bus_type); /* force a synchronous connection attempt */
+
+ /* Throw exception if connection attempt failed */
+ if (*bus_connection == NULL) {
+ const char *bus_type_name = bus_type == DBUS_BUS_SESSION ? "session" : "system";
+ seed_make_exception(ctx, exception, "BusError",
+ "Not connected to %s message bus",
+ bus_type_name);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static DBusMessage*
+prepare_call(SeedContext ctx,
+ SeedObject obj,
+ guint argc,
+ SeedValue *argv,
+ DBusBusType bus_type,
+ SeedException *exception)
+{
+ DBusMessage *message;
+ const char *bus_name;
+ const char *path;
+ const char *interface;
+ const char *method;
+ gboolean auto_start;
+ const char *out_signature;
+ const char *in_signature;
+ DBusMessageIter arg_iter;
+ DBusSignatureIter sig_iter;
+
+ if (!bus_check(ctx, bus_type, exception))
+ return NULL;
+
+ bus_name = seed_value_to_string (ctx, argv[0], exception);
+ if (bus_name == NULL)
+ return NULL;
+
+ path = seed_value_to_string (ctx, argv[1], exception);
+ if (path == NULL)
+ return NULL;
+
+ if (seed_value_is_null(ctx, argv[2])) {
+ interface = NULL;
+ } else {
+ interface = seed_value_to_string (ctx, argv[2], exception);
+ if (interface == NULL)
+ return NULL; /* exception was set */
+ }
+
+ method = seed_value_to_string (ctx, argv[3], exception);
+ if (method == NULL)
+ return NULL;
+
+ out_signature = seed_value_to_string (ctx, argv[4], exception);
+ if (out_signature == NULL)
+ return NULL;
+
+ in_signature = seed_value_to_string (ctx, argv[5], exception);
+ if (in_signature == NULL)
+ return NULL;
+
+ g_assert(bus_name && path && method && in_signature && out_signature);
+
+ auto_start = seed_value_to_boolean(ctx, argv[6], exception);
+
+ /* FIXME should validate the bus_name, path, interface, method really, but
+ * we should just not write buggy JS ;-)
+ */
+
+ message = dbus_message_new_method_call(bus_name,
+ path,
+ interface,
+ method);
+ if (message == NULL)
+ {
+ seed_make_exception (ctx, exception, "DBusError", "Could not create new method call. (OOM?)");
+ return NULL;
+ }
+
+ dbus_message_set_auto_start(message, auto_start);
+
+ dbus_message_iter_init_append(message, &arg_iter);
+
+ if (in_signature)
+ dbus_signature_iter_init(&sig_iter, in_signature);
+ else
+ dbus_signature_iter_init(&sig_iter, "a{sv}");
+
+ if (!seed_js_values_to_dbus(ctx, 0, argv[8], &arg_iter, &sig_iter, exception)) {
+ // big_debug(BIG_DEBUG_JS_DBUS, "Failed to marshal call from JS to dbus");
+ dbus_message_unref(message);
+ return NULL;
+ }
+
+ return message;
+}
+
+static gboolean
+complete_call(SeedContext ctx,
+ SeedValue *retval,
+ DBusMessage *reply,
+ DBusError *derror,
+ SeedException *exception)
+{
+ DBusMessageIter arg_iter;
+ GArray *ret_values;
+ int array_length;
+
+ if (dbus_error_is_set(derror))
+ {
+ // big_debug(BIG_DEBUG_JS_DBUS,
+ // "Error sending call: %s: %s",
+ // derror->name, derror->message);
+ seed_make_exception(ctx, exception, "DBusError",
+ "DBus error: %s: %s",
+ derror->name,
+ derror->message);
+ dbus_error_free(derror);
+ return FALSE;
+ }
+
+ if (reply == NULL)
+ {
+ // big_debug(BIG_DEBUG_JS_DBUS,
+ // "No reply received to call");
+ return FALSE;
+ }
+
+ if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR)
+ {
+ seed_make_exception (ctx, exception, "DBusError",
+ "DBus error: %s: %s",
+ derror->name,
+ derror->message);
+ dbus_error_free(derror);
+
+ return FALSE;
+ }
+
+ dbus_message_iter_init(reply, &arg_iter);
+ if (!seed_js_values_from_dbus(ctx, &arg_iter, &ret_values, exception))
+ {
+ // big_debug(BIG_DEBUG_JS_DBUS, "Failed to marshal dbus call reply back to JS");
+ return FALSE;
+ }
+
+ g_assert(ret_values != NULL);
+ // TODO: I AM HERE
+
+ array_length = ret_values->len;
+ if (array_length == 1) {
+ /* If the array only has one element return that element alone */
+ *retval = g_array_index (ret_values, SeedValue, 0);
+ } else {
+ /* Otherwise return an array with all the return values. The
+ * funny assignment is to avoid creating a temporary JSObject
+ * we'd need to root
+ */
+ *retval = seed_make_array (ctx, ret_values->data, array_length, exception);
+ }
+
+ g_array_free (ret_values, TRUE);
+
+ seed_js_add_dbus_props(ctx, reply, *retval);
+
+ return TRUE;
+}
+
static SeedValue
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]