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 2001, 2002 Sun Microsystems Inc.,
7
 * Copyright 2001, 2002 Ximian, Inc.
8
 *
9
 * This library is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU Lesser General Public
11
 * License as published by the Free Software Foundation; either
12
 * version 2.1 of the License, or (at your option) any later version.
13
 *
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
 * Lesser General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Lesser General Public
20
 * License along with this library; if not, write to the
21
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22
 * Boston, MA 02110-1301, USA.
23
 */
24

            
25
#include "bridge.h"
26
#include <atk/atk.h>
27
#include <droute/droute.h>
28

            
29
#include "accessible-stateset.h"
30
#include "atspi/atspi.h"
31
#include "introspection.h"
32
#include "object.h"
33
#include "spi-dbus.h"
34
#include <string.h>
35

            
36
static dbus_bool_t
37
164
impl_get_Name (DBusMessageIter *iter, void *user_data)
38
{
39
164
  AtkObject *object = (AtkObject *) user_data;
40

            
41
164
  g_return_val_if_fail (ATK_IS_OBJECT (user_data), FALSE);
42

            
43
164
  return droute_return_v_string (iter, atk_object_get_name (object));
44
}
45

            
46
static dbus_bool_t
47
1
impl_get_Description (DBusMessageIter *iter, void *user_data)
48
{
49
1
  AtkObject *object = (AtkObject *) user_data;
50

            
51
1
  g_return_val_if_fail (ATK_IS_OBJECT (user_data), FALSE);
52

            
53
1
  return droute_return_v_string (iter, atk_object_get_description (object));
54
}
55

            
56
static dbus_bool_t
57
1
impl_get_Locale (DBusMessageIter *iter, void *user_data)
58
{
59
1
  AtkObject *object = (AtkObject *) user_data;
60

            
61
1
  g_return_val_if_fail (ATK_IS_OBJECT (user_data), FALSE);
62

            
63
1
  return droute_return_v_string (iter, atk_object_get_object_locale (object));
64
}
65

            
66
static dbus_bool_t
67
2
impl_get_Parent (DBusMessageIter *iter, void *user_data)
68
{
69
2
  AtkObject *obj = (AtkObject *) user_data;
70
  AtkObject *parent;
71
  DBusMessageIter iter_variant;
72
  dbus_uint32_t role;
73

            
74
2
  g_return_val_if_fail (ATK_IS_OBJECT (user_data), FALSE);
75

            
76
2
  role = spi_accessible_role_from_atk_role (atk_object_get_role (obj));
77

            
78
2
  dbus_message_iter_open_container (iter, DBUS_TYPE_VARIANT, "(so)",
79
                                    &iter_variant);
80

            
81
2
  parent = atk_object_get_parent (obj);
82
2
  if (parent == NULL)
83
    {
84
      /* TODO, move in to a 'Plug' wrapper. */
85
1
      if (ATK_IS_PLUG (obj))
86
        {
87
          char *id = g_object_get_data (G_OBJECT (obj), "dbus-plug-parent");
88
          char *bus_parent;
89
          char *path_parent;
90

            
91
          if (id)
92
            {
93
              bus_parent = g_strdup (id);
94
              if (bus_parent && (path_parent = g_utf8_strchr (bus_parent + 1, -1, ':')))
95
                {
96
                  DBusMessageIter iter_parent;
97
                  *(path_parent++) = '\0';
98
                  dbus_message_iter_open_container (&iter_variant, DBUS_TYPE_STRUCT, NULL,
99
                                                    &iter_parent);
100
                  dbus_message_iter_append_basic (&iter_parent, DBUS_TYPE_STRING, &bus_parent);
101
                  dbus_message_iter_append_basic (&iter_parent, DBUS_TYPE_OBJECT_PATH, &path_parent);
102
                  dbus_message_iter_close_container (&iter_variant, &iter_parent);
103
                }
104
              else
105
                {
106
                  spi_object_append_null_reference (&iter_variant);
107
                }
108
            }
109
          else
110
            {
111
              spi_object_append_null_reference (&iter_variant);
112
            }
113
        }
114
1
      else if (role != ATSPI_ROLE_APPLICATION)
115
1
        spi_object_append_null_reference (&iter_variant);
116
      else
117
        spi_object_append_desktop_reference (&iter_variant);
118
    }
119
  else
120
    {
121
1
      spi_object_append_reference (&iter_variant, parent);
122
    }
123

            
124
2
  dbus_message_iter_close_container (iter, &iter_variant);
125
2
  return TRUE;
126
}
127

            
128
static dbus_bool_t
129
1
impl_get_ChildCount (DBusMessageIter *iter, void *user_data)
130
{
131
1
  AtkObject *object = (AtkObject *) user_data;
132
  int childCount;
133

            
134
1
  g_return_val_if_fail (ATK_IS_OBJECT (user_data), FALSE);
135

            
136
1
  childCount = (ATK_IS_SOCKET (object) && atk_socket_is_occupied (ATK_SOCKET (object)))
137
                   ? 1
138
1
                   : atk_object_get_n_accessible_children (object);
139
1
  return droute_return_v_int32 (iter, childCount);
140
}
141

            
142
static DBusMessage *
143
138
impl_GetChildAtIndex (DBusConnection *bus,
144
                      DBusMessage *message,
145
                      void *user_data)
