Add the droute and dbind libraries as static libraries within this repository.
[platform/core/uifw/at-spi2-atk.git] / dbind / dbind.c
1
2
3 #include <stdio.h>
4 #include <stdarg.h>
5 #include <glib.h>
6
7 #include "config.h"
8 #include "dbind/dbind.h"
9
10 /*
11  * FIXME: compare types - to ensure they match &
12  *        do dynamic padding of structures etc.
13  */
14
15 /*---------------------------------------------------------------------------*/
16
17 static void
18 set_reply (DBusPendingCall *pending, void *user_data)
19 {
20     void **replyptr = (void **)user_data;
21
22     *replyptr = dbus_pending_call_steal_reply (pending);
23 }
24
25 static DBusMessage *
26 send_and_allow_reentry (DBusConnection *bus, DBusMessage *message, DBusError *error)
27 {
28     DBusPendingCall *pending;
29     DBusMessage *reply = NULL;
30
31     if (!dbus_connection_send_with_reply (bus, message, &pending, -1))
32     {
33         return NULL;
34     }
35     dbus_pending_call_set_notify (pending, set_reply, (void *)&reply, NULL);
36     while (!reply)
37     {
38       if (!dbus_connection_read_write_dispatch (bus, -1)) return NULL;
39     }
40     return reply;
41 }
42
43 dbus_bool_t
44 dbind_method_call_reentrant_va (DBusConnection *cnx,
45                                 const char     *bus_name,
46                                 const char     *path,
47                                 const char     *interface,
48                                 const char     *method,
49                                 DBusError      *opt_error,
50                                 const char     *arg_types,
51                                 va_list         args)
52 {
53     dbus_bool_t success = FALSE;
54     DBusMessage *msg = NULL, *reply = NULL;
55     DBusMessageIter iter;
56     DBusError *err, real_err;
57     const char *p;
58
59     if (opt_error)
60         err = opt_error;
61     else {
62         dbus_error_init (&real_err);
63         err = &real_err;
64     }
65
66     msg = dbus_message_new_method_call (bus_name, path, interface, method);
67     if (!msg)
68         goto out;
69
70     p = arg_types;
71     dbus_message_iter_init_append (msg, &iter);
72     dbind_any_marshal_va (&iter, &p, args);
73
74     reply = send_and_allow_reentry (cnx, msg, err);
75     if (!reply)
76         goto out;
77
78     if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR)
79     {
80       const char *name = dbus_message_get_error_name (reply);
81       dbus_set_error (err, name, g_strdup (""));
82       goto out;
83     }
84     /* demarshal */
85     if (p[0] == '=' && p[1] == '>')
86     {
87         DBusMessageIter iter;
88         p += 2;
89         dbus_message_iter_init (reply, &iter);
90         dbind_any_demarshal_va (&iter, &p, args);
91     }
92
93     success = TRUE;
94 out:
95     if (msg)
96         dbus_message_unref (msg);
97
98     if (reply)
99         dbus_message_unref (reply);
100
101     if (err == &real_err)
102         dbus_error_free (err);
103
104     return success;
105 }
106
107 /**
108  * dbind_method_call_reentrant:
109  *
110  * @cnx:       A D-Bus Connection used to make the method call.
111  * @bus_name:  The D-Bus bus name of the program where the method call should
112  *             be made.
113  * @path:      The D-Bus object path that should handle the method.
114  * @interface: The D-Bus interface used to scope the method name.
115  * @method:    Method to be invoked.
116  * @opt_error: D-Bus error.
117  * @arg_types: Variable length arguments interleaving D-Bus argument types
118  *             and pointers to argument data.
119  *
120  * Makes a D-Bus method call using the supplied location data, method name and
121  * argument data.This function is re-entrant. It continuously reads from the D-Bus
122  * bus and dispatches messages until a reply has been recieved.
123  **/
124 dbus_bool_t
125 dbind_method_call_reentrant (DBusConnection *cnx,
126                              const char     *bus_name,
127                              const char     *path,
128                              const char     *interface,
129                              const char     *method,
130                              DBusError      *opt_error,
131                              const char     *arg_types,
132                              ...)
133 {
134     dbus_bool_t success = FALSE;
135     va_list args;
136
137     va_start (args, arg_types);
138     success = dbind_method_call_reentrant_va (cnx,
139                                               bus_name,
140                                               path,
141                                               interface,
142                                               method,
143                                               opt_error,
144                                               arg_types,
145                                               args);
146     va_end (args);
147
148     return success;
149 }
150
151 /*---------------------------------------------------------------------------*/
152
153 dbus_bool_t
154 dbind_emit_signal_va (DBusConnection *cnx,
155                       const char     *path,
156                       const char     *interface,
157                       const char     *signal,
158                       DBusError      *opt_error,
159                       const char     *arg_types,
160                       va_list         args)
161 {
162     dbus_bool_t success = FALSE;
163     DBusMessage *msg = NULL;
164     DBusMessageIter iter;
165     DBusError *err, real_err;
166     char *p;
167
168     if (opt_error)
169         err = opt_error;
170     else {
171         dbus_error_init (&real_err);
172         err = &real_err;
173     }
174
175     msg = dbus_message_new_signal (path, interface, signal);
176     if (!msg)
177         goto out;
178
179     p = arg_types;
180     dbus_message_iter_init_append (msg, &iter);
181     dbind_any_marshal_va (&iter, &p, args);
182
183     if (!dbus_connection_send (cnx, msg, NULL))
184        goto out;
185
186     success = TRUE;
187 out:
188
189     if (msg)
190         dbus_message_unref (msg);
191
192     if (err == &real_err)
193         dbus_error_free (err);
194
195     return success;
196 }
197
198 /**
199  * dbind_emit_signal:
200  *
201  * @cnx:       A D-Bus Connection used to make the method call.
202  * @path:      The D-Bus object path that this signal is emitted from.
203  * @interface: The D-Bus interface used to scope the method name.
204  * @signal:    Name of signal to emit.
205  * @opt_error: D-Bus error.
206  * @arg_types: Variable length arguments interleaving D-Bus argument types
207  *             and pointers to argument data.
208  *
209  * Emits a D-Bus signal  using the supplied signal name and argument data.
210  **/
211 dbus_bool_t
212 dbind_emit_signal (DBusConnection *cnx,
213                    const char     *path,
214                    const char     *interface,
215                    const char     *signal,
216                    DBusError      *opt_error,
217                    const char     *arg_types,
218                    ...)
219 {
220     dbus_bool_t success = FALSE;
221     va_list args;
222
223     va_start (args, arg_types);
224     success = dbind_emit_signal_va (cnx, path, interface, signal, opt_error, arg_types, args);
225     va_end (args);
226
227     return success;
228 }
229
230 /*END------------------------------------------------------------------------*/