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 2008, 2009, 2010 Codethink Ltd.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library; if not, write to the
20 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 * Boston, MA 02111-1307, USA.
25 * This module contains utility functions for exporting AT-SPI
26 * objects based upon an ATK object.
28 * It incudes functions for marshalling object references
29 * and supported interfaces to a D-Bus message.
33 #include <common/spi-types.h>
34 #include <common/spi-dbus.h>
36 #include "accessible-register.h"
37 #include "accessible-cache.h"
38 #include "accessible-leasing.h"
42 /*---------------------------------------------------------------------------*/
45 * This is the all important function that decides whether an object should
48 * The choice of algorithm for this is somewhat vuage. We want ideally to lease
49 * all atk objects that are not owned by their parent.
51 * The 'cache' object attempts to cache all objects that are owned by their
52 * parent by traversing the tree of accessibles, ignoring the children of
53 * manages-descendants and transient objects.
55 * This function will simply look for all the accessibles that the cache object
56 * has not found and assume that they need to be leased.
59 maybe_lease (AtkObject *obj)
61 if (!spi_cache_in (spi_global_cache, G_OBJECT (obj)))
63 spi_leasing_take (spi_global_leasing, G_OBJECT (obj));
67 /*---------------------------------------------------------------------------*/
70 * It is assumed that all of these functions are returning an accessible
71 * object to the client side.
73 * All of them will lease the AtkObject if it is deemed neccessary.
77 spi_object_append_reference (DBusMessageIter * iter, AtkObject * obj)
79 DBusMessageIter iter_struct;
85 name = dbus_bus_get_unique_name (spi_global_app_data->bus);
86 path = spi_register_object_to_path (spi_global_register, G_OBJECT (obj));
89 path = g_strdup (SPI_DBUS_PATH_NULL);
91 dbus_message_iter_open_container (iter, DBUS_TYPE_STRUCT, NULL,
93 dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &name);
94 dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_OBJECT_PATH, &path);
95 dbus_message_iter_close_container (iter, &iter_struct);
101 spi_object_append_v_reference (DBusMessageIter * iter, AtkObject * obj)
103 DBusMessageIter iter_variant;
105 dbus_message_iter_open_container (iter, DBUS_TYPE_VARIANT, "(so)",
107 spi_object_append_reference (&iter_variant, obj);
108 dbus_message_iter_close_container (iter, &iter_variant);
112 spi_object_append_desktop_reference (DBusMessageIter * iter)
114 DBusMessageIter iter_struct;
115 const char *name = SPI_DBUS_NAME_REGISTRY;
116 const char *path = SPI_DBUS_PATH_ROOT;
118 dbus_message_iter_open_container (iter, DBUS_TYPE_STRUCT, NULL,
120 dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &name);
121 dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_OBJECT_PATH, &path);
122 dbus_message_iter_close_container (iter, &iter_struct);
126 spi_object_append_null_reference (DBusMessageIter * iter)
128 DBusMessageIter iter_struct;
130 const char *path = "/org/at_spi/null";
132 name = dbus_bus_get_unique_name (spi_global_app_data->bus);
134 dbus_message_iter_open_container (iter, DBUS_TYPE_STRUCT, NULL,
136 dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &name);
137 dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_OBJECT_PATH, &path);
138 dbus_message_iter_close_container (iter, &iter_struct);
142 spi_object_return_reference (DBusMessage * msg, AtkObject * obj)
146 reply = dbus_message_new_method_return (msg);
149 DBusMessageIter iter;
150 dbus_message_iter_init_append (reply, &iter);
151 spi_object_append_reference (&iter, obj);
153 g_object_unref (G_OBJECT (obj));
158 /*---------------------------------------------------------------------------*/
161 spi_object_append_interfaces (DBusMessageIter * iter, AtkObject * obj)
165 itf = SPI_DBUS_INTERFACE_ACCESSIBLE;
166 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
168 if (ATK_IS_ACTION (obj))
170 itf = SPI_DBUS_INTERFACE_ACTION;
171 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
174 if (ATK_IS_COMPONENT (obj))
176 itf = SPI_DBUS_INTERFACE_COMPONENT;
177 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
180 if (ATK_IS_EDITABLE_TEXT (obj))
182 itf = SPI_DBUS_INTERFACE_EDITABLE_TEXT;
183 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
186 if (ATK_IS_TEXT (obj))
188 itf = SPI_DBUS_INTERFACE_TEXT;
189 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
192 if (ATK_IS_HYPERTEXT (obj))
194 itf = SPI_DBUS_INTERFACE_HYPERTEXT;
195 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
198 if (ATK_IS_IMAGE (obj))
200 itf = SPI_DBUS_INTERFACE_IMAGE;
201 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
204 if (ATK_IS_SELECTION (obj))
206 itf = SPI_DBUS_INTERFACE_SELECTION;
207 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
210 if (ATK_IS_TABLE (obj))
212 itf = SPI_DBUS_INTERFACE_TABLE;
213 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
216 if (ATK_IS_VALUE (obj))
218 itf = SPI_DBUS_INTERFACE_VALUE;
219 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
223 if (ATK_IS_STREAMABLE_CONTENT (obj))
225 itf = "org.freedesktop.atspi.StreamableContent";
226 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
230 if (ATK_IS_DOCUMENT (obj))
232 itf = "org.freedesktop.atspi.Collection";
233 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
234 itf = SPI_DBUS_INTERFACE_DOCUMENT;
235 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
238 if (ATK_IS_HYPERLINK_IMPL (obj))
240 itf = SPI_DBUS_INTERFACE_HYPERLINK;
241 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
245 /*---------------------------------------------------------------------------*/
248 spi_object_append_attribute_set (DBusMessageIter * iter, AtkAttributeSet * attr)
250 DBusMessageIter dictIter;
252 dbus_message_iter_open_container (iter, DBUS_TYPE_ARRAY, "{ss}", &dictIter);
255 DBusMessageIter dictEntryIter;
256 AtkAttribute *attribute = (AtkAttribute *) attr->data;
257 const char *key = attribute->name;
258 const char *value = attribute->value;
265 dbus_message_iter_open_container (&dictIter, DBUS_TYPE_DICT_ENTRY, NULL,
267 dbus_message_iter_append_basic (&dictEntryIter, DBUS_TYPE_STRING,
269 dbus_message_iter_append_basic (&dictEntryIter, DBUS_TYPE_STRING,
271 dbus_message_iter_close_container (&dictIter, &dictEntryIter);
272 attr = g_slist_next (attr);
274 dbus_message_iter_close_container (iter, &dictIter);
277 /*---------------------------------------------------------------------------*/
280 init_role_lookup_table (Accessibility_Role * role_table)
283 /* if it's not in the list below, dunno what it is */
284 for (i = 0; i < ATK_ROLE_LAST_DEFINED; ++i)
286 role_table[i] = Accessibility_ROLE_UNKNOWN;
289 role_table[ATK_ROLE_INVALID] = Accessibility_ROLE_INVALID;
290 role_table[ATK_ROLE_ACCEL_LABEL] = Accessibility_ROLE_ACCELERATOR_LABEL;
291 role_table[ATK_ROLE_ALERT] = Accessibility_ROLE_ALERT;
292 role_table[ATK_ROLE_ANIMATION] = Accessibility_ROLE_ANIMATION;
293 role_table[ATK_ROLE_ARROW] = Accessibility_ROLE_ARROW;
294 role_table[ATK_ROLE_CALENDAR] = Accessibility_ROLE_CALENDAR;
295 role_table[ATK_ROLE_CANVAS] = Accessibility_ROLE_CANVAS;
296 role_table[ATK_ROLE_CHECK_BOX] = Accessibility_ROLE_CHECK_BOX;
297 role_table[ATK_ROLE_CHECK_MENU_ITEM] = Accessibility_ROLE_CHECK_MENU_ITEM;
298 role_table[ATK_ROLE_COLOR_CHOOSER] = Accessibility_ROLE_COLOR_CHOOSER;
299 role_table[ATK_ROLE_COLUMN_HEADER] = Accessibility_ROLE_COLUMN_HEADER;
300 role_table[ATK_ROLE_COMBO_BOX] = Accessibility_ROLE_COMBO_BOX;
301 role_table[ATK_ROLE_DATE_EDITOR] = Accessibility_ROLE_DATE_EDITOR;
302 role_table[ATK_ROLE_DESKTOP_ICON] = Accessibility_ROLE_DESKTOP_ICON;
303 role_table[ATK_ROLE_DESKTOP_FRAME] = Accessibility_ROLE_DESKTOP_FRAME;
304 role_table[ATK_ROLE_DIAL] = Accessibility_ROLE_DIAL;
305 role_table[ATK_ROLE_DIALOG] = Accessibility_ROLE_DIALOG;
306 role_table[ATK_ROLE_DIRECTORY_PANE] = Accessibility_ROLE_DIRECTORY_PANE;
307 role_table[ATK_ROLE_DRAWING_AREA] = Accessibility_ROLE_DRAWING_AREA;
308 role_table[ATK_ROLE_FILE_CHOOSER] = Accessibility_ROLE_FILE_CHOOSER;
309 role_table[ATK_ROLE_FILLER] = Accessibility_ROLE_FILLER;
310 role_table[ATK_ROLE_FONT_CHOOSER] = Accessibility_ROLE_FONT_CHOOSER;
311 role_table[ATK_ROLE_FRAME] = Accessibility_ROLE_FRAME;
312 role_table[ATK_ROLE_GLASS_PANE] = Accessibility_ROLE_GLASS_PANE;
313 role_table[ATK_ROLE_HTML_CONTAINER] = Accessibility_ROLE_HTML_CONTAINER;
314 role_table[ATK_ROLE_ICON] = Accessibility_ROLE_ICON;
315 role_table[ATK_ROLE_IMAGE] = Accessibility_ROLE_IMAGE;
316 role_table[ATK_ROLE_INTERNAL_FRAME] = Accessibility_ROLE_INTERNAL_FRAME;
317 role_table[ATK_ROLE_LABEL] = Accessibility_ROLE_LABEL;
318 role_table[ATK_ROLE_LAYERED_PANE] = Accessibility_ROLE_LAYERED_PANE;
319 role_table[ATK_ROLE_LIST] = Accessibility_ROLE_LIST;
320 role_table[ATK_ROLE_LIST_ITEM] = Accessibility_ROLE_LIST_ITEM;
321 role_table[ATK_ROLE_MENU] = Accessibility_ROLE_MENU;
322 role_table[ATK_ROLE_MENU_BAR] = Accessibility_ROLE_MENU_BAR;
323 role_table[ATK_ROLE_MENU_ITEM] = Accessibility_ROLE_MENU_ITEM;
324 role_table[ATK_ROLE_OPTION_PANE] = Accessibility_ROLE_OPTION_PANE;
325 role_table[ATK_ROLE_PAGE_TAB] = Accessibility_ROLE_PAGE_TAB;
326 role_table[ATK_ROLE_PAGE_TAB_LIST] = Accessibility_ROLE_PAGE_TAB_LIST;
327 role_table[ATK_ROLE_PANEL] = Accessibility_ROLE_PANEL;
328 role_table[ATK_ROLE_PASSWORD_TEXT] = Accessibility_ROLE_PASSWORD_TEXT;
329 role_table[ATK_ROLE_POPUP_MENU] = Accessibility_ROLE_POPUP_MENU;
330 role_table[ATK_ROLE_PROGRESS_BAR] = Accessibility_ROLE_PROGRESS_BAR;
331 role_table[ATK_ROLE_PUSH_BUTTON] = Accessibility_ROLE_PUSH_BUTTON;
332 role_table[ATK_ROLE_RADIO_BUTTON] = Accessibility_ROLE_RADIO_BUTTON;
333 role_table[ATK_ROLE_RADIO_MENU_ITEM] = Accessibility_ROLE_RADIO_MENU_ITEM;
334 role_table[ATK_ROLE_ROOT_PANE] = Accessibility_ROLE_ROOT_PANE;
335 role_table[ATK_ROLE_ROW_HEADER] = Accessibility_ROLE_ROW_HEADER;
336 role_table[ATK_ROLE_SCROLL_BAR] = Accessibility_ROLE_SCROLL_BAR;
337 role_table[ATK_ROLE_SCROLL_PANE] = Accessibility_ROLE_SCROLL_PANE;
338 role_table[ATK_ROLE_SEPARATOR] = Accessibility_ROLE_SEPARATOR;
339 role_table[ATK_ROLE_SLIDER] = Accessibility_ROLE_SLIDER;
340 role_table[ATK_ROLE_SPIN_BUTTON] = Accessibility_ROLE_SPIN_BUTTON;
341 role_table[ATK_ROLE_SPLIT_PANE] = Accessibility_ROLE_SPLIT_PANE;
342 role_table[ATK_ROLE_STATUSBAR] = Accessibility_ROLE_STATUS_BAR;
343 role_table[ATK_ROLE_TABLE] = Accessibility_ROLE_TABLE;
344 role_table[ATK_ROLE_TABLE_CELL] = Accessibility_ROLE_TABLE_CELL;
345 role_table[ATK_ROLE_TABLE_COLUMN_HEADER] =
346 Accessibility_ROLE_TABLE_COLUMN_HEADER;
347 role_table[ATK_ROLE_TABLE_ROW_HEADER] = Accessibility_ROLE_TABLE_ROW_HEADER;
348 role_table[ATK_ROLE_TEAR_OFF_MENU_ITEM] =
349 Accessibility_ROLE_TEAROFF_MENU_ITEM;
350 role_table[ATK_ROLE_TERMINAL] = Accessibility_ROLE_TERMINAL;
351 role_table[ATK_ROLE_TEXT] = Accessibility_ROLE_TEXT;
352 role_table[ATK_ROLE_TOGGLE_BUTTON] = Accessibility_ROLE_TOGGLE_BUTTON;
353 role_table[ATK_ROLE_TOOL_BAR] = Accessibility_ROLE_TOOL_BAR;
354 role_table[ATK_ROLE_TOOL_TIP] = Accessibility_ROLE_TOOL_TIP;
355 role_table[ATK_ROLE_TREE] = Accessibility_ROLE_TREE;
356 role_table[ATK_ROLE_TREE_TABLE] = Accessibility_ROLE_TREE_TABLE;
357 role_table[ATK_ROLE_UNKNOWN] = Accessibility_ROLE_UNKNOWN;
358 role_table[ATK_ROLE_VIEWPORT] = Accessibility_ROLE_VIEWPORT;
359 role_table[ATK_ROLE_WINDOW] = Accessibility_ROLE_WINDOW;
360 role_table[ATK_ROLE_HEADER] = Accessibility_ROLE_HEADER;
361 role_table[ATK_ROLE_FOOTER] = Accessibility_ROLE_FOOTER;
362 role_table[ATK_ROLE_PARAGRAPH] = Accessibility_ROLE_PARAGRAPH;
363 role_table[ATK_ROLE_RULER] = Accessibility_ROLE_RULER;
364 role_table[ATK_ROLE_APPLICATION] = Accessibility_ROLE_APPLICATION;
365 role_table[ATK_ROLE_AUTOCOMPLETE] = Accessibility_ROLE_AUTOCOMPLETE;
366 role_table[ATK_ROLE_EDITBAR] = Accessibility_ROLE_EDITBAR;
367 role_table[ATK_ROLE_EMBEDDED] = Accessibility_ROLE_EMBEDDED;
368 role_table[ATK_ROLE_ENTRY] = Accessibility_ROLE_ENTRY;
369 role_table[ATK_ROLE_CHART] = Accessibility_ROLE_CHART;
370 role_table[ATK_ROLE_CAPTION] = Accessibility_ROLE_CAPTION;
371 role_table[ATK_ROLE_DOCUMENT_FRAME] = Accessibility_ROLE_DOCUMENT_FRAME;
372 role_table[ATK_ROLE_HEADING] = Accessibility_ROLE_HEADING;
373 role_table[ATK_ROLE_PAGE] = Accessibility_ROLE_PAGE;
374 role_table[ATK_ROLE_SECTION] = Accessibility_ROLE_SECTION;
375 role_table[ATK_ROLE_FORM] = Accessibility_ROLE_FORM;
376 role_table[ATK_ROLE_REDUNDANT_OBJECT] = Accessibility_ROLE_REDUNDANT_OBJECT;
377 role_table[ATK_ROLE_LINK] = Accessibility_ROLE_LINK;
378 role_table[ATK_ROLE_INPUT_METHOD_WINDOW] =
379 Accessibility_ROLE_INPUT_METHOD_WINDOW;
384 spi_accessible_role_from_atk_role (AtkRole role)
386 static gboolean is_initialized = FALSE;
387 static Accessibility_Role spi_role_table[ATK_ROLE_LAST_DEFINED];
388 Accessibility_Role spi_role;
392 is_initialized = init_role_lookup_table (spi_role_table);
395 if (role >= 0 && role < ATK_ROLE_LAST_DEFINED)
397 spi_role = spi_role_table[role];
401 spi_role = Accessibility_ROLE_EXTENDED;
406 /*END------------------------------------------------------------------------*/