146
{
147
138
  AtkObject *object = (AtkObject *) user_data;
148
  DBusMessage *reply;
149
  dbus_int32_t i;
150
  AtkObject *child;
151

            
152
138
  g_return_val_if_fail (ATK_IS_OBJECT (user_data),
153
                        droute_not_yet_handled_error (message));
154
138
  if (!dbus_message_get_args (message, NULL, DBUS_TYPE_INT32, &i, DBUS_TYPE_INVALID))
155
    {
156
      return droute_invalid_arguments_error (message);
157
    }
158

            
159
138
  if (ATK_IS_SOCKET (object) && atk_socket_is_occupied (ATK_SOCKET (object)) && i == 0)
160
    {
161
      AtkSocket *socket = ATK_SOCKET (object);
162
      gchar *child_name, *child_path;
163
      child_name = g_strdup (socket->embedded_plug_id);
164
      child_path = g_utf8_strchr (child_name + 1, -1, ':');
165
      if (child_path)
166
        {
167
          DBusMessageIter iter, iter_socket;
168
          *(child_path++) = '\0';
169
          reply = dbus_message_new_method_return (message);
170
          if (!reply)
171
            return NULL;
172
          dbus_message_iter_init_append (reply, &iter);
173
          dbus_message_iter_open_container (&iter, DBUS_TYPE_STRUCT, NULL,
174
                                            &iter_socket);
175
          dbus_message_iter_append_basic (&iter_socket, DBUS_TYPE_STRING, &child_name);
176
          dbus_message_iter_append_basic (&iter_socket, DBUS_TYPE_OBJECT_PATH, &child_path);
177
          g_free (child_name);
178
          dbus_message_iter_close_container (&iter, &iter_socket);
179
          return reply;
180
        }
181
      g_free (child_name);
182
    }
183
138
  child = atk_object_ref_accessible_child (object, i);
184
138
  reply = spi_object_return_reference (message, child);
185
138
  if (child)
186
138
    g_object_unref (child);
187

            
188
138
  return reply;
189
}
190

            
191
static DBusMessage *
192
impl_GetChildren (DBusConnection *bus,
193
                  DBusMessage *message,
194
                  void *user_data)
195
{
196
  AtkObject *object = (AtkObject *) user_data;
197
  gint i;
198
  gint count;
199
  DBusMessage *reply;
200
  DBusMessageIter iter, iter_array;
201

            
202
  g_return_val_if_fail (ATK_IS_OBJECT (user_data),
203
                        droute_not_yet_handled_error (message));
204
  count = atk_object_get_n_accessible_children (object);
205
  reply = dbus_message_new_method_return (message);
206
  if (!reply)
207
    goto oom;
208
  dbus_message_iter_init_append (reply, &iter);
209
  if (!dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "(so)", &iter_array))
210
    goto oom;
211

            
212
  if (ATK_IS_SOCKET (object) && atk_socket_is_occupied (ATK_SOCKET (object)))
