3 #define DBUS_API_SUBJECT_TO_CHANGE
4 #include <dbind/dbind.h>
5 #include <dbind/dbind-any.h>
10 * FIXME: compare types - to ensure they match &
11 * do dynamic padding of structures etc.
14 struct _DBindContext {
19 dbind_create_context (DBusBusType type, DBusError *opt_error)
21 DBindContext *ctx = NULL;
23 DBusError *err, real_err;
28 dbus_error_init (&real_err);
32 cnx = dbus_bus_get (DBUS_BUS_SESSION, err);
36 ctx = g_new0 (DBindContext, 1);
41 dbus_error_free (err);
47 dbind_context_free (DBindContext *ctx)
51 dbus_connection_unref (ctx->cnx);
56 dbind_context_method_call (DBindContext *ctx,
59 const char *interface,
62 const char *arg_types,
68 va_start (args, arg_types);
70 success = dbind_connection_method_call_va
71 (ctx->cnx, bus_name, path, interface, method, opt_error, arg_types, args);
79 dbind_connection_method_call (DBusConnection *cnx,
82 const char *interface,
85 const char *arg_types,
91 va_start (args, arg_types);
93 success = dbind_connection_method_call_va
94 (cnx, bus_name, path, interface, method, opt_error, arg_types, args);
101 static void set_reply (DBusPendingCall *pending, void *user_data)
103 void **replyptr = (void **)user_data;
105 *replyptr = dbus_pending_call_steal_reply (pending);
109 send_and_allow_reentry (DBusConnection *bus, DBusMessage *message, int timeout, DBusError *error)
111 DBusPendingCall *pending;
112 DBusMessage *reply = NULL;
114 if (!dbus_connection_send_with_reply (bus, message, &pending, timeout))
118 dbus_pending_call_set_notify (pending, set_reply, (void *)&reply, NULL);
121 if (!dbus_connection_read_write_dispatch (bus, timeout)) return NULL;
127 dbind_connection_method_call_va (DBusConnection *cnx,
128 const char *bus_name,
130 const char *interface,
132 DBusError *opt_error,
133 const char *arg_types,
136 dbus_bool_t success = FALSE;
137 DBusMessage *msg = NULL, *reply = NULL;
138 DBusError *err, real_err;
145 dbus_error_init (&real_err);
149 msg = dbus_message_new_method_call (bus_name, path, interface, method);
152 dbus_message_set_auto_start (msg, TRUE);
155 p = (char *)arg_types;
157 DBusMessageIter iter;
159 dbus_message_iter_init_append (msg, &iter);
160 /* special case base-types since we need to walk the stack worse-luck */
161 for (;*p != '\0' && *p != '=';) {
165 dbus_int64_t int64arg;
170 case DBUS_TYPE_BOOLEAN:
171 case DBUS_TYPE_INT16:
172 case DBUS_TYPE_UINT16:
173 case DBUS_TYPE_INT32:
174 case DBUS_TYPE_UINT32:
175 intarg = va_arg (args, int);
178 case DBUS_TYPE_INT64:
179 case DBUS_TYPE_UINT64:
180 int64arg = va_arg (args, dbus_int64_t);
183 case DBUS_TYPE_DOUBLE:
184 doublearg = va_arg (args, double);
188 case DBUS_TYPE_STRING:
189 case DBUS_TYPE_OBJECT_PATH:
190 case DBUS_TYPE_SIGNATURE:
191 case DBUS_TYPE_ARRAY:
192 case DBUS_TYPE_DICT_ENTRY:
193 ptrarg = va_arg (args, void *);
196 case DBUS_STRUCT_BEGIN_CHAR:
197 ptrarg = va_arg (args, void *);
201 case DBUS_TYPE_VARIANT:
202 fprintf (stderr, "No variant support yet - very toolkit specific\n");
203 ptrarg = va_arg (args, void *);
207 fprintf (stderr, "Unknown / invalid arg type %c\n", *p);
211 dbind_any_marshal (&iter, &p, &arg);
215 dest = dbus_message_get_destination(msg);
218 if (!strcmp (dbus_bus_get_unique_name(cnx), dest))
220 /* Can't use dbus_message_send_with_reply_and_block because it will
221 * not pass messages on to the provider side, causing deadlock */
222 reply = send_and_allow_reentry (cnx, msg, -1, err);
226 reply = dbus_connection_send_with_reply_and_block (cnx, msg, -1, err);
231 if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR)
233 char *name = dbus_message_get_error_name (reply);
234 dbus_set_error (err, name, g_strdup (""));
238 if (p[0] == '=' && p[1] == '>')
240 DBusMessageIter iter;
242 dbus_message_iter_init (reply, &iter);
244 void *arg = va_arg (args, void *);
245 dbind_any_demarshal (&iter, &p, &arg);
252 dbus_message_unref (msg);
255 dbus_message_unref (reply);
257 if (err == &real_err)
258 dbus_error_free (err);