2 * AT-SPI - Assistive Technology Service Provider Interface
3 * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
5 * Copyright 2008 Novell, Inc.
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
27 static DRouteInterface *
28 find_iface (DRouteData * data, const char *name)
32 for (l = data->interfaces; l; l = g_slist_next (l))
34 DRouteInterface *iface = (DRouteInterface *) l->data;
35 if (iface && iface->name && !strcmp (iface->name, name))
41 static DBusHandlerResult
42 prop_get_all (DBusConnection * bus, DBusMessage * message, DRouteData * data)
44 DRouteInterface *iface_def;
48 const char *path = dbus_message_get_path (message);
50 DBusMessageIter iter, iter_dict, iter_dict_entry;
52 dbus_error_init (&error);
53 if (!dbus_message_get_args
54 (message, &error, DBUS_TYPE_STRING, &iface, DBUS_TYPE_INVALID))
56 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
58 reply = dbus_message_new_method_return (message);
59 /* tbd: replace tbd with todo? */
62 dbus_message_iter_init_append (reply, &iter);
63 if (!dbus_message_iter_open_container
64 (&iter, DBUS_TYPE_ARRAY, "{sv}", &iter_dict))
66 iface_def = find_iface (data, iface);
68 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
69 if (iface_def->properties)
70 for (prop = iface_def->properties; prop->name; prop++)
74 if (!dbus_message_iter_open_container
75 (&iter_dict, DBUS_TYPE_DICT_ENTRY, NULL, &iter_dict_entry))
77 dbus_message_iter_append_basic (&iter_dict_entry, DBUS_TYPE_STRING,
79 (*prop->get) (path, &iter_dict_entry, data->user_data);
80 if (!dbus_message_iter_close_container (&iter_dict, &iter_dict_entry))
83 if (!dbus_message_iter_close_container (&iter, &iter_dict))
85 dbus_connection_send (bus, reply, NULL);
86 dbus_message_unref (reply);
87 return DBUS_HANDLER_RESULT_HANDLED;
89 /* tbd: return a standard out-of-memory error */
90 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
93 static DBusHandlerResult
94 prop (DBusConnection * bus, DBusMessage * message, DRouteData * data)
96 const char *mode = dbus_message_get_member (message);
97 const char *iface, *member;
98 const char *path = dbus_message_get_path (message);
101 DBusMessageIter iter;
102 DRouteInterface *iface_def;
103 DRouteProperty *prop = NULL;
105 if (!strcmp (mode, "Set"))
107 else if (!strcmp (mode, "Get"))
110 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
111 reply = dbus_message_new_method_return (message);
112 dbus_message_iter_init (message, &iter);
113 dbus_message_iter_get_basic (&iter, &iface);
114 dbus_message_iter_next (&iter);
115 dbus_message_iter_get_basic (&iter, &member);
117 dbus_message_iter_init_append (reply, &iter);
118 iface_def = find_iface (data, iface);
120 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
121 if (iface_def->properties)
122 for (prop = iface_def->properties;
123 prop->name && strcmp (prop->name, member); prop++)
124 if (!prop || !prop->name)
125 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
129 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
130 (*prop->set) (path, &iter, data->user_data);
135 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
136 (*prop->get) (path, &iter, data->user_data);
138 dbus_connection_send (bus, reply, NULL);
139 dbus_message_unref (reply);
140 return DBUS_HANDLER_RESULT_HANDLED;
144 droute_message (DBusConnection * bus, DBusMessage * message, void *user_data)
146 DRouteData *data = (DRouteData *) user_data;
147 DRouteInterface *iface_def;
148 DRouteMethod *method;
149 const char *iface = dbus_message_get_interface (message);
150 const char *member = dbus_message_get_member (message);
155 dbus_error_init (&error);
157 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
158 if (iface && !strcmp (iface, "org.freedesktop.DBus.Properties"))
160 if (!strcmp (member, "GetAll"))
161 return prop_get_all (bus, message, data);
162 return prop (bus, message, data);
166 iface_def = find_iface (data, iface);
168 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
169 if (iface_def->methods)
170 for (method = iface_def->methods; method->func; method++)
172 if (!strcmp (method->name, member))
175 (*method->func) (bus, message,
176 (method->wants_droute_data ? data : data->
180 dbus_connection_send (bus, reply, NULL);
181 dbus_message_unref (reply);
183 return DBUS_HANDLER_RESULT_HANDLED;
190 if (type == DBUS_MESSAGE_TYPE_SIGNAL)
191 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
192 for (l = data->interfaces; l; l = g_slist_next (l))
194 iface_def = (DRouteInterface *) l->data;
195 if (iface_def->methods)
196 for (method = iface_def->methods; method->func; method++)
198 if (!strcmp (method->name, member))
200 reply = (*method->func) (bus, message, data->user_data);
203 dbus_connection_send (bus, reply, NULL);
204 dbus_message_unref (reply);
206 return DBUS_HANDLER_RESULT_HANDLED;
211 return DBUS_HANDLER_RESULT_HANDLED;
215 droute_return_v_int32 (DBusMessageIter * iter, dbus_int32_t val)
219 if (!dbus_message_iter_open_container
220 (iter, DBUS_TYPE_VARIANT, DBUS_TYPE_INT32_AS_STRING, &sub))
224 dbus_message_iter_append_basic (&sub, DBUS_TYPE_INT32, &val);
225 dbus_message_iter_close_container (iter, &sub);
230 droute_return_v_double (DBusMessageIter * iter, double val)
234 if (!dbus_message_iter_open_container
235 (iter, DBUS_TYPE_VARIANT, DBUS_TYPE_DOUBLE_AS_STRING, &sub))
239 dbus_message_iter_append_basic (&sub, DBUS_TYPE_DOUBLE, &val);
240 dbus_message_iter_close_container (iter, &sub);
244 /* Return a string in a variant
245 * will return an empty string if passed a NULL value */
247 droute_return_v_string (DBusMessageIter * iter, const char *val)
253 if (!dbus_message_iter_open_container
254 (iter, DBUS_TYPE_VARIANT, DBUS_TYPE_STRING_AS_STRING, &sub))
258 dbus_message_iter_append_basic (&sub, DBUS_TYPE_STRING, &val);
259 dbus_message_iter_close_container (iter, &sub);
264 droute_get_v_int32 (DBusMessageIter * iter)
269 // TODO- ensure we have the correct type
270 dbus_message_iter_recurse (iter, &sub);
271 dbus_message_iter_get_basic (&sub, &rv);
276 droute_get_v_string (DBusMessageIter * iter)
281 // TODO- ensure we have the correct type
282 dbus_message_iter_recurse (iter, &sub);
283 dbus_message_iter_get_basic (&sub, &rv);
288 droute_return_v_object (DBusMessageIter * iter, const char *path)
292 if (!dbus_message_iter_open_container
293 (iter, DBUS_TYPE_VARIANT, DBUS_TYPE_OBJECT_PATH_AS_STRING, &sub))
297 dbus_message_iter_append_basic (&sub, DBUS_TYPE_OBJECT_PATH, &path);
298 dbus_message_iter_close_container (iter, &sub);
303 droute_add_interface (DRouteData * data, const char *name,
304 DRouteMethod * methods, DRouteProperty * properties,
305 DRouteGetDatumFunction get_datum,
306 DRouteFreeDatumFunction free_datum)
308 DRouteInterface *iface =
309 (DRouteInterface *) malloc (sizeof (DRouteInterface));
314 iface->name = strdup (name);
320 iface->methods = methods;
321 iface->properties = properties;
322 iface->get_datum = get_datum;
323 iface->free_datum = free_datum;
324 new_list = g_slist_append (data->interfaces, iface);
331 data->interfaces = new_list;