213
    {
214
      AtkSocket *socket = ATK_SOCKET (object);
215
      gchar *child_name, *child_path;
216
      child_name = g_strdup (socket->embedded_plug_id);
217
      child_path = g_utf8_strchr (child_name + 1, -1, ':');
218
      if (child_path)
219
        {
220
          DBusMessageIter iter_struct;
221
          *(child_path++) = '\0';
222
          dbus_message_iter_open_container (&iter_array, DBUS_TYPE_STRUCT, NULL,
223
                                            &iter_struct);
224
          dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING,
225
                                          &child_name);
226
          dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_OBJECT_PATH,
227
                                          &child_path);
228
          dbus_message_iter_close_container (&iter_array, &iter_struct);
229
          g_free (child_name);
230
          if (!dbus_message_iter_close_container (&iter, &iter_array))
231
            goto oom;
232
          return reply;
233
        }
234
      g_free (child_name);
235
    }
236

            
237
  for (i = 0; i < count; i++)
238
    {
239
      AtkObject *child = atk_object_ref_accessible_child (object, i);
240
      spi_object_append_reference (&iter_array, child);
241
      if (child)
242
        g_object_unref (child);
243
    }
244
  if (!dbus_message_iter_close_container (&iter, &iter_array))
245
    goto oom;
246
  return reply;
247
oom:
248
  // TODO: handle out-of-memory
249
  return reply;
250
}
251

            
252
static DBusMessage *
253
1
impl_GetIndexInParent (DBusConnection *bus,
254
                       DBusMessage *message,
255
                       void *user_data)
256
{
257
1
  AtkObject *object = (AtkObject *) user_data;
258
  dbus_int32_t rv;
259
  DBusMessage *reply;
260

            
261
1
  g_return_val_if_fail (ATK_IS_OBJECT (user_data),
262
                        droute_not_yet_handled_error (message));
263

            
264
1
  rv = atk_object_get_index_in_parent (object);
265
1
  reply = dbus_message_new_method_return (message);
266
1
  dbus_message_append_args (reply, DBUS_TYPE_INT32, &rv, DBUS_TYPE_INVALID);
267
1
  return reply;
268
}
269

            
270
static gboolean
271
2
spi_init_relation_type_table (AtspiRelationType *types)
272
{
273
  gint i;
274

            
275
44
  for (i = 0; i < ATK_RELATION_LAST_DEFINED; i++)
276
42
    types[i] = ATSPI_RELATION_NULL;
277

            
278
2
  types[ATK_RELATION_CONTROLLED_BY] = ATSPI_RELATION_CONTROLLED_BY;
279
2
  types[ATK_RELATION_CONTROLLER_FOR] = ATSPI_RELATION_CONTROLLER_FOR;
280
2
  types[ATK_RELATION_LABEL_FOR] = ATSPI_RELATION_LABEL_FOR;
281
2
  types[ATK_RELATION_LABELLED_BY] = ATSPI_RELATION_LABELLED_BY;
282
2
  types[ATK_RELATION_MEMBER_OF] = ATSPI_RELATION_MEMBER_OF;
283
2
  types[ATK_RELATION_NODE_CHILD_OF] = ATSPI_RELATION_NODE_CHILD_OF;
284
2
  types[ATK_RELATION_FLOWS_TO] = ATSPI_RELATION_FLOWS_TO;
285
2
  types[ATK_RELATION_FLOWS_FROM] = ATSPI_RELATION_FLOWS_FROM;
286
2
  types[ATK_RELATION_SUBWINDOW_OF] = ATSPI_RELATION_SUBWINDOW_OF;
287
2
  types[ATK_RELATION_EMBEDS] = ATSPI_RELATION_EMBEDS;
288
2
  types[ATK_RELATION_EMBEDDED_BY] = ATSPI_RELATION_EMBEDDED_BY;
289
2
  types[ATK_RELATION_POPUP_FOR] = ATSPI_RELATION_POPUP_FOR;
290
2
  types[ATK_RELATION_PARENT_WINDOW_OF] =
291
      ATSPI_RELATION_PARENT_WINDOW_OF;
292
2
  types[ATK_RELATION_DESCRIPTION_FOR] =
293
      ATSPI_RELATION_DESCRIPTION_FOR;
294
2
  types[ATK_RELATION_DESCRIBED_BY] = ATSPI_RELATION_DESCRIBED_BY;
295
2
  types[ATK_RELATION_DETAILS] = ATSPI_RELATION_DETAILS;
296
2
  types[ATK_RELATION_DETAILS_FOR] = ATSPI_RELATION_DETAILS_FOR;
297
2
  types[ATK_RELATION_ERROR_MESSAGE] = ATSPI_RELATION_ERROR_MESSAGE;
298
2
  types[ATK_RELATION_ERROR_FOR] = ATSPI_RELATION_ERROR_FOR;
299
2
  types[ATK_RELATION_NODE_PARENT_OF] = ATSPI_RELATION_NODE_PARENT_OF;
300

            
301
2
  return TRUE;
302
}
303

            
304
static AtspiRelationType
305
2
spi_relation_type_from_atk_relation_type (AtkRelationType type)
306
{
307
  static gboolean is_initialized = FALSE;
308
  static AtspiRelationType
309
      spi_relation_type_table[ATK_RELATION_LAST_DEFINED];
310
  AtspiRelationType spi_type;
311

            
312
2
  if (!is_initialized)
313
2
    is_initialized = spi_init_relation_type_table (spi_relation_type_table);
314

            
315
2
  if (type > ATK_RELATION_NULL && type < ATK_RELATION_LAST_DEFINED)
316
2
    spi_type = spi_relation_type_table[type];
317
  else
318
    spi_type = ATSPI_RELATION_EXTENDED;
319
2
  return spi_type;
320
}
321

            
322
static DBusMessage *
323
2
impl_GetRelationSet (DBusConnection *bus,
324
                     DBusMessage *message,
325
                     void *user_data)
