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
impl_get_Version (DBusMessageIter *iter, void *user_data)
38
{
39
  return droute_return_v_uint32 (iter, SPI_DBUS_ACCESSIBLE_VERSION);
40
}
41

            
42
static dbus_bool_t
43
164
impl_get_Name (DBusMessageIter *iter, void *user_data)
44
{
45
164
  AtkObject *object = (AtkObject *) user_data;
46

            
47
164
  g_return_val_if_fail (ATK_IS_OBJECT (user_data), FALSE);
48

            
49
164
  return droute_return_v_string (iter, atk_object_get_name (object));
50
}
51

            
52
static dbus_bool_t
53
1
impl_get_Description (DBusMessageIter *iter, void *user_data)
54
{
55
1
  AtkObject *object = (AtkObject *) user_data;
56

            
57
1
  g_return_val_if_fail (ATK_IS_OBJECT (user_data), FALSE);
58

            
59
1
  return droute_return_v_string (iter, atk_object_get_description (object));
60
}
61

            
62
static dbus_bool_t
63
1
impl_get_Locale (DBusMessageIter *iter, void *user_data)
64
{
65
1
  AtkObject *object = (AtkObject *) user_data;
66

            
67
1
  g_return_val_if_fail (ATK_IS_OBJECT (user_data), FALSE);
68

            
69
1
  return droute_return_v_string (iter, atk_object_get_object_locale (object));
70
}
71

            
72
static dbus_bool_t
73
2
impl_get_Parent (DBusMessageIter *iter, void *user_data)
74
{
75
2
  AtkObject *obj = (AtkObject *) user_data;
76
  AtkObject *parent;
77
  DBusMessageIter iter_variant;
78
  dbus_uint32_t role;
79

            
80
2
  g_return_val_if_fail (ATK_IS_OBJECT (user_data), FALSE);
81

            
82
2
  role = spi_accessible_role_from_atk_role (atk_object_get_role (obj));
83

            
84
2
  dbus_message_iter_open_container (iter, DBUS_TYPE_VARIANT, "(so)",
85
                                    &iter_variant);
86

            
87
2
  parent = atk_object_get_parent (obj);
88
2
  if (parent == NULL)
89
    {
90
      /* TODO, move in to a 'Plug' wrapper. */
91
1
      if (ATK_IS_PLUG (obj))
92
        {
93
          char *id = g_object_get_data (G_OBJECT (obj), "dbus-plug-parent");
94
          char *bus_parent;
95
          char *path_parent;
96

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

            
130
2
  dbus_message_iter_close_container (iter, &iter_variant);
131
2
  return TRUE;
132
}
133

            
134
static dbus_bool_t
135
1
impl_get_ChildCount (DBusMessageIter *iter, void *user_data)
136
{
137
1
  AtkObject *object = (AtkObject *) user_data;
138
  int childCount;
139

            
140
1
  g_return_val_if_fail (ATK_IS_OBJECT (user_data), FALSE);
141

            
142
2
  childCount = (ATK_IS_SOCKET (object) && atk_socket_is_occupied (ATK_SOCKET (object)))
143
                   ? 1
144
1
                   : atk_object_get_n_accessible_children (object);
145
1
  return droute_return_v_int32 (iter, childCount);
146
}
147

            
148
static DBusMessage *
149
138
impl_GetChildAtIndex (DBusConnection *bus,
150
                      DBusMessage *message,
151
                      void *user_data)
152
{
153
138
  AtkObject *object = (AtkObject *) user_data;
154
  DBusMessage *reply;
155
  dbus_int32_t i;
156
  AtkObject *child;
157

            
158
138
  g_return_val_if_fail (ATK_IS_OBJECT (user_data),
159
                        droute_not_yet_handled_error (message));
160
138
  if (!dbus_message_get_args (message, NULL, DBUS_TYPE_INT32, &i, DBUS_TYPE_INVALID))
161
    {
162
      return droute_invalid_arguments_error (message);
163
    }
164

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

            
194
138
  return reply;
195
}
196

            
197
static DBusMessage *
198
impl_GetChildren (DBusConnection *bus,
199
                  DBusMessage *message,
200
                  void *user_data)
201
{
202
  AtkObject *object = (AtkObject *) user_data;
203
  gint i;
204
  gint count;
205
  DBusMessage *reply;
206
  DBusMessageIter iter, iter_array;
207

            
208
  g_return_val_if_fail (ATK_IS_OBJECT (user_data),
209
                        droute_not_yet_handled_error (message));
210
  count = atk_object_get_n_accessible_children (object);
211

            
212
  if (count > ATSPI_MAX_CHILDREN)
213
    {
214
      gchar *errmsg = g_strdup_printf (
215
          "Accessible's child count %d exceeds the maximum of %d handled by GetChildren.", count, ATSPI_MAX_CHILDREN);
216
      reply = dbus_message_new_error (message, DBUS_ERROR_INVALID_ARGS, errmsg);
217
      g_free (errmsg);
218
      return reply;
219
    }
220

            
221
  reply = dbus_message_new_method_return (message);
222
  if (!reply)
223
    goto oom;
224
  dbus_message_iter_init_append (reply, &iter);
225
  if (!dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "(so)", &iter_array))
226
    goto oom;
227

            
228
  if (ATK_IS_SOCKET (object) && atk_socket_is_occupied (ATK_SOCKET (object)))
229
    {
230
      AtkSocket *socket = ATK_SOCKET (object);
231
      gchar *child_name, *child_path;
232
      child_name = g_strdup (socket->embedded_plug_id);
233
      child_path = g_utf8_strchr (child_name + 1, -1, ':');
234
      if (child_path)
235
        {
236
          DBusMessageIter iter_struct;
237
          *(child_path++) = '\0';
238
          dbus_message_iter_open_container (&iter_array, DBUS_TYPE_STRUCT, NULL,
239
                                            &iter_struct);
240
          dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING,
241
                                          &child_name);
242
          dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_OBJECT_PATH,
243
                                          &child_path);
244
          dbus_message_iter_close_container (&iter_array, &iter_struct);
245
          g_free (child_name);
246
          if (!dbus_message_iter_close_container (&iter, &iter_array))
247
            goto oom;
248
          return reply;
249
        }
250
      g_free (child_name);
251
    }
