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.
23 #include <droute/droute.h>
25 #include "common/spi-dbus.h"
26 #include "common/spi-stateset.h"
28 #include "accessible-register.h"
29 #include "accessible-marshaller.h"
33 /*---------------------------------------------------------------------------*/
36 * Marshals the D-Bus path of an AtkObject into a D-Bus message.
38 * Unrefs the AtkObject if unref is true.
41 spi_dbus_return_object (DBusMessage *message, AtkObject *obj, gboolean unref)
46 path = atk_dbus_object_to_path (obj);
52 path = g_strdup (SPI_DBUS_PATH_NULL);
54 reply = dbus_message_new_method_return (message);
57 dbus_message_append_args (reply, DBUS_TYPE_OBJECT_PATH, &path,
66 /*---------------------------------------------------------------------------*/
69 * Marshals a variant containing the D-Bus path of an AtkObject into a D-Bus
72 * Unrefs the object if unref is true.
75 spi_dbus_return_v_object (DBusMessageIter *iter, AtkObject *obj, int unref)
79 path = atk_dbus_object_to_path (obj);
84 return droute_return_v_object (iter, path);
87 /*---------------------------------------------------------------------------*/
90 append_atk_object_interfaces (AtkObject *object, DBusMessageIter *iter)
94 itf = SPI_DBUS_INTERFACE_ACCESSIBLE;
95 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
97 if (ATK_IS_ACTION (object))
99 itf = SPI_DBUS_INTERFACE_ACTION;
100 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
103 if (ATK_IS_COMPONENT (object))
105 itf = SPI_DBUS_INTERFACE_COMPONENT;
106 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
109 if (ATK_IS_EDITABLE_TEXT (object))
111 itf = SPI_DBUS_INTERFACE_EDITABLE_TEXT;
112 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
115 if (ATK_IS_TEXT (object))
117 itf = SPI_DBUS_INTERFACE_TEXT;
118 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
121 if (ATK_IS_HYPERTEXT (object))
123 itf = SPI_DBUS_INTERFACE_HYPERTEXT;
124 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
127 if (ATK_IS_IMAGE (object))
129 itf = SPI_DBUS_INTERFACE_IMAGE;
130 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
133 if (ATK_IS_SELECTION (object))
135 itf = SPI_DBUS_INTERFACE_SELECTION;
136 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
139 if (ATK_IS_TABLE (object))
141 itf = SPI_DBUS_INTERFACE_TABLE;
142 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
145 if (ATK_IS_VALUE (object))
147 itf = SPI_DBUS_INTERFACE_VALUE;
148 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
151 if (ATK_IS_STREAMABLE_CONTENT (object))
153 itf = "org.freedesktop.atspi.StreamableContent";
154 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
157 if (ATK_IS_DOCUMENT (object))
159 itf = "org.freedesktop.atspi.Collection";
160 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
161 itf = SPI_DBUS_INTERFACE_DOCUMENT;
162 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
165 if (ATK_IS_HYPERLINK_IMPL (object))
167 itf = SPI_DBUS_INTERFACE_HYPERLINK;
168 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
172 /*---------------------------------------------------------------------------*/
175 * Marshals the given AtkObject into the provided D-Bus iterator.
177 * The object is marshalled including all its client side cache data.
178 * The format of the structure is (ooaoassusau).
179 * This is used in the updateTree signal and the getTree method
180 * of the org.freedesktop.atspi.Tree interface.
182 * To marshal an object its parent, and all its children must already
183 * be registered with D-Bus and have been given a D-Bus object path.
186 spi_atk_append_accessible(AtkObject *obj, gpointer iter)
188 DBusMessageIter *iter_array;
189 DBusMessageIter iter_struct, iter_sub_array;
190 dbus_uint32_t states [2];
193 const char *name, *desc;
196 iter_array = (DBusMessageIter *) iter;
198 dbus_message_iter_open_container (iter_array, DBUS_TYPE_STRUCT, NULL, &iter_struct);
201 gchar *path, *path_parent;
203 /* Marshall object path */
204 path = atk_dbus_object_to_path (obj);
205 dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_OBJECT_PATH, &path);
207 /* Marshall parent */
208 parent = atk_object_get_parent(obj);
211 path_parent = atk_dbus_desktop_object_path ();
215 path_parent = atk_dbus_object_to_path (parent);
218 /* This should only happen if a widget is re-parented to
219 * an AtkObject that has not been registered and is then
220 * updated. Ideally objects would be de-registered when
221 * they are removed from a registered tree object, but
222 * this would invalidate a huge amount of cache when
226 g_warning ("AT-SPI: Registered accessible marshalled when parent not registered");
228 path_parent = atk_dbus_desktop_object_path ();
231 dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_OBJECT_PATH, &path_parent);
234 /* Marshall children */
235 dbus_message_iter_open_container (&iter_struct, DBUS_TYPE_ARRAY, "o", &iter_sub_array);
239 childcount = atk_object_get_n_accessible_children (obj);
240 for (i = 0; i < childcount; i++)
245 child = atk_object_ref_accessible_child (obj, i);
246 child_path = atk_dbus_object_to_path (child);
249 dbus_message_iter_append_basic (&iter_sub_array, DBUS_TYPE_OBJECT_PATH, &child_path);
252 g_object_unref(G_OBJECT(child));
255 dbus_message_iter_close_container (&iter_struct, &iter_sub_array);
257 /* Marshall interfaces */
258 dbus_message_iter_open_container (&iter_struct, DBUS_TYPE_ARRAY, "s", &iter_sub_array);
259 append_atk_object_interfaces (obj, &iter_sub_array);
260 dbus_message_iter_close_container (&iter_struct, &iter_sub_array);
263 name = atk_object_get_name (obj);
266 dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &name);
269 role = spi_accessible_role_from_atk_role (atk_object_get_role (obj));
270 dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_UINT32, &role);
272 /* Marshall description */
273 desc = atk_object_get_description (obj);
276 dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &desc);
280 /* Marshall state set */
281 spi_atk_state_to_dbus_array (obj, states);
282 dbus_message_iter_open_container (&iter_struct, DBUS_TYPE_ARRAY, "u", &iter_sub_array);
283 for (count = 0; count < 2; count++)
285 dbus_message_iter_append_basic (&iter_sub_array, DBUS_TYPE_UINT32, &states[count]);
287 dbus_message_iter_close_container (&iter_struct, &iter_sub_array);
289 dbus_message_iter_close_container (iter_array, &iter_struct);
293 spi_atk_append_attribute_set (DBusMessageIter *iter, AtkAttributeSet *attr)
295 DBusMessageIter dictIter;
297 dbus_message_iter_open_container (iter, DBUS_TYPE_ARRAY, "{ss}", &dictIter);
298 spi_atk_append_attribute_set_inner (&dictIter, attr);
299 dbus_message_iter_close_container (iter, &dictIter);
303 spi_atk_append_attribute_set_inner (DBusMessageIter *iter, AtkAttributeSet *attr)
305 DBusMessageIter dictEntryIter;
309 AtkAttribute *attribute = (AtkAttribute *) attr->data;
310 dbus_message_iter_open_container (iter, DBUS_TYPE_DICT_ENTRY, NULL, &dictEntryIter);
311 dbus_message_iter_append_basic (&dictEntryIter, DBUS_TYPE_STRING, &attribute->name);
312 dbus_message_iter_append_basic (&dictEntryIter, DBUS_TYPE_STRING, &attribute->value);
313 dbus_message_iter_close_container (iter, &dictEntryIter);
314 attr = g_slist_next (attr);
318 /*END------------------------------------------------------------------------*/