1 /*
2 * AT-SPI - Assistive Technology Service Provider Interface
3 * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
4 *
5 * Copyright 2008 Novell, Inc.
6 * Copyright 2008, 2009, 2010 Codethink Ltd.
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
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 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the
20 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22 */
23
24 /*
25 * This module contains utility functions for exporting AT-SPI
26 * objects based upon an ATK object.
27 *
28 * It incudes functions for marshalling object references
29 * and supported interfaces to a D-Bus message.
30 */
31
32 #include <atk/atk.h>
33 #include "atspi/atspi.h"
34 #include "spi-dbus.h"
35
36 #include "accessible-register.h"
37 #include "accessible-cache.h"
38 #include "accessible-leasing.h"
39
40 #include "bridge.h"
41
42 /*---------------------------------------------------------------------------*/
43
44 /*
45 * This is the all important function that decides whether an object should
46 * be leased or not.
47 *
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.
50 *
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.
54 *
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.
57 */
58 void
spi_object_lease_if_needed(GObject * obj)59 spi_object_lease_if_needed (GObject *obj)
60 {
61 if (!spi_cache_in (spi_global_cache, obj))
62 {
63 spi_leasing_take (spi_global_leasing, obj);
64 }
65 }
66
67 /*---------------------------------------------------------------------------*/
68
69 /*
70 * It is assumed that all of these functions are returning an accessible
71 * object to the client side.
72 *
73 * All of them will lease the AtkObject if it is deemed neccessary.
74 */
75
76 void
spi_object_append_null_reference(DBusMessageIter * iter)77 spi_object_append_null_reference (DBusMessageIter * iter)
78 {
79 DBusMessageIter iter_struct;
80 const char *name;
81 const char *path = ATSPI_DBUS_PATH_NULL;
82
83 name = dbus_bus_get_unique_name (spi_global_app_data->bus);
84
85 dbus_message_iter_open_container (iter, DBUS_TYPE_STRUCT, NULL,
86 &iter_struct);
87 dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &name);
88 dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_OBJECT_PATH, &path);
89 dbus_message_iter_close_container (iter, &iter_struct);
90 }
91
92 void
spi_object_append_reference(DBusMessageIter * iter,AtkObject * obj)93 spi_object_append_reference (DBusMessageIter * iter, AtkObject * obj)
94 {
95 DBusMessageIter iter_struct;
96 const gchar *name;
97 gchar *path;
98
99 if (!obj) {
100 spi_object_append_null_reference (iter);
101 return;
102 }
103
104 spi_object_lease_if_needed (G_OBJECT (obj));
105
106 name = dbus_bus_get_unique_name (spi_global_app_data->bus);
107 path = spi_register_object_to_path (spi_global_register, G_OBJECT (obj));
108
109 if (!path)
110 path = g_strdup (SPI_DBUS_PATH_NULL);
111
112 dbus_message_iter_open_container (iter, DBUS_TYPE_STRUCT, NULL,
113 &iter_struct);
114 dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &name);
115 dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_OBJECT_PATH, &path);
116 dbus_message_iter_close_container (iter, &iter_struct);
117
118 g_free (path);
119 }
120
121 /* TODO: Perhaps combine with spi_object_append_reference. Leaving separate
122 * for now in case we want to use a different path for hyperlinks. */
123 void
spi_hyperlink_append_reference(DBusMessageIter * iter,AtkHyperlink * obj)124 spi_hyperlink_append_reference (DBusMessageIter * iter, AtkHyperlink * obj)
125 {
126 DBusMessageIter iter_struct;
127 const gchar *name;
128 gchar *path;
129
130 if (!obj) {
131 spi_object_append_null_reference (iter);
132 return;
133 }
134
135 spi_object_lease_if_needed (G_OBJECT (obj));
136
137 name = dbus_bus_get_unique_name (spi_global_app_data->bus);
138 path = spi_register_object_to_path (spi_global_register, G_OBJECT (obj));
139
140 if (!path)
141 path = g_strdup (SPI_DBUS_PATH_NULL);
142
143 dbus_message_iter_open_container (iter, DBUS_TYPE_STRUCT, NULL,
144 &iter_struct);
145 dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &name);
146 dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_OBJECT_PATH, &path);
147 dbus_message_iter_close_container (iter, &iter_struct);
148
149 g_free (path);
150 }
151
152 void
spi_object_append_v_reference(DBusMessageIter * iter,AtkObject * obj)153 spi_object_append_v_reference (DBusMessageIter * iter, AtkObject * obj)
154 {
155 DBusMessageIter iter_variant;
156
157 dbus_message_iter_open_container (iter, DBUS_TYPE_VARIANT, "(so)",
158 &iter_variant);
159 spi_object_append_reference (&iter_variant, obj);
160 dbus_message_iter_close_container (iter, &iter_variant);
161 }
162
163 void
spi_object_append_desktop_reference(DBusMessageIter * iter)164 spi_object_append_desktop_reference (DBusMessageIter * iter)
165 {
166 DBusMessageIter iter_struct;
167 const char *name = spi_global_app_data->desktop_name;
168 const char *path = spi_global_app_data->desktop_path;
169
170 dbus_message_iter_open_container (iter, DBUS_TYPE_STRUCT, NULL,
171 &iter_struct);
172 dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &name);
173 dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_OBJECT_PATH, &path);
174 dbus_message_iter_close_container (iter, &iter_struct);
175 }
176
177 DBusMessage *
spi_object_return_reference(DBusMessage * msg,AtkObject * obj)178 spi_object_return_reference (DBusMessage * msg, AtkObject * obj)
179 {
180 DBusMessage *reply;
181
182 reply = dbus_message_new_method_return (msg);
183 if (reply)
184 {
185 DBusMessageIter iter;
186 dbus_message_iter_init_append (reply, &iter);
187 spi_object_append_reference (&iter, obj);
188 }
189
190 return reply;
191 }
192
193 DBusMessage *
spi_hyperlink_return_reference(DBusMessage * msg,AtkHyperlink * obj)194 spi_hyperlink_return_reference (DBusMessage * msg, AtkHyperlink * obj)
195 {
196 DBusMessage *reply;
197
198 reply = dbus_message_new_method_return (msg);
199 if (reply)
200 {
201 DBusMessageIter iter;
202 dbus_message_iter_init_append (reply, &iter);
203 spi_hyperlink_append_reference (&iter, obj);
204 }
205 if (obj)
206 g_object_unref (G_OBJECT (obj));
207
208 return reply;
209 }
210
211 /*---------------------------------------------------------------------------*/
212
213 void
spi_object_append_interfaces(DBusMessageIter * iter,AtkObject * obj)214 spi_object_append_interfaces (DBusMessageIter * iter, AtkObject * obj)
215 {
216 const gchar *itf;
217
218 itf = ATSPI_DBUS_INTERFACE_ACCESSIBLE;
219 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
220
221 if (ATK_IS_ACTION (obj))
222 {
223 itf = ATSPI_DBUS_INTERFACE_ACTION;
224 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
225 }
226
227 if (atk_object_get_role (obj) == ATK_ROLE_APPLICATION)
228 {
229 itf = ATSPI_DBUS_INTERFACE_APPLICATION;
230 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
231 }
232
233 if (ATK_IS_COMPONENT (obj))
234 {
235 itf = ATSPI_DBUS_INTERFACE_COMPONENT;
236 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
237 }
238
239 if (ATK_IS_EDITABLE_TEXT (obj))
240 {
241 itf = ATSPI_DBUS_INTERFACE_EDITABLE_TEXT;
242 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
243 }
244
245 if (ATK_IS_TEXT (obj))
246 {
247 itf = ATSPI_DBUS_INTERFACE_TEXT;
248 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
249 }
250
251 if (ATK_IS_HYPERTEXT (obj))
252 {
253 itf = ATSPI_DBUS_INTERFACE_HYPERTEXT;
254 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
255 }
256
257 if (ATK_IS_IMAGE (obj))
258 {
259 itf = ATSPI_DBUS_INTERFACE_IMAGE;
260 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
261 }
262
263 if (ATK_IS_SELECTION (obj))
264 {
265 itf = ATSPI_DBUS_INTERFACE_SELECTION;
266 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
267 }
268
269 if (ATK_IS_TABLE (obj))
270 {
271 itf = ATSPI_DBUS_INTERFACE_TABLE;
272 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
273 }
274
275 if (ATK_IS_TABLE_CELL (obj))
276 {
277 itf = ATSPI_DBUS_INTERFACE_TABLE_CELL;
278 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
279 }
280
281 if (ATK_IS_VALUE (obj))
282 {
283 itf = ATSPI_DBUS_INTERFACE_VALUE;
284 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
285 }
286
287 #if 0
288 if (ATK_IS_STREAMABLE_CONTENT (obj))
289 {
290 itf = "org.a11y.atspi.StreamableContent";
291 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
292 }
293 #endif
294
295 if (ATK_IS_OBJECT (obj))
296 {
297 itf = "org.a11y.atspi.Collection";
298 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
299 }
300
301 if (ATK_IS_DOCUMENT (obj))
302 {
303 itf = ATSPI_DBUS_INTERFACE_DOCUMENT;
304 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
305 }
306
307 if (ATK_IS_HYPERLINK_IMPL (obj))
308 {
309 itf = ATSPI_DBUS_INTERFACE_HYPERLINK;
310 dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
311 }
312 }
313
314 /*---------------------------------------------------------------------------*/
315
316 void
spi_object_append_attribute_set(DBusMessageIter * iter,AtkAttributeSet * attr)317 spi_object_append_attribute_set (DBusMessageIter * iter, AtkAttributeSet * attr)
318 {
319 DBusMessageIter dictIter;
320
321 dbus_message_iter_open_container (iter, DBUS_TYPE_ARRAY, "{ss}", &dictIter);
322 while (attr)
323 {
324 DBusMessageIter dictEntryIter;
325 AtkAttribute *attribute = (AtkAttribute *) attr->data;
326 const char *key = attribute->name;
327 const char *value = attribute->value;
328
329 if (key == NULL)
330 key = "";
331 if (value == NULL)
332 value = "";
333
334 dbus_message_iter_open_container (&dictIter, DBUS_TYPE_DICT_ENTRY, NULL,
335 &dictEntryIter);
336 dbus_message_iter_append_basic (&dictEntryIter, DBUS_TYPE_STRING,
337 &key);
338 dbus_message_iter_append_basic (&dictEntryIter, DBUS_TYPE_STRING,
339 &value);
340 dbus_message_iter_close_container (&dictIter, &dictEntryIter);
341 attr = g_slist_next (attr);
342 }
343 dbus_message_iter_close_container (iter, &dictIter);
344 }
345
346 /*---------------------------------------------------------------------------*/
347
348 static gboolean
init_role_lookup_table(AtspiRole * role_table)349 init_role_lookup_table (AtspiRole * role_table)
350 {
351 int i;
352 /* if it's not in the list below, dunno what it is */
353 for (i = 0; i < ATK_ROLE_LAST_DEFINED; ++i)
354 {
355 role_table[i] = ATSPI_ROLE_UNKNOWN;
356 }
357
358 role_table[ATK_ROLE_INVALID] = ATSPI_ROLE_INVALID;
359 role_table[ATK_ROLE_ACCEL_LABEL] = ATSPI_ROLE_ACCELERATOR_LABEL;
360 role_table[ATK_ROLE_ALERT] = ATSPI_ROLE_ALERT;
361 role_table[ATK_ROLE_ANIMATION] = ATSPI_ROLE_ANIMATION;
362 role_table[ATK_ROLE_ARROW] = ATSPI_ROLE_ARROW;
363 role_table[ATK_ROLE_CALENDAR] = ATSPI_ROLE_CALENDAR;
364 role_table[ATK_ROLE_CANVAS] = ATSPI_ROLE_CANVAS;
365 role_table[ATK_ROLE_CHECK_BOX] = ATSPI_ROLE_CHECK_BOX;
366 role_table[ATK_ROLE_CHECK_MENU_ITEM] = ATSPI_ROLE_CHECK_MENU_ITEM;
367 role_table[ATK_ROLE_COLOR_CHOOSER] = ATSPI_ROLE_COLOR_CHOOSER;
368 role_table[ATK_ROLE_COLUMN_HEADER] = ATSPI_ROLE_COLUMN_HEADER;
369 role_table[ATK_ROLE_COMBO_BOX] = ATSPI_ROLE_COMBO_BOX;
370 role_table[ATK_ROLE_DATE_EDITOR] = ATSPI_ROLE_DATE_EDITOR;
371 role_table[ATK_ROLE_DESKTOP_ICON] = ATSPI_ROLE_DESKTOP_ICON;
372 role_table[ATK_ROLE_DESKTOP_FRAME] = ATSPI_ROLE_DESKTOP_FRAME;
373 role_table[ATK_ROLE_DIAL] = ATSPI_ROLE_DIAL;
374 role_table[ATK_ROLE_DIALOG] = ATSPI_ROLE_DIALOG;
375 role_table[ATK_ROLE_DIRECTORY_PANE] = ATSPI_ROLE_DIRECTORY_PANE;
376 role_table[ATK_ROLE_DRAWING_AREA] = ATSPI_ROLE_DRAWING_AREA;
377 role_table[ATK_ROLE_FILE_CHOOSER] = ATSPI_ROLE_FILE_CHOOSER;
378 role_table[ATK_ROLE_FILLER] = ATSPI_ROLE_FILLER;
379 role_table[ATK_ROLE_FONT_CHOOSER] = ATSPI_ROLE_FONT_CHOOSER;
380 role_table[ATK_ROLE_FRAME] = ATSPI_ROLE_FRAME;
381 role_table[ATK_ROLE_GLASS_PANE] = ATSPI_ROLE_GLASS_PANE;
382 role_table[ATK_ROLE_HTML_CONTAINER] = ATSPI_ROLE_HTML_CONTAINER;
383 role_table[ATK_ROLE_ICON] = ATSPI_ROLE_ICON;
384 role_table[ATK_ROLE_IMAGE] = ATSPI_ROLE_IMAGE;
385 role_table[ATK_ROLE_INTERNAL_FRAME] = ATSPI_ROLE_INTERNAL_FRAME;
386 role_table[ATK_ROLE_LABEL] = ATSPI_ROLE_LABEL;
387 role_table[ATK_ROLE_LAYERED_PANE] = ATSPI_ROLE_LAYERED_PANE;
388 role_table[ATK_ROLE_LIST] = ATSPI_ROLE_LIST;
389 role_table[ATK_ROLE_LIST_ITEM] = ATSPI_ROLE_LIST_ITEM;
390 role_table[ATK_ROLE_MENU] = ATSPI_ROLE_MENU;
391 role_table[ATK_ROLE_MENU_BAR] = ATSPI_ROLE_MENU_BAR;
392 role_table[ATK_ROLE_MENU_ITEM] = ATSPI_ROLE_MENU_ITEM;
393 role_table[ATK_ROLE_OPTION_PANE] = ATSPI_ROLE_OPTION_PANE;
394 role_table[ATK_ROLE_PAGE_TAB] = ATSPI_ROLE_PAGE_TAB;
395 role_table[ATK_ROLE_PAGE_TAB_LIST] = ATSPI_ROLE_PAGE_TAB_LIST;
396 role_table[ATK_ROLE_PANEL] = ATSPI_ROLE_PANEL;
397 role_table[ATK_ROLE_PASSWORD_TEXT] = ATSPI_ROLE_PASSWORD_TEXT;
398 role_table[ATK_ROLE_POPUP_MENU] = ATSPI_ROLE_POPUP_MENU;
399 role_table[ATK_ROLE_PROGRESS_BAR] = ATSPI_ROLE_PROGRESS_BAR;
400 role_table[ATK_ROLE_PUSH_BUTTON] = ATSPI_ROLE_PUSH_BUTTON;
401 role_table[ATK_ROLE_RADIO_BUTTON] = ATSPI_ROLE_RADIO_BUTTON;
402 role_table[ATK_ROLE_RADIO_MENU_ITEM] = ATSPI_ROLE_RADIO_MENU_ITEM;
403 role_table[ATK_ROLE_ROOT_PANE] = ATSPI_ROLE_ROOT_PANE;
404 role_table[ATK_ROLE_ROW_HEADER] = ATSPI_ROLE_ROW_HEADER;
405 role_table[ATK_ROLE_SCROLL_BAR] = ATSPI_ROLE_SCROLL_BAR;
406 role_table[ATK_ROLE_SCROLL_PANE] = ATSPI_ROLE_SCROLL_PANE;
407 role_table[ATK_ROLE_SEPARATOR] = ATSPI_ROLE_SEPARATOR;
408 role_table[ATK_ROLE_SLIDER] = ATSPI_ROLE_SLIDER;
409 role_table[ATK_ROLE_SPIN_BUTTON] = ATSPI_ROLE_SPIN_BUTTON;
410 role_table[ATK_ROLE_SPLIT_PANE] = ATSPI_ROLE_SPLIT_PANE;
411 role_table[ATK_ROLE_STATUSBAR] = ATSPI_ROLE_STATUS_BAR;
412 role_table[ATK_ROLE_TABLE] = ATSPI_ROLE_TABLE;
413 role_table[ATK_ROLE_TABLE_CELL] = ATSPI_ROLE_TABLE_CELL;
414 role_table[ATK_ROLE_TABLE_COLUMN_HEADER] =
415 ATSPI_ROLE_TABLE_COLUMN_HEADER;
416 role_table[ATK_ROLE_TABLE_ROW_HEADER] = ATSPI_ROLE_TABLE_ROW_HEADER;
417 role_table[ATK_ROLE_TEAR_OFF_MENU_ITEM] =
418 ATSPI_ROLE_TEAROFF_MENU_ITEM;
419 role_table[ATK_ROLE_TERMINAL] = ATSPI_ROLE_TERMINAL;
420 role_table[ATK_ROLE_TEXT] = ATSPI_ROLE_TEXT;
421 role_table[ATK_ROLE_TOGGLE_BUTTON] = ATSPI_ROLE_TOGGLE_BUTTON;
422 role_table[ATK_ROLE_TOOL_BAR] = ATSPI_ROLE_TOOL_BAR;
423 role_table[ATK_ROLE_TOOL_TIP] = ATSPI_ROLE_TOOL_TIP;
424 role_table[ATK_ROLE_TREE] = ATSPI_ROLE_TREE;
425 role_table[ATK_ROLE_TREE_TABLE] = ATSPI_ROLE_TREE_TABLE;
426 role_table[ATK_ROLE_UNKNOWN] = ATSPI_ROLE_UNKNOWN;
427 role_table[ATK_ROLE_VIEWPORT] = ATSPI_ROLE_VIEWPORT;
428 role_table[ATK_ROLE_WINDOW] = ATSPI_ROLE_WINDOW;
429 role_table[ATK_ROLE_HEADER] = ATSPI_ROLE_HEADER;
430 role_table[ATK_ROLE_FOOTER] = ATSPI_ROLE_FOOTER;
431 role_table[ATK_ROLE_PARAGRAPH] = ATSPI_ROLE_PARAGRAPH;
432 role_table[ATK_ROLE_RULER] = ATSPI_ROLE_RULER;
433 role_table[ATK_ROLE_APPLICATION] = ATSPI_ROLE_APPLICATION;
434 role_table[ATK_ROLE_AUTOCOMPLETE] = ATSPI_ROLE_AUTOCOMPLETE;
435 role_table[ATK_ROLE_EDITBAR] = ATSPI_ROLE_EDITBAR;
436 role_table[ATK_ROLE_EMBEDDED] = ATSPI_ROLE_EMBEDDED;
437 role_table[ATK_ROLE_ENTRY] = ATSPI_ROLE_ENTRY;
438 role_table[ATK_ROLE_CHART] = ATSPI_ROLE_CHART;
439 role_table[ATK_ROLE_CAPTION] = ATSPI_ROLE_CAPTION;
440 role_table[ATK_ROLE_DOCUMENT_FRAME] = ATSPI_ROLE_DOCUMENT_FRAME;
441 role_table[ATK_ROLE_HEADING] = ATSPI_ROLE_HEADING;
442 role_table[ATK_ROLE_PAGE] = ATSPI_ROLE_PAGE;
443 role_table[ATK_ROLE_SECTION] = ATSPI_ROLE_SECTION;
444 role_table[ATK_ROLE_FORM] = ATSPI_ROLE_FORM;
445 role_table[ATK_ROLE_REDUNDANT_OBJECT] = ATSPI_ROLE_REDUNDANT_OBJECT;
446 role_table[ATK_ROLE_LINK] = ATSPI_ROLE_LINK;
447 role_table[ATK_ROLE_INPUT_METHOD_WINDOW] =
448 ATSPI_ROLE_INPUT_METHOD_WINDOW;
449 role_table[ATK_ROLE_TABLE_ROW] = ATSPI_ROLE_TABLE_ROW;
450 role_table[ATK_ROLE_TREE_ITEM] = ATSPI_ROLE_TREE_ITEM;
451 role_table[ATK_ROLE_DOCUMENT_SPREADSHEET] =
452 ATSPI_ROLE_DOCUMENT_SPREADSHEET;
453 role_table[ATK_ROLE_DOCUMENT_PRESENTATION] =
454 ATSPI_ROLE_DOCUMENT_PRESENTATION;
455 role_table[ATK_ROLE_DOCUMENT_TEXT] = ATSPI_ROLE_DOCUMENT_TEXT;
456 role_table[ATK_ROLE_DOCUMENT_WEB] = ATSPI_ROLE_DOCUMENT_WEB;
457 role_table[ATK_ROLE_DOCUMENT_EMAIL] = ATSPI_ROLE_DOCUMENT_EMAIL;
458 role_table[ATK_ROLE_COMMENT] = ATSPI_ROLE_COMMENT;
459 role_table[ATK_ROLE_LIST_BOX] = ATSPI_ROLE_LIST_BOX;
460 role_table[ATK_ROLE_GROUPING] = ATSPI_ROLE_GROUPING;
461 role_table[ATK_ROLE_IMAGE_MAP] = ATSPI_ROLE_IMAGE_MAP;
462 role_table[ATK_ROLE_NOTIFICATION] = ATSPI_ROLE_NOTIFICATION;
463 role_table[ATK_ROLE_INFO_BAR] = ATSPI_ROLE_INFO_BAR;
464 role_table[ATK_ROLE_LEVEL_BAR] = ATSPI_ROLE_LEVEL_BAR;
465 role_table[ATK_ROLE_TITLE_BAR] = ATSPI_ROLE_TITLE_BAR;
466 role_table[ATK_ROLE_BLOCK_QUOTE] = ATSPI_ROLE_BLOCK_QUOTE;
467 role_table[ATK_ROLE_AUDIO] = ATSPI_ROLE_AUDIO;
468 role_table[ATK_ROLE_VIDEO] = ATSPI_ROLE_VIDEO;
469 role_table[ATK_ROLE_DEFINITION] = ATSPI_ROLE_DEFINITION;
470 role_table[ATK_ROLE_ARTICLE] = ATSPI_ROLE_ARTICLE;
471 role_table[ATK_ROLE_LANDMARK] = ATSPI_ROLE_LANDMARK;
472 role_table[ATK_ROLE_LOG] = ATSPI_ROLE_LOG;
473 role_table[ATK_ROLE_MARQUEE] = ATSPI_ROLE_MARQUEE;
474 role_table[ATK_ROLE_MATH] = ATSPI_ROLE_MATH;
475 role_table[ATK_ROLE_RATING] = ATSPI_ROLE_RATING;
476 role_table[ATK_ROLE_TIMER] = ATSPI_ROLE_TIMER;
477 role_table[ATK_ROLE_STATIC] = ATSPI_ROLE_STATIC;
478 role_table[ATK_ROLE_MATH_FRACTION] = ATSPI_ROLE_MATH_FRACTION;
479 role_table[ATK_ROLE_MATH_ROOT] = ATSPI_ROLE_MATH_ROOT;
480 role_table[ATK_ROLE_SUBSCRIPT] = ATSPI_ROLE_SUBSCRIPT;
481 role_table[ATK_ROLE_SUPERSCRIPT] = ATSPI_ROLE_SUPERSCRIPT;
482 role_table[ATK_ROLE_DESCRIPTION_LIST] = ATSPI_ROLE_DESCRIPTION_LIST;
483 role_table[ATK_ROLE_DESCRIPTION_TERM] = ATSPI_ROLE_DESCRIPTION_TERM;
484 role_table[ATK_ROLE_DESCRIPTION_VALUE] = ATSPI_ROLE_DESCRIPTION_VALUE;
485 role_table[ATK_ROLE_FOOTNOTE] = ATSPI_ROLE_FOOTNOTE;
486 role_table[ATK_ROLE_CONTENT_DELETION] = ATSPI_ROLE_CONTENT_DELETION;
487 role_table[ATK_ROLE_CONTENT_INSERTION] = ATSPI_ROLE_CONTENT_INSERTION;
488
489 return TRUE;
490 }
491
492 AtspiRole
spi_accessible_role_from_atk_role(AtkRole role)493 spi_accessible_role_from_atk_role (AtkRole role)
494 {
495 static gboolean is_initialized = FALSE;
496 static AtspiRole spi_role_table[ATK_ROLE_LAST_DEFINED];
497 AtspiRole spi_role;
498
499 if (!is_initialized)
500 {
501 is_initialized = init_role_lookup_table (spi_role_table);
502 }
503
504 if (role >= 0 && role < ATK_ROLE_LAST_DEFINED)
505 {
506 spi_role = spi_role_table[role];
507 }
508 else
509 {
510 spi_role = ATSPI_ROLE_EXTENDED;
511 }
512 return spi_role;
513 }
514
515 /*END------------------------------------------------------------------------*/
516