252

            
253
  for (i = 0; i < count; i++)
254
    {
255
      AtkObject *child = atk_object_ref_accessible_child (object, i);
256
      spi_object_append_reference (&iter_array, child);
257
      if (child)
258
        g_object_unref (child);
259
    }
260
  if (!dbus_message_iter_close_container (&iter, &iter_array))
261
    goto oom;
262
  return reply;
263
oom:
264
  // TODO: handle out-of-memory
265
  return reply;
266
}
267

            
268
static DBusMessage *
269
1
impl_GetIndexInParent (DBusConnection *bus,
270
                       DBusMessage *message,
271
                       void *user_data)
272
{
273
1
  AtkObject *object = (AtkObject *) user_data;
274
  dbus_int32_t rv;
275
  DBusMessage *reply;
276

            
277
1
  g_return_val_if_fail (ATK_IS_OBJECT (user_data),
278
                        droute_not_yet_handled_error (message));
279

            
280
1
  rv = atk_object_get_index_in_parent (object);
281
1
  reply = dbus_message_new_method_return (message);
282
1
  dbus_message_append_args (reply, DBUS_TYPE_INT32, &rv, DBUS_TYPE_INVALID);
283
1
  return reply;
284
}
285

            
286
static gboolean
287
2
spi_init_relation_type_table (AtspiRelationType *types)
288
{
289
  gint i;
290

            
291
44
  for (i = 0; i < ATK_RELATION_LAST_DEFINED; i++)
292
42
    types[i] = ATSPI_RELATION_NULL;
293

            
294
2
  types[ATK_RELATION_CONTROLLED_BY] = ATSPI_RELATION_CONTROLLED_BY;
295
2
  types[ATK_RELATION_CONTROLLER_FOR] = ATSPI_RELATION_CONTROLLER_FOR;
296
2
  types[ATK_RELATION_LABEL_FOR] = ATSPI_RELATION_LABEL_FOR;
297
2
  types[ATK_RELATION_LABELLED_BY] = ATSPI_RELATION_LABELLED_BY;
298
2
  types[ATK_RELATION_MEMBER_OF] = ATSPI_RELATION_MEMBER_OF;
299
2
  types[ATK_RELATION_NODE_CHILD_OF] = ATSPI_RELATION_NODE_CHILD_OF;
300
2
  types[ATK_RELATION_FLOWS_TO] = ATSPI_RELATION_FLOWS_TO;
301
2
  types[ATK_RELATION_FLOWS_FROM] = ATSPI_RELATION_FLOWS_FROM;
302
2
  types[ATK_RELATION_SUBWINDOW_OF] = ATSPI_RELATION_SUBWINDOW_OF;
303
2
  types[ATK_RELATION_EMBEDS] = ATSPI_RELATION_EMBEDS;
304
2
  types[ATK_RELATION_EMBEDDED_BY] = ATSPI_RELATION_EMBEDDED_BY;
305
2
  types[ATK_RELATION_POPUP_FOR] = ATSPI_RELATION_POPUP_FOR;
306
2
  types[ATK_RELATION_PARENT_WINDOW_OF] =
307
      ATSPI_RELATION_PARENT_WINDOW_OF;
308
2
  types[ATK_RELATION_DESCRIPTION_FOR] =
309
      ATSPI_RELATION_DESCRIPTION_FOR;
310
2
  types[ATK_RELATION_DESCRIBED_BY] = ATSPI_RELATION_DESCRIBED_BY;
311
2
  types[ATK_RELATION_DETAILS] = ATSPI_RELATION_DETAILS;
312
2
  types[ATK_RELATION_DETAILS_FOR] = ATSPI_RELATION_DETAILS_FOR;
313
2
  types[ATK_RELATION_ERROR_MESSAGE] = ATSPI_RELATION_ERROR_MESSAGE;
314
2
  types[ATK_RELATION_ERROR_FOR] = ATSPI_RELATION_ERROR_FOR;
315
2
  types[ATK_RELATION_NODE_PARENT_OF] = ATSPI_RELATION_NODE_PARENT_OF;
316

            
317
2
  return TRUE;
318
}
319

            
320
static AtspiRelationType
321
2
spi_relation_type_from_atk_relation_type (AtkRelationType type)
322
{
323
  static gboolean is_initialized = FALSE;
324
  static AtspiRelationType
325
      spi_relation_type_table[ATK_RELATION_LAST_DEFINED];
326
  AtspiRelationType spi_type;
327

            
328
2
  if (!is_initialized)
329
2
    is_initialized = spi_init_relation_type_table (spi_relation_type_table);
330

            
331
2
  if (type > ATK_RELATION_NULL && type < ATK_RELATION_LAST_DEFINED)
332
2
    spi_type = spi_relation_type_table[type];
333
  else
334
    spi_type = ATSPI_RELATION_EXTENDED;
335
2
  return spi_type;
336
}
337

            
338
static DBusMessage *
339
2
impl_GetRelationSet (DBusConnection *bus,
340
                     DBusMessage *message,
341
                     void *user_data)
