2 * AT-SPI - Assistive Technology Service Provider Interface
3 * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
5 * Copyright 2008 Novell, Inc.
6 * Copyright 2001, 2002 Sun Microsystems Inc.,
7 * Copyright 2001, 2002 Ximian, Inc.
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
19 * You should have received a copy of the GNU Library General Public
20 * License along with this library; if not, write to the
21 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 * Boston, MA 02111-1307, USA.
28 #include <droute/droute.h>
31 #include "spi-common/spi-dbus.h"
34 static gboolean update_pending = FALSE;
36 /*---------------------------------------------------------------------------*/
39 append_atk_object_interfaces (AtkObject *object, DBusMessageIter *iter)
43 itf = SPI_DBUS_INTERFACE_ACCESSIBLE;
44 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
46 if (ATK_IS_ACTION (object))
48 itf = SPI_DBUS_INTERFACE_ACTION;
49 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
52 if (ATK_IS_COMPONENT (object))
54 itf = SPI_DBUS_INTERFACE_COMPONENT;
55 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
58 if (ATK_IS_EDITABLE_TEXT (object))
60 itf = SPI_DBUS_INTERFACE_EDITABLE_TEXT;
61 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
64 if (ATK_IS_TEXT (object))
66 itf = SPI_DBUS_INTERFACE_TEXT;
67 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
70 if (ATK_IS_HYPERTEXT (object))
72 itf = SPI_DBUS_INTERFACE_HYPERTEXT;
73 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
76 if (ATK_IS_IMAGE (object))
78 itf = SPI_DBUS_INTERFACE_IMAGE;
79 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
82 if (ATK_IS_SELECTION (object))
84 itf = SPI_DBUS_INTERFACE_SELECTION;
85 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
88 if (ATK_IS_TABLE (object))
90 itf = SPI_DBUS_INTERFACE_TABLE;
91 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
94 if (ATK_IS_VALUE (object))
96 itf = SPI_DBUS_INTERFACE_VALUE;
97 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
100 if (ATK_IS_STREAMABLE_CONTENT (object))
102 itf = "org.freedesktop.atspi.StreamableContent";
103 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
106 if (ATK_IS_DOCUMENT (object))
108 itf = "org.freedesktop.atspi.Collection";
109 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
110 itf = SPI_DBUS_INTERFACE_DOCUMENT;
111 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
114 if (ATK_IS_HYPERLINK_IMPL (object))
116 itf = SPI_DBUS_INTERFACE_HYPERLINK;
117 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
121 /*---------------------------------------------------------------------------*/
123 static const char *dumm = "/APath/1";
126 * Marshals the given AtkObject into the provided D-Bus iterator.
128 * The object is marshalled including all its client side cache data.
129 * The format of the structure is (ooaoassusau).
130 * This is used in the updateTree signal and the getTree method
131 * of the org.freedesktop.atspi.Tree interface.
134 append_accessible(gpointer ref, gpointer obj_data, gpointer iter)
137 DBusMessageIter *iter_array;
138 DBusMessageIter iter_struct, iter_sub_array;
139 dbus_int32_t states [2];
142 const char *name, *desc;
147 obj = ATK_OBJECT(obj_data);
148 iter_array = (DBusMessageIter *) iter;
150 dbus_message_iter_open_container (iter_array, DBUS_TYPE_STRUCT, NULL, &iter_struct);
153 gchar *path, *path_parent;
155 path = atk_dbus_get_path_from_ref(GPOINTER_TO_INT(ref));
156 dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_OBJECT_PATH, &path);
158 parent = atk_object_get_parent(obj);
160 path_parent = g_strdup("/");
162 path_parent = atk_dbus_get_path (parent);
163 dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_OBJECT_PATH, &path_parent);
166 dbus_message_iter_open_container (&iter_struct, DBUS_TYPE_ARRAY, "o", &iter_sub_array);
170 childcount = atk_object_get_n_accessible_children (obj);
171 for (i = 0; i < childcount; i++)
176 child = atk_object_ref_accessible_child (obj, i);
177 child_path = atk_dbus_get_path (child);
178 g_object_unref(G_OBJECT(child));
179 dbus_message_iter_append_basic (&iter_sub_array, DBUS_TYPE_OBJECT_PATH, &child_path);
183 dbus_message_iter_close_container (&iter_struct, &iter_sub_array);
185 dbus_message_iter_open_container (&iter_struct, DBUS_TYPE_ARRAY, "s", &iter_sub_array);
186 append_atk_object_interfaces (obj, &iter_sub_array);
187 dbus_message_iter_close_container (&iter_struct, &iter_sub_array);
189 name = atk_object_get_name (obj);
192 dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &name);
194 role = spi_accessible_role_from_atk_role (atk_object_get_role (obj));
195 dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_UINT32, &role);
197 desc = atk_object_get_description (obj);
200 dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &desc);
204 spi_atk_state_to_dbus_array (obj, &states);
205 dbus_message_iter_open_container (&iter_struct, DBUS_TYPE_ARRAY, "u", &iter_sub_array);
206 for (count = 0; count < 2; count++)
207 dbus_message_iter_append_basic (&iter_sub_array, DBUS_TYPE_UINT32, &states[count]);
208 dbus_message_iter_close_container (&iter_struct, &iter_sub_array);
209 dbus_message_iter_close_container (iter_array, &iter_struct);
212 /*---------------------------------------------------------------------------*/
215 * Used to marshal array of objects to remove.
216 * Marshalls an object path onto the iter provided.
219 append_accessible_path(gpointer ref_data, gpointer null, gpointer data)
223 DBusMessageIter *iter_array;
225 iter_array = (DBusMessageIter *) data;
226 ref = GPOINTER_TO_INT(ref_data);
227 path = atk_dbus_get_path_from_ref(ref);
228 dbus_message_iter_append_basic (iter_array, DBUS_TYPE_OBJECT_PATH, &path);
232 /*---------------------------------------------------------------------------*/
235 send_cache_update(gpointer data)
237 DBusMessage *message;
238 DBusMessageIter iter;
239 DBusMessageIter iter_array;
240 DBusConnection *bus = (DBusConnection *) data;
242 message = dbus_message_new_signal ("/org/freedesktop/atspi/tree", SPI_DBUS_INTERFACE_TREE, "updateTree");
244 dbus_message_iter_init_append (message, &iter);
246 dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "(ooaoassusau)", &iter_array);
247 atk_dbus_foreach_update_list(append_accessible, &iter_array);
248 dbus_message_iter_close_container(&iter, &iter_array);
250 dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "o", &iter_array);
251 atk_dbus_foreach_remove_list(append_accessible_path, &iter_array);
252 dbus_message_iter_close_container(&iter, &iter_array);
254 dbus_connection_send(bus, message, NULL);
255 update_pending = FALSE;
260 /*---------------------------------------------------------------------------*/
263 atk_tree_cache_needs_update(DBusConnection *bus)
267 g_idle_add(send_cache_update, bus);
268 update_pending = TRUE;
272 /*---------------------------------------------------------------------------*/
275 impl_getRoot (DBusConnection *bus, DBusMessage *message, void *user_data)
277 AtkObject *root = atk_get_root();
281 if (root) path = atk_dbus_get_path(root);
283 return spi_dbus_general_error (message);
284 reply = dbus_message_new_method_return (message);
285 dbus_message_append_args (reply, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID);
290 /*---------------------------------------------------------------------------*/
293 impl_getTree (DBusConnection *bus, DBusMessage *message, void *user_data)
296 DBusMessageIter iter, iter_array;
297 AtkObject *root = atk_get_root();
300 return spi_dbus_general_error(message);
301 reply = dbus_message_new_method_return (message);
303 dbus_message_iter_init_append (reply, &iter);
304 dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(ooaoassusau)", &iter_array);
305 atk_dbus_foreach_registered(append_accessible, &iter_array);
306 dbus_message_iter_close_container(&iter, &iter_array);
310 /*---------------------------------------------------------------------------*/
312 static DRouteMethod methods[] = {
313 {impl_getRoot, "getRoot"},
314 {impl_getTree, "getTree"},
319 spi_initialize_tree (DRoutePath *path)
321 droute_path_add_interface (path,
322 SPI_DBUS_INTERFACE_TREE,
327 /*END------------------------------------------------------------------------*/