326
{
327
2
  AtkObject *object = (AtkObject *) user_data;
328
  DBusMessage *reply;
329
  AtkRelationSet *set;
330
  DBusMessageIter iter, iter_array, iter_struct, iter_targets;
331
  gint count;
332
  gint i, j;
333

            
334
2
  g_return_val_if_fail (ATK_IS_OBJECT (user_data),
335
                        droute_not_yet_handled_error (message));
336
2
  reply = dbus_message_new_method_return (message);
337
2
  if (!reply)
338
    return NULL;
339
2
  set = atk_object_ref_relation_set (object);
340
2
  dbus_message_iter_init_append (reply, &iter);
341
2
  if (!dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "(ua(so))", &iter_array))
342
    {
343
      goto oom;
344
    }
345
2
  count = 0;
346
2
  if (set)
347
2
    count = atk_relation_set_get_n_relations (set);
348
4
  for (i = 0; i < count; i++)
349
    {
350
2
      AtkRelation *r = atk_relation_set_get_relation (set, i);
351
      AtkRelationType rt;
352
      GPtrArray *target;
353
      dbus_uint32_t type;
354
2
      if (!r)
355
        continue;
356
2
      rt = atk_relation_get_relation_type (r);
357
2
      type = spi_relation_type_from_atk_relation_type (rt);
358
2
      target = atk_relation_get_target (r);
359
2
      if (!dbus_message_iter_open_container (&iter_array, DBUS_TYPE_STRUCT, NULL, &iter_struct))
360
        {
361
          goto oom;
362
        }
363
2
      dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_UINT32, &type);
364
2
      if (!dbus_message_iter_open_container (&iter_struct, DBUS_TYPE_ARRAY, "(so)", &iter_targets))
365
        {
366
          goto oom;
367
        }
368
4
      for (j = 0; j < target->len; j++)
369
        {
370
2
          AtkObject *obj = target->pdata[j];
371
2
          if (!obj)
372
            continue;
373
2
          spi_object_append_reference (&iter_targets, obj);
374
        }
375
2
      dbus_message_iter_close_container (&iter_struct, &iter_targets);
376
2
      dbus_message_iter_close_container (&iter_array, &iter_struct);
377
    }
378
2
  dbus_message_iter_close_container (&iter, &iter_array);
379
2
oom:
380
2
  if (set)
381
2
    g_object_unref (set);
382
  // TODO: handle out of memory */
383
2
  return reply;
384
}
385

            
386
static DBusMessage *
387
5
impl_GetRole (DBusConnection *bus, DBusMessage *message, void *user_data)
388
{
389
5
  AtkObject *object = (AtkObject *) user_data;
390
  gint role;
391
  dbus_uint32_t rv;
392
  DBusMessage *reply;
393

            
394
5
  g_return_val_if_fail (ATK_IS_OBJECT (user_data),
395
                        droute_not_yet_handled_error (message));
396
5
  role = atk_object_get_role (object);
397
5
  rv = spi_accessible_role_from_atk_role (role);
398
5
  reply = dbus_message_new_method_return (message);
399
5
  if (reply)
400
    {
401
5
      dbus_message_append_args (reply, DBUS_TYPE_UINT32, &rv,
402
                                DBUS_TYPE_INVALID);
403
    }
404
5
  return reply;
405
}
406

            
407
static DBusMessage *
408
impl_GetRoleName (DBusConnection *bus,
409
                  DBusMessage *message,
410
                  void *user_data)
