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.
26 #include <droute/droute.h>
28 #include "common/spi-dbus.h"
29 #include "common/spi-stateset.h"
33 impl_get_Name (DBusMessageIter * iter, void *user_data)
35 AtkObject *object = (AtkObject *) user_data;
37 g_return_val_if_fail (ATK_IS_OBJECT (user_data), FALSE);
39 return droute_return_v_string (iter, atk_object_get_name (object));
43 impl_set_Name (DBusMessageIter * iter, void *user_data)
45 AtkObject *object = (AtkObject *) user_data;
46 const char *name = droute_get_v_string (iter);
48 g_return_val_if_fail (ATK_IS_OBJECT (user_data), FALSE);
50 atk_object_set_name (object, name);
55 impl_get_Description (DBusMessageIter * iter, void *user_data)
57 AtkObject *object = (AtkObject *) user_data;
59 g_return_val_if_fail (ATK_IS_OBJECT (user_data), FALSE);
61 return droute_return_v_string (iter, atk_object_get_description (object));
65 impl_set_Description (DBusMessageIter * iter, void *user_data)
67 AtkObject *object = (AtkObject *) user_data;
68 const char *description = droute_get_v_string (iter);
70 g_return_val_if_fail (ATK_IS_OBJECT (user_data), FALSE);
72 atk_object_set_description (object, description);
77 impl_get_Parent (DBusMessageIter * iter, void *user_data)
79 AtkObject *object = (AtkObject *) user_data;
81 g_return_val_if_fail (ATK_IS_OBJECT (user_data), FALSE);
83 spi_object_append_v_reference (iter, atk_object_get_parent (object));
88 impl_get_ChildCount (DBusMessageIter * iter, void *user_data)
90 AtkObject *object = (AtkObject *) user_data;
92 g_return_val_if_fail (ATK_IS_OBJECT (user_data), FALSE);
94 return droute_return_v_int32 (iter,
95 atk_object_get_n_accessible_children
100 impl_GetChildAtIndex (DBusConnection * bus,
101 DBusMessage * message, void *user_data)
103 AtkObject *object = (AtkObject *) user_data;
108 dbus_error_init (&error);
109 g_return_val_if_fail (ATK_IS_OBJECT (user_data),
110 droute_not_yet_handled_error (message));
111 if (!dbus_message_get_args
112 (message, &error, DBUS_TYPE_INT32, &i, DBUS_TYPE_INVALID))
114 return droute_invalid_arguments_error (message);
116 child = atk_object_ref_accessible_child (object, i);
117 return spi_object_return_reference (message, child);
121 impl_GetChildren (DBusConnection * bus,
122 DBusMessage * message, void *user_data)
124 AtkObject *object = (AtkObject *) user_data;
128 DBusMessageIter iter, iter_array;
130 g_return_val_if_fail (ATK_IS_OBJECT (user_data),
131 droute_not_yet_handled_error (message));
132 count = atk_object_get_n_accessible_children (object);
133 reply = dbus_message_new_method_return (message);
136 dbus_message_iter_init_append (reply, &iter);
137 if (!dbus_message_iter_open_container
138 (&iter, DBUS_TYPE_ARRAY, "(so)", &iter_array))
140 for (i = 0; i < count; i++)
142 AtkObject *child = atk_object_ref_accessible_child (object, i);
143 spi_object_append_reference (&iter_array, child);
145 g_object_unref (child);
147 if (!dbus_message_iter_close_container (&iter, &iter_array))
151 // TODO: handle out-of-memory
156 impl_GetIndexInParent (DBusConnection * bus,
157 DBusMessage * message, void *user_data)
159 AtkObject *object = (AtkObject *) user_data;
163 g_return_val_if_fail (ATK_IS_OBJECT (user_data),
164 droute_not_yet_handled_error (message));
166 rv = atk_object_get_index_in_parent (object);
167 reply = dbus_message_new_method_return (message);
168 dbus_message_append_args (reply, DBUS_TYPE_UINT32, &rv, DBUS_TYPE_INVALID);
173 spi_init_relation_type_table (Accessibility_RelationType * types)
177 for (i = 0; i < ATK_RELATION_LAST_DEFINED; i++)
178 types[i] = Accessibility_RELATION_NULL;
180 types[ATK_RELATION_CONTROLLED_BY] = Accessibility_RELATION_CONTROLLED_BY;
181 types[ATK_RELATION_CONTROLLER_FOR] = Accessibility_RELATION_CONTROLLER_FOR;
182 types[ATK_RELATION_LABEL_FOR] = Accessibility_RELATION_LABEL_FOR;
183 types[ATK_RELATION_LABELLED_BY] = Accessibility_RELATION_LABELLED_BY;
184 types[ATK_RELATION_MEMBER_OF] = Accessibility_RELATION_MEMBER_OF;
185 types[ATK_RELATION_NODE_CHILD_OF] = Accessibility_RELATION_NODE_CHILD_OF;
186 types[ATK_RELATION_FLOWS_TO] = Accessibility_RELATION_FLOWS_TO;
187 types[ATK_RELATION_FLOWS_FROM] = Accessibility_RELATION_FLOWS_FROM;
188 types[ATK_RELATION_SUBWINDOW_OF] = Accessibility_RELATION_SUBWINDOW_OF;
189 types[ATK_RELATION_EMBEDS] = Accessibility_RELATION_EMBEDS;
190 types[ATK_RELATION_EMBEDDED_BY] = Accessibility_RELATION_EMBEDDED_BY;
191 types[ATK_RELATION_POPUP_FOR] = Accessibility_RELATION_POPUP_FOR;
192 types[ATK_RELATION_PARENT_WINDOW_OF] =
193 Accessibility_RELATION_PARENT_WINDOW_OF;
194 types[ATK_RELATION_DESCRIPTION_FOR] =
195 Accessibility_RELATION_DESCRIPTION_FOR;
196 types[ATK_RELATION_DESCRIBED_BY] = Accessibility_RELATION_DESCRIBED_BY;
201 static Accessibility_RelationType
202 spi_relation_type_from_atk_relation_type (AtkRelationType type)
204 static gboolean is_initialized = FALSE;
205 static Accessibility_RelationType
206 spi_relation_type_table[ATK_RELATION_LAST_DEFINED];
207 Accessibility_RelationType spi_type;
210 is_initialized = spi_init_relation_type_table (spi_relation_type_table);
212 if (type > ATK_RELATION_NULL && type < ATK_RELATION_LAST_DEFINED)
213 spi_type = spi_relation_type_table[type];
215 spi_type = Accessibility_RELATION_EXTENDED;
220 impl_GetRelationSet (DBusConnection * bus,
221 DBusMessage * message, void *user_data)
223 AtkObject *object = (AtkObject *) user_data;
226 DBusMessageIter iter, iter_array, iter_struct, iter_targets;
230 g_return_val_if_fail (ATK_IS_OBJECT (user_data),
231 droute_not_yet_handled_error (message));
232 reply = dbus_message_new_method_return (message);
235 set = atk_object_ref_relation_set (object);
236 dbus_message_iter_init_append (reply, &iter);
237 if (!dbus_message_iter_open_container
238 (&iter, DBUS_TYPE_ARRAY, "(ua(so))", &iter_array))
242 count = atk_relation_set_get_n_relations (set);
243 for (i = 0; i < count; i++)
245 AtkRelation *r = atk_relation_set_get_relation (set, i);
251 rt = atk_relation_get_relation_type (r);
252 type = spi_relation_type_from_atk_relation_type (rt);
253 target = atk_relation_get_target (r);
254 if (!dbus_message_iter_open_container
255 (&iter_array, DBUS_TYPE_STRUCT, NULL, &iter_struct))
259 dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_UINT32, &type);
260 if (!dbus_message_iter_open_container
261 (&iter_struct, DBUS_TYPE_ARRAY, "(so)", &iter_targets))
265 for (j = 0; j < target->len; j++)
267 AtkObject *obj = target->pdata[j];
271 spi_object_append_reference (&iter_targets, obj);
273 dbus_message_iter_close_container (&iter_struct, &iter_targets);
274 dbus_message_iter_close_container (&iter_array, &iter_struct);
276 dbus_message_iter_close_container (&iter, &iter_array);
278 // TODO: handle out of memory */
283 impl_GetRole (DBusConnection * bus, DBusMessage * message, void *user_data)
285 AtkObject *object = (AtkObject *) user_data;
290 g_return_val_if_fail (ATK_IS_OBJECT (user_data),
291 droute_not_yet_handled_error (message));
292 role = atk_object_get_role (object);
293 rv = spi_accessible_role_from_atk_role (role);
294 reply = dbus_message_new_method_return (message);
297 dbus_message_append_args (reply, DBUS_TYPE_UINT32, &rv,
304 impl_get_role_str (void *datum)
306 g_return_val_if_fail (ATK_IS_OBJECT (datum), g_strdup (""));
307 return g_strdup_printf ("%d",
308 spi_accessible_role_from_atk_role
309 (atk_object_get_role ((AtkObject *) datum)));
313 impl_GetRoleName (DBusConnection * bus,
314 DBusMessage * message, void *user_data)
316 AtkObject *object = (AtkObject *) user_data;
318 const char *role_name;
321 g_return_val_if_fail (ATK_IS_OBJECT (user_data),
322 droute_not_yet_handled_error (message));
323 role = atk_object_get_role (object);
324 role_name = atk_role_get_name (role);
327 reply = dbus_message_new_method_return (message);
330 dbus_message_append_args (reply, DBUS_TYPE_STRING, &role_name,
337 impl_GetLocalizedRoleName (DBusConnection * bus,
338 DBusMessage * message, void *user_data)
340 AtkObject *object = (AtkObject *) user_data;
342 const char *role_name;
345 g_return_val_if_fail (ATK_IS_OBJECT (user_data),
346 droute_not_yet_handled_error (message));
347 role = atk_object_get_role (object);
348 role_name = atk_role_get_localized_name (role);
351 reply = dbus_message_new_method_return (message);
354 dbus_message_append_args (reply, DBUS_TYPE_STRING, &role_name,
361 impl_GetState (DBusConnection * bus, DBusMessage * message, void *user_data)
363 AtkObject *object = (AtkObject *) user_data;
365 DBusMessage *reply = NULL;
366 DBusMessageIter iter, iter_array;
368 dbus_uint32_t states[2];
372 g_return_val_if_fail (ATK_IS_OBJECT (user_data),
373 droute_not_yet_handled_error (message));
375 reply = dbus_message_new_method_return (message);
376 dbus_message_iter_init_append (reply, &iter);
378 spi_atk_state_to_dbus_array (object, states);
379 dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "u", &iter_array);
380 for (count = 0; count < 2; count++)
382 dbus_message_iter_append_basic (&iter_array, DBUS_TYPE_UINT32,
385 dbus_message_iter_close_container (&iter, &iter_array);
390 impl_GetAttributes (DBusConnection * bus,
391 DBusMessage * message, void *user_data)
393 AtkObject *object = (AtkObject *) user_data;
394 AtkAttributeSet *attributes;
395 DBusMessage *reply = NULL;
396 DBusMessageIter iter;
398 g_return_val_if_fail (ATK_IS_OBJECT (user_data),
399 droute_not_yet_handled_error (message));
401 attributes = atk_object_get_attributes (object);
403 reply = dbus_message_new_method_return (message);
404 dbus_message_iter_init_append (reply, &iter);
405 spi_object_append_attribute_set (&iter, attributes);
407 atk_attribute_set_free (attributes);
413 impl_GetApplication (DBusConnection * bus,
414 DBusMessage * message, void *user_data)
416 AtkObject *root = atk_get_root ();
417 return spi_object_return_reference (message, root);
421 impl_GetInterfaces (DBusConnection * bus,
422 DBusMessage * message, void *user_data)
424 AtkObject *object = (AtkObject *) user_data;
426 const char *role_name;
428 DBusMessageIter iter, iter_array;
430 g_return_val_if_fail (ATK_IS_OBJECT (user_data),
431 droute_not_yet_handled_error (message));
432 reply = dbus_message_new_method_return (message);
435 dbus_message_iter_init_append (reply, &iter);
436 dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "s",
438 spi_object_append_interfaces (&iter_array, object);
439 dbus_message_iter_close_container (&iter, &iter_array);
445 impl_Embedded (DBusConnection *bus,
446 DBusMessage *message,
449 AtkObject *object = (AtkObject *) user_data;
453 if (!dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID))
455 return droute_invalid_arguments_error (message);
457 id = g_object_get_data (G_OBJECT (object), "dbus-plug-parent");
460 id = g_strconcat (dbus_message_get_sender (message), ":", path, NULL);
461 g_object_set_data (G_OBJECT (object), "dbus-plug-parent", id);
462 return dbus_message_new_method_return (message);
465 static DRouteMethod methods[] = {
466 {impl_GetChildAtIndex, "GetChildAtIndex"},
467 {impl_GetChildren, "GetChildren"},
468 {impl_GetIndexInParent, "GetIndexInParent"},
469 {impl_GetRelationSet, "GetRelationSet"},
470 {impl_GetRole, "GetRole"},
471 {impl_GetRoleName, "GetRoleName"},
472 {impl_GetLocalizedRoleName, "GetLocalizedRoleName"},
473 {impl_GetState, "GetState"},
474 {impl_GetAttributes, "GetAttributes"},
475 {impl_GetApplication, "GetApplication"},
476 {impl_GetInterfaces, "GetInterfaces"},
477 {impl_Embedded, "Embedded"},
481 static DRouteProperty properties[] = {
482 {impl_get_Name, impl_set_Name, "Name"},
483 {impl_get_Description, impl_set_Description, "Description"},
484 {impl_get_Parent, NULL, "Parent"},
485 {impl_get_ChildCount, NULL, "ChildCount"},
490 spi_initialize_accessible (DRoutePath * path)
492 droute_path_add_interface (path,
493 SPI_DBUS_INTERFACE_ACCESSIBLE,
494 methods, properties);