342
{
343
2
  AtkObject *object = (AtkObject *) user_data;
344
  DBusMessage *reply;
345
  AtkRelationSet *set;
346
  DBusMessageIter iter, iter_array, iter_struct, iter_targets;
347
  gint count;
348
  gint i, j;
349

            
350
2
  g_return_val_if_fail (ATK_IS_OBJECT (user_data),
351
                        droute_not_yet_handled_error (message));
352
2
  reply = dbus_message_new_method_return (message);
353
2
  if (!reply)
354
    return NULL;
355
2
  set = atk_object_ref_relation_set (object);
356
2
  dbus_message_iter_init_append (reply, &iter);
357
2
  if (!dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "(ua(so))", &iter_array))
358
    {
359
      goto oom;
360
    }
361
2
  count = 0;
362
2
  if (set)
363
2
    count = atk_relation_set_get_n_relations (set);
364
4
  for (i = 0; i < count; i++)
365
    {
366
2
      AtkRelation *r = atk_relation_set_get_relation (set, i);
367
      AtkRelationType rt;
368
      GPtrArray *target;
369
      dbus_uint32_t type;
370
2
      if (!r)
371
        continue;
372
2
      rt = atk_relation_get_relation_type (r);
373
2
      type = spi_relation_type_from_atk_relation_type (rt);
374
2
      target = atk_relation_get_target (r);
375
2
      if (!dbus_message_iter_open_container (&iter_array, DBUS_TYPE_STRUCT, NULL, &iter_struct))
376
        {
377
          goto oom;
378
        }
379
2
      dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_UINT32, &type);
380
2
      if (!dbus_message_iter_open_container (&iter_struct, DBUS_TYPE_ARRAY, "(so)", &iter_targets))
381
        {
382
          goto oom;
383
        }
384
4
      for (j = 0; j < target->len; j++)
385
        {
386
2
          AtkObject *obj = target->pdata[j];
387
2
          if (!obj)
388
            continue;
389
2
          spi_object_append_reference (&iter_targets, obj);
390
        }
391
2
      dbus_message_iter_close_container (&iter_struct, &iter_targets);
392
2
      dbus_message_iter_close_container (&iter_array, &iter_struct);
393
    }
394
2
  dbus_message_iter_close_container (&iter, &iter_array);
395
2
oom:
396
2
  if (set)
397
2
    g_object_unref (set);
398
  // TODO: handle out of memory */
