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 /*---------------------------------------------------------------------------*/
37 append_atk_object_interfaces (AtkObject *object, DBusMessageIter *iter)
41 itf = SPI_DBUS_INTERFACE_ACCESSIBLE;
42 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
44 if (ATK_IS_ACTION (object))
46 itf = SPI_DBUS_INTERFACE_ACTION;
47 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
50 if (ATK_IS_COMPONENT (object))
52 itf = SPI_DBUS_INTERFACE_COMPONENT;
53 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
56 if (ATK_IS_EDITABLE_TEXT (object))
58 itf = SPI_DBUS_INTERFACE_EDITABLE_TEXT;
59 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
62 if (ATK_IS_TEXT (object))
64 itf = SPI_DBUS_INTERFACE_TEXT;
65 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
68 if (ATK_IS_HYPERTEXT (object))
70 itf = SPI_DBUS_INTERFACE_HYPERTEXT;
71 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
74 if (ATK_IS_IMAGE (object))
76 itf = SPI_DBUS_INTERFACE_IMAGE;
77 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
80 if (ATK_IS_SELECTION (object))
82 itf = SPI_DBUS_INTERFACE_SELECTION;
83 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
86 if (ATK_IS_TABLE (object))
88 itf = SPI_DBUS_INTERFACE_TABLE;
89 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
92 if (ATK_IS_VALUE (object))
94 itf = SPI_DBUS_INTERFACE_VALUE;
95 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
98 if (ATK_IS_STREAMABLE_CONTENT (object))
100 itf = "org.freedesktop.atspi.StreamableContent";
101 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
104 if (ATK_IS_DOCUMENT (object))
106 itf = "org.freedesktop.atspi.Collection";
107 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
108 itf = SPI_DBUS_INTERFACE_DOCUMENT;
109 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
112 if (ATK_IS_HYPERLINK_IMPL (object))
114 itf = SPI_DBUS_INTERFACE_HYPERLINK;
115 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
119 /*---------------------------------------------------------------------------*/
121 static const char *dumm = "/APath/1";
125 * Marshals the given AtkObject into the provided D-Bus iterator.
127 * The object is marshalled including all its client side cache data.
128 * The format of the structure is (ooaoassusau).
129 * This is used in the updateTree signal and the getTree method
130 * of the org.freedesktop.atspi.Tree interface.
133 append_accessible(gpointer obj_data, gpointer iter)
136 DBusMessageIter *iter_array;
137 DBusMessageIter iter_struct, iter_sub_array;
138 dbus_int32_t states [2];
141 const char *name, *desc;
146 obj = ATK_OBJECT(obj_data);
147 iter_array = (DBusMessageIter *) iter;
149 dbus_message_iter_open_container (iter_array, DBUS_TYPE_STRUCT, NULL, &iter_struct);
152 gchar *path, *path_parent;
154 path = atk_dbus_object_to_path (obj);
155 dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_OBJECT_PATH, &path);
157 parent = atk_object_get_parent(obj);
159 path_parent = g_strdup("/");
161 path_parent = atk_dbus_object_to_path (parent);
162 dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_OBJECT_PATH, &path_parent);
165 dbus_message_iter_open_container (&iter_struct, DBUS_TYPE_ARRAY, "o", &iter_sub_array);
169 childcount = atk_object_get_n_accessible_children (obj);
170 for (i = 0; i < childcount; i++)
175 child = atk_object_ref_accessible_child (obj, i);
176 child_path = atk_dbus_object_to_path (child);
177 g_object_unref(G_OBJECT(child));
178 if (G_LIKELY (child_path))
180 dbus_message_iter_append_basic (&iter_sub_array, DBUS_TYPE_OBJECT_PATH, &child_path);
184 g_critical ("AT-SPI: Child object exists in accessible tree but has not been registered");
189 dbus_message_iter_close_container (&iter_struct, &iter_sub_array);
191 dbus_message_iter_open_container (&iter_struct, DBUS_TYPE_ARRAY, "s", &iter_sub_array);
192 append_atk_object_interfaces (obj, &iter_sub_array);
193 dbus_message_iter_close_container (&iter_struct, &iter_sub_array);
195 name = atk_object_get_name (obj);
198 dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &name);
200 role = spi_accessible_role_from_atk_role (atk_object_get_role (obj));
201 dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_UINT32, &role);
203 desc = atk_object_get_description (obj);
206 dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &desc);
210 spi_atk_state_to_dbus_array (obj, &states);
211 dbus_message_iter_open_container (&iter_struct, DBUS_TYPE_ARRAY, "u", &iter_sub_array);
212 for (count = 0; count < 2; count++)
213 dbus_message_iter_append_basic (&iter_sub_array, DBUS_TYPE_UINT32, &states[count]);
214 dbus_message_iter_close_container (&iter_struct, &iter_sub_array);
215 dbus_message_iter_close_container (iter_array, &iter_struct);
218 /* For use as a GHFunc */
220 append_accessible_hf (gpointer key, gpointer obj_data, gpointer iter)
222 append_accessible (obj_data, iter);
225 /*---------------------------------------------------------------------------*/
228 spi_emit_cache_removal (guint ref, DBusConnection *bus)
230 DBusMessage *message;
231 DBusMessageIter iter;
234 message = dbus_message_new_signal ("/org/freedesktop/atspi/tree", SPI_DBUS_INTERFACE_TREE, "removeAccessible");
236 dbus_message_iter_init_append (message, &iter);
238 path = atk_dbus_ref_to_path (ref);
239 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &path);
241 dbus_connection_send(bus, message, NULL);
245 spi_emit_cache_update (const GList *accessibles, DBusConnection *bus)
247 DBusMessage *message;
248 DBusMessageIter iter;
249 DBusMessageIter iter_array;
250 message = dbus_message_new_signal ("/org/freedesktop/atspi/tree", SPI_DBUS_INTERFACE_TREE, "updateAccessible");
252 dbus_message_iter_init_append (message, &iter);
253 dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "(ooaoassusau)", &iter_array);
254 g_list_foreach ((GList *)accessibles, append_accessible, &iter_array);
255 dbus_message_iter_close_container(&iter, &iter_array);
257 dbus_connection_send(bus, message, NULL);
261 /*---------------------------------------------------------------------------*/
264 impl_getRoot (DBusConnection *bus, DBusMessage *message, void *user_data)
266 AtkObject *root = atk_get_root();
271 return spi_dbus_general_error (message);
272 path = atk_dbus_object_to_path (root);
274 return spi_dbus_general_error (message);
275 reply = dbus_message_new_method_return (message);
276 dbus_message_append_args (reply, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID);
281 /*---------------------------------------------------------------------------*/
284 impl_getTree (DBusConnection *bus, DBusMessage *message, void *user_data)
287 DBusMessageIter iter, iter_array;
289 reply = dbus_message_new_method_return (message);
291 dbus_message_iter_init_append (reply, &iter);
292 dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(ooaoassusau)", &iter_array);
293 atk_dbus_foreach_registered(append_accessible_hf, &iter_array);
294 dbus_message_iter_close_container(&iter, &iter_array);
298 /*---------------------------------------------------------------------------*/
300 static DRouteMethod methods[] = {
301 {impl_getRoot, "getRoot"},
302 {impl_getTree, "getTree"},
307 spi_initialize_tree (DRoutePath *path)
309 droute_path_add_interface (path,
310 SPI_DBUS_INTERFACE_TREE,
315 /*END------------------------------------------------------------------------*/