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.
28 static DRouteInterface *
29 find_iface (DRouteData * data, const char *name)
33 for (l = data->interfaces; l; l = g_slist_next (l))
35 DRouteInterface *iface = (DRouteInterface *) l->data;
36 if (iface && iface->name && !strcmp (iface->name, name))
42 static DBusHandlerResult
43 prop_get_all (DBusConnection * bus, DBusMessage * message, DRouteData * data)
45 DRouteInterface *iface_def;
49 const char *path = dbus_message_get_path (message);
51 DBusMessageIter iter, iter_dict, iter_dict_entry;
53 dbus_error_init (&error);
54 if (!dbus_message_get_args
55 (message, &error, DBUS_TYPE_STRING, &iface, DBUS_TYPE_INVALID))
57 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
59 reply = dbus_message_new_method_return (message);
60 /* tbd: replace tbd with todo? */
63 dbus_message_iter_init_append (reply, &iter);
64 if (!dbus_message_iter_open_container
65 (&iter, DBUS_TYPE_ARRAY, "{sv}", &iter_dict))
67 iface_def = find_iface (data, iface);
69 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
70 if (iface_def->properties)
71 for (prop = iface_def->properties; prop->name; prop++)
75 if (!dbus_message_iter_open_container
76 (&iter_dict, DBUS_TYPE_DICT_ENTRY, NULL, &iter_dict_entry))
78 dbus_message_iter_append_basic (&iter_dict_entry, DBUS_TYPE_STRING,
80 (*prop->get) (path, &iter_dict_entry, data->user_data);
81 if (!dbus_message_iter_close_container (&iter_dict, &iter_dict_entry))
84 if (!dbus_message_iter_close_container (&iter, &iter_dict))
86 dbus_connection_send (bus, reply, NULL);
87 dbus_message_unref (reply);
88 return DBUS_HANDLER_RESULT_HANDLED;
90 /* tbd: return a standard out-of-memory error */
91 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
94 static DBusHandlerResult
95 prop (DBusConnection * bus, DBusMessage * message, DRouteData * data)
97 const char *mode = dbus_message_get_member (message);
98 const char *iface, *member;
99 const char *path = dbus_message_get_path (message);
102 DBusMessageIter iter;
103 DRouteInterface *iface_def;
104 DRouteProperty *prop = NULL;
106 if (!strcmp (mode, "Set"))
108 else if (!strcmp (mode, "Get"))
111 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
112 reply = dbus_message_new_method_return (message);
113 dbus_message_iter_init (message, &iter);
114 dbus_message_iter_get_basic (&iter, &iface);
115 dbus_message_iter_next (&iter);
116 dbus_message_iter_get_basic (&iter, &member);
118 dbus_message_iter_init_append (reply, &iter);
119 iface_def = find_iface (data, iface);
121 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
122 if (iface_def->properties)
123 for (prop = iface_def->properties;
124 prop->name && strcmp (prop->name, member); prop++)
125 if (!prop || !prop->name)
126 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
130 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
131 (*prop->set) (path, &iter, data->user_data);
136 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
137 (*prop->get) (path, &iter, data->user_data);
139 dbus_connection_send (bus, reply, NULL);
140 dbus_message_unref (reply);
141 return DBUS_HANDLER_RESULT_HANDLED;
145 droute_message (DBusConnection * bus, DBusMessage * message, void *user_data)
147 DRouteData *data = (DRouteData *) user_data;
148 DRouteInterface *iface_def;
149 DRouteMethod *method;
150 const char *iface = dbus_message_get_interface (message);
151 const char *member = dbus_message_get_member (message);
156 dbus_error_init (&error);
158 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
159 if (iface && !strcmp (iface, "org.freedesktop.DBus.Properties"))
161 if (!strcmp (member, "GetAll"))
162 return prop_get_all (bus, message, data);
163 return prop (bus, message, data);
167 iface_def = find_iface (data, iface);
169 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
170 if (iface_def->methods)
171 for (method = iface_def->methods; method->func; method++)
173 if (!strcmp (method->name, member))
176 (*method->func) (bus, message,
177 (method->wants_droute_data ? data : data->
181 dbus_connection_send (bus, reply, NULL);
182 dbus_message_unref (reply);
184 return DBUS_HANDLER_RESULT_HANDLED;
191 if (type == DBUS_MESSAGE_TYPE_SIGNAL)
192 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
193 for (l = data->interfaces; l; l = g_slist_next (l))
195 iface_def = (DRouteInterface *) l->data;
196 if (iface_def->methods)
197 for (method = iface_def->methods; method->func; method++)
199 if (!strcmp (method->name, member))
201 reply = (*method->func) (bus, message, data->user_data);
204 dbus_connection_send (bus, reply, NULL);
205 dbus_message_unref (reply);
207 return DBUS_HANDLER_RESULT_HANDLED;
212 return DBUS_HANDLER_RESULT_HANDLED;
216 droute_return_v_int32 (DBusMessageIter * iter, dbus_int32_t val)
220 if (!dbus_message_iter_open_container
221 (iter, DBUS_TYPE_VARIANT, DBUS_TYPE_INT32_AS_STRING, &sub))
225 dbus_message_iter_append_basic (&sub, DBUS_TYPE_INT32, &val);
226 dbus_message_iter_close_container (iter, &sub);
231 droute_return_v_double (DBusMessageIter * iter, double val)
235 if (!dbus_message_iter_open_container
236 (iter, DBUS_TYPE_VARIANT, DBUS_TYPE_DOUBLE_AS_STRING, &sub))
240 dbus_message_iter_append_basic (&sub, DBUS_TYPE_DOUBLE, &val);
241 dbus_message_iter_close_container (iter, &sub);
245 /* Return a string in a variant
246 * will return an empty string if passed a NULL value */
248 droute_return_v_string (DBusMessageIter * iter, const char *val)
254 if (!dbus_message_iter_open_container
255 (iter, DBUS_TYPE_VARIANT, DBUS_TYPE_STRING_AS_STRING, &sub))
259 dbus_message_iter_append_basic (&sub, DBUS_TYPE_STRING, &val);
260 dbus_message_iter_close_container (iter, &sub);
265 droute_get_v_int32 (DBusMessageIter * iter)
270 // TODO- ensure we have the correct type
271 dbus_message_iter_recurse (iter, &sub);
272 dbus_message_iter_get_basic (&sub, &rv);
277 droute_get_v_string (DBusMessageIter * iter)
282 // TODO- ensure we have the correct type
283 dbus_message_iter_recurse (iter, &sub);
284 dbus_message_iter_get_basic (&sub, &rv);
289 droute_return_v_object (DBusMessageIter * iter, const char *path)
293 if (!dbus_message_iter_open_container
294 (iter, DBUS_TYPE_VARIANT, DBUS_TYPE_OBJECT_PATH_AS_STRING, &sub))
298 dbus_message_iter_append_basic (&sub, DBUS_TYPE_OBJECT_PATH, &path);
299 dbus_message_iter_close_container (iter, &sub);
304 droute_add_interface (DRouteData * data, const char *name,
305 DRouteMethod * methods, DRouteProperty * properties,
306 DRouteGetDatumFunction get_datum,
307 DRouteFreeDatumFunction free_datum)
309 DRouteInterface *iface =
310 (DRouteInterface *) malloc (sizeof (DRouteInterface));
315 iface->name = strdup (name);
321 iface->methods = methods;
322 iface->properties = properties;
323 iface->get_datum = get_datum;
324 iface->free_datum = free_datum;
325 new_list = g_slist_append (data->interfaces, iface);
332 data->interfaces = new_list;