411
{
412
  AtkObject *object = (AtkObject *) user_data;
413
  gint role;
414
  const char *role_name;
415
  DBusMessage *reply;
416

            
417
  g_return_val_if_fail (ATK_IS_OBJECT (user_data),
418
                        droute_not_yet_handled_error (message));
419
  role = atk_object_get_role (object);
420
  role_name = atk_role_get_name (role);
421
  if (!role_name)
422
    role_name = "";
423
  reply = dbus_message_new_method_return (message);
424
  if (reply)
425
    {
426
      dbus_message_append_args (reply, DBUS_TYPE_STRING, &role_name,
427
                                DBUS_TYPE_INVALID);
428
    }
429
  return reply;
430
}
431

            
432
static DBusMessage *
433
impl_GetLocalizedRoleName (DBusConnection *bus,
434
                           DBusMessage *message,
435
                           void *user_data)
436
{
437
  AtkObject *object = (AtkObject *) user_data;
438
  gint role;
439
  const char *role_name;
440
  DBusMessage *reply;
441

            
442
  g_return_val_if_fail (ATK_IS_OBJECT (user_data),
443
                        droute_not_yet_handled_error (message));
444
  role = atk_object_get_role (object);
445
  role_name = atk_role_get_localized_name (role);
446
  if (!role_name)
447
    role_name = "";
448
  reply = dbus_message_new_method_return (message);
449
  if (reply)
450
    {
451
      dbus_message_append_args (reply, DBUS_TYPE_STRING, &role_name,
452
                                DBUS_TYPE_INVALID);
453
    }
454
  return reply;
455
}
456

            
457
static DBusMessage *
458
12
impl_GetState (DBusConnection *bus, DBusMessage *message, void *user_data)
459
{
460
12
  AtkObject *object = (AtkObject *) user_data;
461

            
462
12
  DBusMessage *reply = NULL;
463
  DBusMessageIter iter, iter_array;
464

            
465
  dbus_uint32_t states[2];
466

            
467
  guint count;
468

            
469
12
  g_return_val_if_fail (ATK_IS_OBJECT (user_data),
470
                        droute_not_yet_handled_error (message));
471

            
472
12
  reply = dbus_message_new_method_return (message);
473
12
  dbus_message_iter_init_append (reply, &iter);
474

            
475
12
  spi_atk_state_to_dbus_array (object, states);
476
12
  dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "u", &iter_array);
477
36
  for (count = 0; count < 2; count++)
478
    {
479
24
      dbus_message_iter_append_basic (&iter_array, DBUS_TYPE_UINT32,
480
24
                                      &states[count]);
481
    }
482
12
  dbus_message_iter_close_container (&iter, &iter_array);
483
12
  return reply;
484
}
485

            
486
static DBusMessage *
487
2
impl_GetAttributes (DBusConnection *bus,
488
                    DBusMessage *message,
489
                    void *user_data)
490
{
491
2
  AtkObject *object = (AtkObject *) user_data;
492
  AtkAttributeSet *attributes;
493
2
  DBusMessage *reply = NULL;
494
  DBusMessageIter iter;
495

            
496
2
  g_return_val_if_fail (ATK_IS_OBJECT (user_data),
497
                        droute_not_yet_handled_error (message));
498

            
499
2
  attributes = atk_object_get_attributes (object);
500

            
501
2
  reply = dbus_message_new_method_return (message);
502
2
  dbus_message_iter_init_append (reply, &iter);
503
2
  spi_object_append_attribute_set (&iter, attributes);
504

            
505
2
  atk_attribute_set_free (attributes);
506

            
507
2
  return reply;
508
}
509

            
510
static dbus_bool_t
511
impl_get_Attributes (DBusMessageIter *iter, void *user_data)
512
{
513
  DBusMessageIter iter_variant;
514
  AtkObject *object = (AtkObject *) user_data;
515
  AtkAttributeSet *attributes;
516

            
517
  g_return_val_if_fail (ATK_IS_OBJECT (user_data), FALSE);
518

            
519
  attributes = atk_object_get_attributes (object);
520

            
521
  dbus_message_iter_open_container (iter, DBUS_TYPE_VARIANT, "a{ss}", &iter_variant);
522
  spi_object_append_attribute_set (&iter_variant, attributes);
523
  dbus_message_iter_close_container (iter, &iter_variant);
524

            
525
  atk_attribute_set_free (attributes);
526

            
527
  return TRUE;
528
}
529

            
530
static DBusMessage *
531
impl_GetApplication (DBusConnection *bus,
532
                     DBusMessage *message,
533
                     void *user_data)