399
2
  return reply;
400
}
401

            
402
static DBusMessage *
403
5
impl_GetRole (DBusConnection *bus, DBusMessage *message, void *user_data)
404
{
405
5
  AtkObject *object = (AtkObject *) user_data;
406
  gint role;
407
  dbus_uint32_t rv;
408
  DBusMessage *reply;
409

            
410
5
  g_return_val_if_fail (ATK_IS_OBJECT (user_data),
411
                        droute_not_yet_handled_error (message));
412
5
  role = atk_object_get_role (object);
413
5
  rv = spi_accessible_role_from_atk_role (role);
414
5
  reply = dbus_message_new_method_return (message);
415
5
  if (reply)
416
    {
417
5
      dbus_message_append_args (reply, DBUS_TYPE_UINT32, &rv,
418
                                DBUS_TYPE_INVALID);
419
    }
420
5
  return reply;
421
}
422

            
423
static DBusMessage *
424
impl_GetRoleName (DBusConnection *bus,
425
                  DBusMessage *message,
426
                  void *user_data)
427
{
428
  AtkObject *object = (AtkObject *) user_data;
429
  gint role;
430
  const char *role_name;
431
  DBusMessage *reply;
432

            
433
  g_return_val_if_fail (ATK_IS_OBJECT (user_data),
434
                        droute_not_yet_handled_error (message));
435
  role = atk_object_get_role (object);
436
  role_name = atk_role_get_name (role);
437
  if (!role_name)
438
    role_name = "";
439
  reply = dbus_message_new_method_return (message);
440
  if (reply)
441
    {
442
      dbus_message_append_args (reply, DBUS_TYPE_STRING, &role_name,
443
                                DBUS_TYPE_INVALID);
444
    }
445
  return reply;
446
}
447

            
448
static DBusMessage *
449
impl_GetLocalizedRoleName (DBusConnection *bus,
450
                           DBusMessage *message,
451
                           void *user_data)
452
{
453
  AtkObject *object = (AtkObject *) user_data;
454
  gint role;
455
  const char *role_name;
456
  DBusMessage *reply;
457

            
458
  g_return_val_if_fail (ATK_IS_OBJECT (user_data),
459
                        droute_not_yet_handled_error (message));
460
  role = atk_object_get_role (object);
461
  role_name = atk_role_get_localized_name (role);
462
  if (!role_name)
463
    role_name = "";
464
  reply = dbus_message_new_method_return (message);
465
  if (reply)
466
    {
467
      dbus_message_append_args (reply, DBUS_TYPE_STRING, &role_name,
468
                                DBUS_TYPE_INVALID);
469
    }
470
  return reply;
471
}
472

            
473
static DBusMessage *
474
12
impl_GetState (DBusConnection *bus, DBusMessage *message, void *user_data)
475
{
476
12
  AtkObject *object = (AtkObject *) user_data;
477

            
478
12
  DBusMessage *reply = NULL;
479
  DBusMessageIter iter, iter_array;
480

            
481
  dbus_uint32_t states[2];
482

            
483
  guint count;
484

            
485
12
  g_return_val_if_fail (ATK_IS_OBJECT (user_data),
486
                        droute_not_yet_handled_error (message));
487

            
488
12
  reply = dbus_message_new_method_return (message);
489
12
  dbus_message_iter_init_append (reply, &iter);
490

            
491
12
  spi_atk_state_to_dbus_array (object, states);
492
12
  dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "u", &iter_array);
493
36
  for (count = 0; count < 2; count++)
494
    {
495
24
      dbus_message_iter_append_basic (&iter_array, DBUS_TYPE_UINT32,
496
24
                                      &states[count]);
497
    }
498
12
  dbus_message_iter_close_container (&iter, &iter_array);
499
12
  return reply;
500
}
501

            
502
static DBusMessage *
503
2
impl_GetAttributes (DBusConnection *bus,
504
                    DBusMessage *message,
505
                    void *user_data)
