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 "atspi/atspi.h"
33
#include "spi-dbus.h"
34
#include <atk/atk.h>
35

            
36
#include "accessible-cache.h"
37
#include "accessible-leasing.h"
38
#include "accessible-register.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
59
4801
spi_object_lease_if_needed (GObject *obj)
60
{
61
4801
  if (!spi_cache_in (spi_global_cache, obj))
62
    {
63
171
      spi_leasing_take (spi_global_leasing, obj);
64
    }
65
4801
}
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
77
137
spi_object_append_null_reference (DBusMessageIter *iter)
78
{
79
  DBusMessageIter iter_struct;
80
  const char *name;
81
137
  const char *path = ATSPI_DBUS_PATH_NULL;
82

            
83
137
  name = dbus_bus_get_unique_name (spi_global_app_data->bus);
84

            
85
137
  dbus_message_iter_open_container (iter, DBUS_TYPE_STRUCT, NULL,
86
                                    &iter_struct);
87
137
  dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &name);
88
137
  dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_OBJECT_PATH, &path);
89
137
  dbus_message_iter_close_container (iter, &iter_struct);
90
137
}
91

            
92
void
93
4461
spi_object_append_reference (DBusMessageIter *iter, AtkObject *obj)
94
{
95
  DBusMessageIter iter_struct;
96
  const gchar *name;
97
  gchar *path;
98

            
99
4461
  if (!obj)
100
    {
101
      spi_object_append_null_reference (iter);
102
      return;
103
    }
104

            
105
4461
  spi_object_lease_if_needed (G_OBJECT (obj));
106

            
107
4461
  name = dbus_bus_get_unique_name (spi_global_app_data->bus);
108
4461
  path = spi_register_object_to_path (spi_global_register, G_OBJECT (obj));
109

            
110
4461
  if (!path)
111
    path = g_strdup (SPI_DBUS_PATH_NULL);
112

            
113
4461
  dbus_message_iter_open_container (iter, DBUS_TYPE_STRUCT, NULL,
114
                                    &iter_struct);
115
4461
  dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &name);
116
4461
  dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_OBJECT_PATH, &path);
117
4461
  dbus_message_iter_close_container (iter, &iter_struct);
118

            
119
4461
  g_free (path);
120
}
121

            
122
/* TODO: Perhaps combine with spi_object_append_reference.  Leaving separate
123
 * for now in case we want to use a different path for hyperlinks. */
124
void
125
9
spi_hyperlink_append_reference (DBusMessageIter *iter, AtkHyperlink *obj)
126
{
127
  DBusMessageIter iter_struct;
128
  const gchar *name;
129
  gchar *path;
130

            
131
9
  if (!obj)
132
    {
133
      spi_object_append_null_reference (iter);
134
      return;
135
    }
136

            
137
9
  spi_object_lease_if_needed (G_OBJECT (obj));
138

            
139
9
  name = dbus_bus_get_unique_name (spi_global_app_data->bus);
140
9
  path = spi_register_object_to_path (spi_global_register, G_OBJECT (obj));
141

            
142
9
  if (!path)
143
    path = g_strdup (SPI_DBUS_PATH_NULL);
144

            
145
9
  dbus_message_iter_open_container (iter, DBUS_TYPE_STRUCT, NULL,
146
                                    &iter_struct);
147
9
  dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &name);
148
9
  dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_OBJECT_PATH, &path);
149
9
  dbus_message_iter_close_container (iter, &iter_struct);
150

            
151
9
  g_free (path);
