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.
8 * Copyright 2008, 2009 Codethink Ltd.
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Library General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Library General Public License for more details.
20 * You should have received a copy of the GNU Library General Public
21 * License along with this library; if not, write to the
22 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 * Boston, MA 02111-1307, USA.
29 #include <droute/droute.h>
32 #include "accessible-register.h"
33 #include "spi-common/spi-dbus.h"
35 /*---------------------------------------------------------------------------*/
38 append_atk_object_interfaces (AtkObject *object, DBusMessageIter *iter)
42 itf = SPI_DBUS_INTERFACE_ACCESSIBLE;
43 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
45 if (ATK_IS_ACTION (object))
47 itf = SPI_DBUS_INTERFACE_ACTION;
48 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
51 if (ATK_IS_COMPONENT (object))
53 itf = SPI_DBUS_INTERFACE_COMPONENT;
54 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
57 if (ATK_IS_EDITABLE_TEXT (object))
59 itf = SPI_DBUS_INTERFACE_EDITABLE_TEXT;
60 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
63 if (ATK_IS_TEXT (object))
65 itf = SPI_DBUS_INTERFACE_TEXT;
66 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
69 if (ATK_IS_HYPERTEXT (object))
71 itf = SPI_DBUS_INTERFACE_HYPERTEXT;
72 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
75 if (ATK_IS_IMAGE (object))
77 itf = SPI_DBUS_INTERFACE_IMAGE;
78 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
81 if (ATK_IS_SELECTION (object))
83 itf = SPI_DBUS_INTERFACE_SELECTION;
84 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
87 if (ATK_IS_TABLE (object))
89 itf = SPI_DBUS_INTERFACE_TABLE;
90 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
93 if (ATK_IS_VALUE (object))
95 itf = SPI_DBUS_INTERFACE_VALUE;
96 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
99 if (ATK_IS_STREAMABLE_CONTENT (object))
101 itf = "org.freedesktop.atspi.StreamableContent";
102 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
105 if (ATK_IS_DOCUMENT (object))
107 itf = "org.freedesktop.atspi.Collection";
108 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
109 itf = SPI_DBUS_INTERFACE_DOCUMENT;
110 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
113 if (ATK_IS_HYPERLINK_IMPL (object))
115 itf = SPI_DBUS_INTERFACE_HYPERLINK;
116 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
120 /*---------------------------------------------------------------------------*/
122 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 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_object_to_path (obj);
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_object_to_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_object_to_path (child);
178 g_object_unref(G_OBJECT(child));
179 if (G_LIKELY (child_path))
181 dbus_message_iter_append_basic (&iter_sub_array, DBUS_TYPE_OBJECT_PATH, &child_path);
185 g_critical ("AT-SPI: Child object exists in accessible tree but has not been registered");
190 dbus_message_iter_close_container (&iter_struct, &iter_sub_array);
192 dbus_message_iter_open_container (&iter_struct, DBUS_TYPE_ARRAY, "s", &iter_sub_array);
193 append_atk_object_interfaces (obj, &iter_sub_array);
194 dbus_message_iter_close_container (&iter_struct, &iter_sub_array);
196 name = atk_object_get_name (obj);
199 dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &name);
201 role = spi_accessible_role_from_atk_role (atk_object_get_role (obj));
202 dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_UINT32, &role);
204 desc = atk_object_get_description (obj);
207 dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &desc);
211 spi_atk_state_to_dbus_array (obj, &states);
212 dbus_message_iter_open_container (&iter_struct, DBUS_TYPE_ARRAY, "u", &iter_sub_array);
213 for (count = 0; count < 2; count++)
214 dbus_message_iter_append_basic (&iter_sub_array, DBUS_TYPE_UINT32, &states[count]);
215 dbus_message_iter_close_container (&iter_struct, &iter_sub_array);
216 dbus_message_iter_close_container (iter_array, &iter_struct);
219 /* For use as a GHFunc */
221 append_accessible_hf (gpointer key, gpointer obj_data, gpointer iter)
223 append_accessible (obj_data, iter);
226 /*---------------------------------------------------------------------------*/
229 spi_emit_cache_removal (guint ref, DBusConnection *bus)
231 DBusMessage *message;
232 DBusMessageIter iter;
235 message = dbus_message_new_signal ("/org/freedesktop/atspi/tree", SPI_DBUS_INTERFACE_TREE, "removeAccessible");
237 dbus_message_iter_init_append (message, &iter);
239 path = atk_dbus_ref_to_path (ref);
240 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &path);
242 dbus_connection_send(bus, message, NULL);
246 spi_emit_cache_update (const GList *accessibles, DBusConnection *bus)
248 DBusMessage *message;
249 DBusMessageIter iter;
250 DBusMessageIter iter_array;
251 message = dbus_message_new_signal ("/org/freedesktop/atspi/tree", SPI_DBUS_INTERFACE_TREE, "updateAccessible");
253 dbus_message_iter_init_append (message, &iter);
254 dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "(ooaoassusau)", &iter_array);
255 g_list_foreach ((GList *)accessibles, append_accessible, &iter_array);
256 dbus_message_iter_close_container(&iter, &iter_array);
258 dbus_connection_send(bus, message, NULL);
262 /*---------------------------------------------------------------------------*/
265 impl_getRoot (DBusConnection *bus, DBusMessage *message, void *user_data)
267 AtkObject *root = atk_get_root();
272 return spi_dbus_general_error (message);
273 path = atk_dbus_object_to_path (root);
275 return spi_dbus_general_error (message);
276 reply = dbus_message_new_method_return (message);
277 dbus_message_append_args (reply, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID);
282 /*---------------------------------------------------------------------------*/
285 impl_getTree (DBusConnection *bus, DBusMessage *message, void *user_data)
288 DBusMessageIter iter, iter_array;
290 reply = dbus_message_new_method_return (message);
292 dbus_message_iter_init_append (reply, &iter);
293 dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(ooaoassusau)", &iter_array);
294 atk_dbus_foreach_registered(append_accessible_hf, &iter_array);
295 dbus_message_iter_close_container(&iter, &iter_array);
299 /*---------------------------------------------------------------------------*/
301 static DRouteMethod methods[] = {
302 {impl_getRoot, "getRoot"},
303 {impl_getTree, "getTree"},
308 spi_initialize_tree (DRoutePath *path)
310 droute_path_add_interface (path,
311 SPI_DBUS_INTERFACE_TREE,
316 /*END------------------------------------------------------------------------*/