506
{
507
2
  AtkObject *object = (AtkObject *) user_data;
508
  AtkAttributeSet *attributes;
509
2
  DBusMessage *reply = NULL;
510
  DBusMessageIter iter;
511

            
512
2
  g_return_val_if_fail (ATK_IS_OBJECT (user_data),
513
                        droute_not_yet_handled_error (message));
514

            
515
2
  attributes = atk_object_get_attributes (object);
516

            
517
2
  reply = dbus_message_new_method_return (message);
518
2
  dbus_message_iter_init_append (reply, &iter);
519
2
  spi_object_append_attribute_set (&iter, attributes);
520

            
521
2
  atk_attribute_set_free (attributes);
522

            
523
2
  return reply;
524
}
525

            
526
static dbus_bool_t
527
impl_get_Attributes (DBusMessageIter *iter, void *user_data)
528
{
529
  DBusMessageIter iter_variant;
530
  AtkObject *object = (AtkObject *) user_data;
531
  AtkAttributeSet *attributes;
532

            
533
  g_return_val_if_fail (ATK_IS_OBJECT (user_data), FALSE);
534

            
535
  attributes = atk_object_get_attributes (object);
536

            
537
  dbus_message_iter_open_container (iter, DBUS_TYPE_VARIANT, "a{ss}", &iter_variant);
538
  spi_object_append_attribute_set (&iter_variant, attributes);
539
  dbus_message_iter_close_container (iter, &iter_variant);
540

            
541
  atk_attribute_set_free (attributes);
542

            
543
  return TRUE;
544
}
545

            
546
static DBusMessage *
547
impl_GetApplication (DBusConnection *bus,
548
                     DBusMessage *message,
549
                     void *user_data)
550
{
551
  return spi_object_return_reference (message, atk_get_root ());
552
}
553

            
554
static DBusMessage *
555
122
impl_GetInterfaces (DBusConnection *bus,
556
                    DBusMessage *message,
557
                    void *user_data)
558
{
559
122
  AtkObject *object = (AtkObject *) user_data;
560
  DBusMessage *reply;
561
  DBusMessageIter iter, iter_array;
562

            
563
122
  g_return_val_if_fail (ATK_IS_OBJECT (user_data),
564
                        droute_not_yet_handled_error (message));
565
122
  reply = dbus_message_new_method_return (message);
566
122
  if (reply)
567
    {
568
122
      dbus_message_iter_init_append (reply, &iter);
569
122
      dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "s",
570
                                        &iter_array);
571
122
      spi_object_append_interfaces (&iter_array, object);
572
122
      dbus_message_iter_close_container (&iter, &iter_array);
573
    }
574
122
  return reply;
575
}
576

            
577
static dbus_bool_t
578
impl_get_AccessibleId (DBusMessageIter *iter, void *user_data)
579
{
580
  AtkObject *object = (AtkObject *) user_data;
581

            
582
  g_return_val_if_fail (ATK_IS_OBJECT (user_data), FALSE);
583

            
584
  return droute_return_v_string (iter, atk_object_get_accessible_id (object));
585
}
586

            
587
static dbus_bool_t
588
1
impl_get_HelpText (DBusMessageIter *iter, void *user_data)
589
{
590
1
  AtkObject *object = (AtkObject *) user_data;
591

            
592
1
  g_return_val_if_fail (ATK_IS_OBJECT (user_data), FALSE);
593

            
594
1
  return droute_return_v_string (iter, atk_object_get_help_text (object));
595
}
596

            
597
static DRouteMethod methods[] = {
598
  { impl_GetChildAtIndex, "GetChildAtIndex" },
599
  { impl_GetChildren, "GetChildren" },
600
  { impl_GetIndexInParent, "GetIndexInParent" },
601
  { impl_GetRelationSet, "GetRelationSet" },
602
  { impl_GetRole, "GetRole" },
603
  { impl_GetRoleName, "GetRoleName" },
604
  { impl_GetLocalizedRoleName, "GetLocalizedRoleName" },
605
  { impl_GetState, "GetState" },
606
  { impl_GetAttributes, "GetAttributes" },
607
  { impl_GetApplication, "GetApplication" },
608
  { impl_GetInterfaces, "GetInterfaces" },
609
  { NULL, NULL }
610
};
611

            
612
static DRouteProperty properties[] = {
613
  { impl_get_Name, NULL, "Name" },
614
  { impl_get_Description, NULL, "Description" },
615
  { impl_get_Locale, NULL, "Locale" },
616
  { impl_get_Parent, NULL, "Parent" },
617
  { impl_get_ChildCount, NULL, "ChildCount" },
618
  { impl_get_Attributes, NULL, "Attributes" },
619
  { impl_get_AccessibleId, NULL, "AccessibleId" },
620
  { impl_get_HelpText, NULL, "HelpText" },
621
  { impl_get_Version, NULL, "version" },
622
  { NULL, NULL, NULL }
623
};
624

            
625
void
626
161
spi_initialize_accessible (DRoutePath *path)
627
{
628
161
  spi_atk_add_interface (path,
629
                         ATSPI_DBUS_INTERFACE_ACCESSIBLE,
630
                         spi_org_a11y_atspi_Accessible,
631
                         methods, properties);
632
161
};