152
}
153

            
154
void
155
2
spi_object_append_v_reference (DBusMessageIter *iter, AtkObject *obj)
156
{
157
  DBusMessageIter iter_variant;
158

            
159
2
  dbus_message_iter_open_container (iter, DBUS_TYPE_VARIANT, "(so)",
160
                                    &iter_variant);
161
2
  spi_object_append_reference (&iter_variant, obj);
162
2
  dbus_message_iter_close_container (iter, &iter_variant);
163
2
}
164

            
165
void
166
spi_object_append_desktop_reference (DBusMessageIter *iter)
167
{
168
  DBusMessageIter iter_struct;
169
  const char *name = spi_global_app_data->desktop_name;
170
  const char *path = spi_global_app_data->desktop_path;
171

            
172
  dbus_message_iter_open_container (iter, DBUS_TYPE_STRUCT, NULL,
173
                                    &iter_struct);
174
  dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &name);
175
  dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_OBJECT_PATH, &path);
176
  dbus_message_iter_close_container (iter, &iter_struct);
177
}
178

            
179
DBusMessage *
180
150
spi_object_return_reference (DBusMessage *msg, AtkObject *obj)
181
{
182
  DBusMessage *reply;
183

            
184
150
  reply = dbus_message_new_method_return (msg);
185
150
  if (reply)
186
    {
187
      DBusMessageIter iter;
188
150
      dbus_message_iter_init_append (reply, &iter);
189
150
      spi_object_append_reference (&iter, obj);
190
    }
191

            
192
150
  return reply;
193
}
194

            
195
DBusMessage *
196
9
spi_hyperlink_return_reference (DBusMessage *msg, AtkHyperlink *obj)
197
{
198
  DBusMessage *reply;
199

            
200
9
  reply = dbus_message_new_method_return (msg);
201
9
  if (reply)
202
    {
203
      DBusMessageIter iter;
204
9
      dbus_message_iter_init_append (reply, &iter);
205
9
      spi_hyperlink_append_reference (&iter, obj);
206
    }
207
9
  if (obj)
208
9
    g_object_unref (G_OBJECT (obj));
209

            
210
9
  return reply;
211
}
212

            
213
/*---------------------------------------------------------------------------*/
214

            
215
void
216
1541
spi_object_append_interfaces (DBusMessageIter *iter, AtkObject *obj)
217
{
218
  const gchar *itf;
219

            
220
1541
  itf = ATSPI_DBUS_INTERFACE_ACCESSIBLE;
221
1541
  dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
222

            
223
1541
  if (ATK_IS_ACTION (obj))
224
    {
225
21
      itf = ATSPI_DBUS_INTERFACE_ACTION;
226
21
      dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
227
    }
228

            
229
1541
  if (atk_object_get_role (obj) == ATK_ROLE_APPLICATION)
230
    {
231
32
      itf = ATSPI_DBUS_INTERFACE_APPLICATION;
232
32
      dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
233
    }
234

            
235
1541
  if (ATK_IS_COMPONENT (obj))
236
    {
237
36
      itf = ATSPI_DBUS_INTERFACE_COMPONENT;
238
36
      dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
239
    }
240

            
241
1541
  if (ATK_IS_EDITABLE_TEXT (obj))
242
    {
243
18
      itf = ATSPI_DBUS_INTERFACE_EDITABLE_TEXT;
244
18
      dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
245
    }
246

            
247
1541
  if (ATK_IS_TEXT (obj))
248
    {
249
61
      itf = ATSPI_DBUS_INTERFACE_TEXT;
250
61
      dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
251
    }
252

            
253
1541
  if (ATK_IS_HYPERTEXT (obj))
254
    {
255
20
      itf = ATSPI_DBUS_INTERFACE_HYPERTEXT;
256
20
      dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
257
    }
258

            
259
1541
  if (ATK_IS_IMAGE (obj))
260
    {
261
12
      itf = ATSPI_DBUS_INTERFACE_IMAGE;
262
12
      dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
263
    }
264

            
265
1541
  if (ATK_IS_SELECTION (obj))
266
    {
267
18
      itf = ATSPI_DBUS_INTERFACE_SELECTION;
268
18
      dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
269
    }
270

            
271
1541
  if (ATK_IS_TABLE (obj))
272
    {
273
58
      itf = ATSPI_DBUS_INTERFACE_TABLE;
274
58
      dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
275
    }
276

            
277
1541
  if (ATK_IS_TABLE_CELL (obj))
278
    {
279
384
      itf = ATSPI_DBUS_INTERFACE_TABLE_CELL;
280
384
      dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
281
    }
282

            
283
1541
  if (ATK_IS_VALUE (obj))
284
    {
285
14
      itf = ATSPI_DBUS_INTERFACE_VALUE;
286
14
      dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
287
    }
288

            
289
#if 0
290
  if (ATK_IS_STREAMABLE_CONTENT (obj))
291
    {
292
      itf = "org.a11y.atspi.StreamableContent";
293
      dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
294
    }
295
#endif
296

            
297
1541
  if (ATK_IS_OBJECT (obj))
298
    {
299
1541
      itf = "org.a11y.atspi.Collection";
300
1541
      dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
301
    }
302

            
303
1541
  if (ATK_IS_DOCUMENT (obj))
304
    {
305
10
      itf = ATSPI_DBUS_INTERFACE_DOCUMENT;
306
10
      dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
307
    }
308

            
309
1541
  if (ATK_IS_HYPERLINK_IMPL (obj))
310
    {
311
      itf = ATSPI_DBUS_INTERFACE_HYPERLINK;
312
      dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
313
    }
314
1541
}
315

            
316
/*---------------------------------------------------------------------------*/
317

            
318
void
319
6
spi_object_append_attribute_set (DBusMessageIter *iter, AtkAttributeSet *attr)
320
{
321
  DBusMessageIter dictIter;
322

            
323
6
  dbus_message_iter_open_container (iter, DBUS_TYPE_ARRAY, "{ss}", &dictIter);
324
19
  while (attr)
325
    {
326
      DBusMessageIter dictEntryIter;
327
13
      AtkAttribute *attribute = (AtkAttribute *) attr->data;
328
13
      const char *key = attribute->name;
329
13
      const char *value = attribute->value;
330

            
331
13
      if (key == NULL)
332
        key = "";
333
13
      if (value == NULL)
334
1
        value = "";
335

            
336
13
      dbus_message_iter_open_container (&dictIter, DBUS_TYPE_DICT_ENTRY, NULL,
337
                                        &dictEntryIter);
338
13
      dbus_message_iter_append_basic (&dictEntryIter, DBUS_TYPE_STRING,
339
                                      &key);
340
13
      dbus_message_iter_append_basic (&dictEntryIter, DBUS_TYPE_STRING,
341
                                      &value);
342
13
      dbus_message_iter_close_container (&dictIter, &dictEntryIter);
343
13
      attr = g_slist_next (attr);
344
    }
345
6
  dbus_message_iter_close_container (iter, &dictIter);
346
6
}
347

            
348
/*---------------------------------------------------------------------------*/
349

            
350
static gboolean
351
139
init_role_lookup_table (AtspiRole *role_table)
352
{
353
  int i;
354
  /* if it's not in the list below, dunno what it is */
355
17931
  for (i = 0; i < ATK_ROLE_LAST_DEFINED; ++i)
356
    {
357
17792
      role_table[i] = ATSPI_ROLE_UNKNOWN;
358
    }
359

            
360
139
  role_table[ATK_ROLE_INVALID] = ATSPI_ROLE_INVALID;
361
139
  role_table[ATK_ROLE_ACCEL_LABEL] = ATSPI_ROLE_ACCELERATOR_LABEL;
362
139
  role_table[ATK_ROLE_ALERT] = ATSPI_ROLE_ALERT;
363
139
  role_table[ATK_ROLE_ANIMATION] = ATSPI_ROLE_ANIMATION;
364
139
  role_table[ATK_ROLE_ARROW] = ATSPI_ROLE_ARROW;
365
139
  role_table[ATK_ROLE_CALENDAR] = ATSPI_ROLE_CALENDAR;
366
139
  role_table[ATK_ROLE_CANVAS] = ATSPI_ROLE_CANVAS;
367
139
  role_table[ATK_ROLE_CHECK_BOX] = ATSPI_ROLE_CHECK_BOX;
368
139
  role_table[ATK_ROLE_CHECK_MENU_ITEM] = ATSPI_ROLE_CHECK_MENU_ITEM;
369
139
  role_table[ATK_ROLE_COLOR_CHOOSER] = ATSPI_ROLE_COLOR_CHOOSER;
370
139
  role_table[ATK_ROLE_COLUMN_HEADER] = ATSPI_ROLE_COLUMN_HEADER;
371
139
  role_table[ATK_ROLE_COMBO_BOX] = ATSPI_ROLE_COMBO_BOX;
372
139
  role_table[ATK_ROLE_DATE_EDITOR] = ATSPI_ROLE_DATE_EDITOR;
373
139
  role_table[ATK_ROLE_DESKTOP_ICON] = ATSPI_ROLE_DESKTOP_ICON;
374
139
  role_table[ATK_ROLE_DESKTOP_FRAME] = ATSPI_ROLE_DESKTOP_FRAME;
375
139
  role_table[ATK_ROLE_DIAL] = ATSPI_ROLE_DIAL;
376
139
  role_table[ATK_ROLE_DIALOG] = ATSPI_ROLE_DIALOG;
377
139
  role_table[ATK_ROLE_DIRECTORY_PANE] = ATSPI_ROLE_DIRECTORY_PANE;
378
139
  role_table[ATK_ROLE_DRAWING_AREA] = ATSPI_ROLE_DRAWING_AREA;
379
139
  role_table[ATK_ROLE_FILE_CHOOSER] = ATSPI_ROLE_FILE_CHOOSER;
380
139
  role_table[ATK_ROLE_FILLER] = ATSPI_ROLE_FILLER;
381
139
  role_table[ATK_ROLE_FONT_CHOOSER] = ATSPI_ROLE_FONT_CHOOSER;
382
139
  role_table[ATK_ROLE_FRAME] = ATSPI_ROLE_FRAME;
383
139
  role_table[ATK_ROLE_GLASS_PANE] = ATSPI_ROLE_GLASS_PANE;
384
139
  role_table[ATK_ROLE_HTML_CONTAINER] = ATSPI_ROLE_HTML_CONTAINER;
385
139
  role_table[ATK_ROLE_ICON] = ATSPI_ROLE_ICON;
386
139
  role_table[ATK_ROLE_IMAGE] = ATSPI_ROLE_IMAGE;
387
139
  role_table[ATK_ROLE_INTERNAL_FRAME] = ATSPI_ROLE_INTERNAL_FRAME;
388
139
  role_table[ATK_ROLE_LABEL] = ATSPI_ROLE_LABEL;
389
139
  role_table[ATK_ROLE_LAYERED_PANE] = ATSPI_ROLE_LAYERED_PANE;
390
139
  role_table[ATK_ROLE_LIST] = ATSPI_ROLE_LIST;
391
139
  role_table[ATK_ROLE_LIST_ITEM] = ATSPI_ROLE_LIST_ITEM;
392
139
  role_table[ATK_ROLE_MENU] = ATSPI_ROLE_MENU;
393
139
  role_table[ATK_ROLE_MENU_BAR] = ATSPI_ROLE_MENU_BAR;
394
139
  role_table[ATK_ROLE_MENU_ITEM] = ATSPI_ROLE_MENU_ITEM;
395
139
  role_table[ATK_ROLE_OPTION_PANE] = ATSPI_ROLE_OPTION_PANE;
396
139
  role_table[ATK_ROLE_PAGE_TAB] = ATSPI_ROLE_PAGE_TAB;
397
139
  role_table[ATK_ROLE_PAGE_TAB_LIST] = ATSPI_ROLE_PAGE_TAB_LIST;
398
139
  role_table[ATK_ROLE_PANEL] = ATSPI_ROLE_PANEL;
399
139
  role_table[ATK_ROLE_PASSWORD_TEXT] = ATSPI_ROLE_PASSWORD_TEXT;
400
139
  role_table[ATK_ROLE_POPUP_MENU] = ATSPI_ROLE_POPUP_MENU;
401
139
  role_table[ATK_ROLE_PROGRESS_BAR] = ATSPI_ROLE_PROGRESS_BAR;
402
139
  role_table[ATK_ROLE_PUSH_BUTTON] = ATSPI_ROLE_PUSH_BUTTON;
403
139
  role_table[ATK_ROLE_RADIO_BUTTON] = ATSPI_ROLE_RADIO_BUTTON;
404
139
  role_table[ATK_ROLE_RADIO_MENU_ITEM] = ATSPI_ROLE_RADIO_MENU_ITEM;
405
139
  role_table[ATK_ROLE_ROOT_PANE] = ATSPI_ROLE_ROOT_PANE;
406
139
  role_table[ATK_ROLE_ROW_HEADER] = ATSPI_ROLE_ROW_HEADER;
407
139
  role_table[ATK_ROLE_SCROLL_BAR] = ATSPI_ROLE_SCROLL_BAR;
408
139
  role_table[ATK_ROLE_SCROLL_PANE] = ATSPI_ROLE_SCROLL_PANE;
409
139
  role_table[ATK_ROLE_SEPARATOR] = ATSPI_ROLE_SEPARATOR;
410
139
  role_table[ATK_ROLE_SLIDER] = ATSPI_ROLE_SLIDER;
411
139
  role_table[ATK_ROLE_SPIN_BUTTON] = ATSPI_ROLE_SPIN_BUTTON;
412
139
  role_table[ATK_ROLE_SPLIT_PANE] = ATSPI_ROLE_SPLIT_PANE;
413
139
  role_table[ATK_ROLE_STATUSBAR] = ATSPI_ROLE_STATUS_BAR;
414
139
  role_table[ATK_ROLE_TABLE] = ATSPI_ROLE_TABLE;
415
139
  role_table[ATK_ROLE_TABLE_CELL] = ATSPI_ROLE_TABLE_CELL;
416
139
  role_table[ATK_ROLE_TABLE_COLUMN_HEADER] =
417
      ATSPI_ROLE_TABLE_COLUMN_HEADER;
418
139
  role_table[ATK_ROLE_TABLE_ROW_HEADER] = ATSPI_ROLE_TABLE_ROW_HEADER;
419
139
  role_table[ATK_ROLE_TEAR_OFF_MENU_ITEM] =
420
      ATSPI_ROLE_TEAROFF_MENU_ITEM;
421
139
  role_table[ATK_ROLE_TERMINAL] = ATSPI_ROLE_TERMINAL;
422
139
  role_table[ATK_ROLE_TEXT] = ATSPI_ROLE_TEXT;
423
139
  role_table[ATK_ROLE_TOGGLE_BUTTON] = ATSPI_ROLE_TOGGLE_BUTTON;
424
139
  role_table[ATK_ROLE_TOOL_BAR] = ATSPI_ROLE_TOOL_BAR;
425
139
  role_table[ATK_ROLE_TOOL_TIP] = ATSPI_ROLE_TOOL_TIP;
426
139
  role_table[ATK_ROLE_TREE] = ATSPI_ROLE_TREE;
427
139
  role_table[ATK_ROLE_TREE_TABLE] = ATSPI_ROLE_TREE_TABLE;
428
139
  role_table[ATK_ROLE_UNKNOWN] = ATSPI_ROLE_UNKNOWN;
429
139
  role_table[ATK_ROLE_VIEWPORT] = ATSPI_ROLE_VIEWPORT;
430
139
  role_table[ATK_ROLE_WINDOW] = ATSPI_ROLE_WINDOW;
431
139
  role_table[ATK_ROLE_HEADER] = ATSPI_ROLE_HEADER;
432
139
  role_table[ATK_ROLE_FOOTER] = ATSPI_ROLE_FOOTER;
433
139
  role_table[ATK_ROLE_PARAGRAPH] = ATSPI_ROLE_PARAGRAPH;
434
139
  role_table[ATK_ROLE_RULER] = ATSPI_ROLE_RULER;
435
139
  role_table[ATK_ROLE_APPLICATION] = ATSPI_ROLE_APPLICATION;
436
139
  role_table[ATK_ROLE_AUTOCOMPLETE] = ATSPI_ROLE_AUTOCOMPLETE;
437
139
  role_table[ATK_ROLE_EDITBAR] = ATSPI_ROLE_EDITBAR;
438
139
  role_table[ATK_ROLE_EMBEDDED] = ATSPI_ROLE_EMBEDDED;
439
139
  role_table[ATK_ROLE_ENTRY] = ATSPI_ROLE_ENTRY;
440
139
  role_table[ATK_ROLE_CHART] = ATSPI_ROLE_CHART;
441
139
  role_table[ATK_ROLE_CAPTION] = ATSPI_ROLE_CAPTION;
442
139
  role_table[ATK_ROLE_DOCUMENT_FRAME] = ATSPI_ROLE_DOCUMENT_FRAME;
443
139
  role_table[ATK_ROLE_HEADING] = ATSPI_ROLE_HEADING;
444
139
  role_table[ATK_ROLE_PAGE] = ATSPI_ROLE_PAGE;
445
139
  role_table[ATK_ROLE_SECTION] = ATSPI_ROLE_SECTION;
446
139
  role_table[ATK_ROLE_FORM] = ATSPI_ROLE_FORM;
447
139
  role_table[ATK_ROLE_REDUNDANT_OBJECT] = ATSPI_ROLE_REDUNDANT_OBJECT;
448
139
  role_table[ATK_ROLE_LINK] = ATSPI_ROLE_LINK;
449
139
  role_table[ATK_ROLE_INPUT_METHOD_WINDOW] =
450
      ATSPI_ROLE_INPUT_METHOD_WINDOW;
451
139
  role_table[ATK_ROLE_TABLE_ROW] = ATSPI_ROLE_TABLE_ROW;
452
139
  role_table[ATK_ROLE_TREE_ITEM] = ATSPI_ROLE_TREE_ITEM;
453
139
  role_table[ATK_ROLE_DOCUMENT_SPREADSHEET] =
454
      ATSPI_ROLE_DOCUMENT_SPREADSHEET;
455
139
  role_table[ATK_ROLE_DOCUMENT_PRESENTATION] =
456
      ATSPI_ROLE_DOCUMENT_PRESENTATION;
457
139
  role_table[ATK_ROLE_DOCUMENT_TEXT] = ATSPI_ROLE_DOCUMENT_TEXT;
458
139
  role_table[ATK_ROLE_DOCUMENT_WEB] = ATSPI_ROLE_DOCUMENT_WEB;
459
139
  role_table[ATK_ROLE_DOCUMENT_EMAIL] = ATSPI_ROLE_DOCUMENT_EMAIL;
460
139
  role_table[ATK_ROLE_COMMENT] = ATSPI_ROLE_COMMENT;
461
139
  role_table[ATK_ROLE_LIST_BOX] = ATSPI_ROLE_LIST_BOX;
462
139
  role_table[ATK_ROLE_GROUPING] = ATSPI_ROLE_GROUPING;
463
139
  role_table[ATK_ROLE_IMAGE_MAP] = ATSPI_ROLE_IMAGE_MAP;
464
139
  role_table[ATK_ROLE_NOTIFICATION] = ATSPI_ROLE_NOTIFICATION;
465
139
  role_table[ATK_ROLE_INFO_BAR] = ATSPI_ROLE_INFO_BAR;
466
139
  role_table[ATK_ROLE_LEVEL_BAR] = ATSPI_ROLE_LEVEL_BAR;
467
139
  role_table[ATK_ROLE_TITLE_BAR] = ATSPI_ROLE_TITLE_BAR;
468
139
  role_table[ATK_ROLE_BLOCK_QUOTE] = ATSPI_ROLE_BLOCK_QUOTE;
469
139
  role_table[ATK_ROLE_AUDIO] = ATSPI_ROLE_AUDIO;
470
139
  role_table[ATK_ROLE_VIDEO] = ATSPI_ROLE_VIDEO;
471
139
  role_table[ATK_ROLE_DEFINITION] = ATSPI_ROLE_DEFINITION;
472
139
  role_table[ATK_ROLE_ARTICLE] = ATSPI_ROLE_ARTICLE;
473
139
  role_table[ATK_ROLE_LANDMARK] = ATSPI_ROLE_LANDMARK;
474
139
  role_table[ATK_ROLE_LOG] = ATSPI_ROLE_LOG;
475
139
  role_table[ATK_ROLE_MARQUEE] = ATSPI_ROLE_MARQUEE;
476
139
  role_table[ATK_ROLE_MATH] = ATSPI_ROLE_MATH;
477
139
  role_table[ATK_ROLE_RATING] = ATSPI_ROLE_RATING;
478
139
  role_table[ATK_ROLE_TIMER] = ATSPI_ROLE_TIMER;
479
139
  role_table[ATK_ROLE_STATIC] = ATSPI_ROLE_STATIC;
480
139
  role_table[ATK_ROLE_MATH_FRACTION] = ATSPI_ROLE_MATH_FRACTION;
481
139
  role_table[ATK_ROLE_MATH_ROOT] = ATSPI_ROLE_MATH_ROOT;
482
139
  role_table[ATK_ROLE_SUBSCRIPT] = ATSPI_ROLE_SUBSCRIPT;
483
139
  role_table[ATK_ROLE_SUPERSCRIPT] = ATSPI_ROLE_SUPERSCRIPT;
484
139
  role_table[ATK_ROLE_DESCRIPTION_LIST] = ATSPI_ROLE_DESCRIPTION_LIST;
485
139
  role_table[ATK_ROLE_DESCRIPTION_TERM] = ATSPI_ROLE_DESCRIPTION_TERM;
486
139
  role_table[ATK_ROLE_DESCRIPTION_VALUE] = ATSPI_ROLE_DESCRIPTION_VALUE;
487
139
  role_table[ATK_ROLE_FOOTNOTE] = ATSPI_ROLE_FOOTNOTE;
488
139
  role_table[ATK_ROLE_CONTENT_DELETION] = ATSPI_ROLE_CONTENT_DELETION;
489
139
  role_table[ATK_ROLE_CONTENT_INSERTION] = ATSPI_ROLE_CONTENT_INSERTION;
490
139
  role_table[ATK_ROLE_MARK] = ATSPI_ROLE_MARK;
491
139
  role_table[ATK_ROLE_SUGGESTION] = ATSPI_ROLE_SUGGESTION;
492
139
  role_table[ATK_ROLE_PUSH_BUTTON_MENU] = ATSPI_ROLE_PUSH_BUTTON_MENU;
493

            
494
139
  return TRUE;
495
}
496

            
497
AtspiRole
498
1433
spi_accessible_role_from_atk_role (AtkRole role)
499
{
500
  static gboolean is_initialized = FALSE;
501
  static AtspiRole spi_role_table[ATK_ROLE_LAST_DEFINED];
502
  AtspiRole spi_role;
503

            
504
1433
  if (!is_initialized)
505
    {
506
139
      is_initialized = init_role_lookup_table (spi_role_table);
507
    }
508

            
509
1433
  if (role >= 0 && role < ATK_ROLE_LAST_DEFINED)
510
    {
511
1433
      spi_role = spi_role_table[role];
512
    }
513
  else
514
    {
515
      spi_role = ATSPI_ROLE_EXTENDED;
516
    }
517
1433
  return spi_role;
518
}
519

            
520
/*END------------------------------------------------------------------------*/