534
{
535
  return spi_object_return_reference (message, atk_get_root ());
536
}
537

            
538
static DBusMessage *
539
122
impl_GetInterfaces (DBusConnection *bus,
540
                    DBusMessage *message,
541
                    void *user_data)
542
{
543
122
  AtkObject *object = (AtkObject *) user_data;
544
  DBusMessage *reply;
545
  DBusMessageIter iter, iter_array;
546

            
547
122
  g_return_val_if_fail (ATK_IS_OBJECT (user_data),
548
                        droute_not_yet_handled_error (message));
549
122
  reply = dbus_message_new_method_return (message);
550
122
  if (reply)
551
    {
552
122
      dbus_message_iter_init_append (reply, &iter);
553
122
      dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "s",
554
                                        &iter_array);
555
122
      spi_object_append_interfaces (&iter_array, object);
556
122
      dbus_message_iter_close_container (&iter, &iter_array);
557
    }
558
122
  return reply;
559
}
560

            
561
static dbus_bool_t
562
impl_get_AccessibleId (DBusMessageIter *iter, void *user_data)
563
{
564
  AtkObject *object = (AtkObject *) user_data;
565

            
566
  g_return_val_if_fail (ATK_IS_OBJECT (user_data), FALSE);
567

            
568
  return droute_return_v_string (iter, atk_object_get_accessible_id (object));
569
}
570

            
571
static dbus_bool_t
572
1
impl_get_HelpText (DBusMessageIter *iter, void *user_data)
573
{
574
1
  AtkObject *object = (AtkObject *) user_data;
575

            
576
1
  g_return_val_if_fail (ATK_IS_OBJECT (user_data), FALSE);
577

            
578
1
  return droute_return_v_string (iter, atk_object_get_help_text (object));
579
}
580

            
581
static DRouteMethod methods[] = {
582
  { impl_GetChildAtIndex, "GetChildAtIndex" },
583
  { impl_GetChildren, "GetChildren" },
584
  { impl_GetIndexInParent, "GetIndexInParent" },
585
  { impl_GetRelationSet, "GetRelationSet" },
586
  { impl_GetRole, "GetRole" },
587
  { impl_GetRoleName, "GetRoleName" },
588
  { impl_GetLocalizedRoleName, "GetLocalizedRoleName" },
589
  { impl_GetState, "GetState" },
590
  { impl_GetAttributes, "GetAttributes" },
591
  { impl_GetApplication, "GetApplication" },
592
  { impl_GetInterfaces, "GetInterfaces" },
593
  { NULL, NULL }
594
};
595

            
596
static DRouteProperty properties[] = {
597
  { impl_get_Name, NULL, "Name" },
598
  { impl_get_Description, NULL, "Description" },
599
  { impl_get_Locale, NULL, "Locale" },
600
  { impl_get_Parent, NULL, "Parent" },
601
  { impl_get_ChildCount, NULL, "ChildCount" },
602
  { impl_get_Attributes, NULL, "Attributes" },
603
  { impl_get_AccessibleId, NULL, "AccessibleId" },
604
  { impl_get_HelpText, NULL, "HelpText" },
605
  { NULL, NULL, NULL }
606
};
607

            
608
void
609
161
spi_initialize_accessible (DRoutePath *path)
610
{
611
161
  spi_atk_add_interface (path,
612
                         ATSPI_DBUS_INTERFACE_ACCESSIBLE,
613
                         spi_org_a11y_atspi_Accessible,
614
                         methods, properties);
615
161
};