1
/*
2
 * AT-SPI - Assistive Technology Service Provider Interface
3
 * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
4
 *
5
 * Copyright 2001, 2002 Sun Microsystems Inc.,
6
 * Copyright 2001, 2002 Ximian, Inc.
7
 * Copyright 2010, 2011 Novell, 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 "atspi-accessible-private.h"
26
#include "atspi-private.h"
27
#include <string.h>
28

            
29
/**
30
 * AtspiAccessible:
31
 *
32
 * The base interface which is implemented by all accessible objects.
33
 *
34
 * All objects support interfaces for querying their contained 'children'
35
 * and position in the accessible-object hierarchy, whether or not they
36
 * actually have children.
37
 */
38

            
39
enum
40
{
41
  REGION_CHANGED,
42
  MODE_CHANGED,
43
  LAST_SIGNAL
44
};
45

            
46
static gboolean enable_caching = FALSE;
47
static guint quark_locale;
48

            
49
static guint atspi_accessible_signals[LAST_SIGNAL] = {
50
  0,
51
};
52

            
53
static gboolean
54
screen_reader_signal_watcher (GSignalInvocationHint *signal_hint,
55
                              guint n_param_values,
56
                              const GValue *param_values,
57
                              gpointer data)
58
{
59
  GObject *object;
60
  AtspiAccessible *accessible;
61
  GSignalQuery signal_query;
62
  const char *name;
63
  DBusMessage *signal;
64
  DBusMessageIter iter, iter_struct, iter_variant, iter_array;
65
  dbus_int32_t detail1 = 0, detail2 = 0;
66
  const char *detail = "";
67
  gchar *dbus_name;
68

            
69
  object = g_value_get_object (param_values + 0);
70
  g_return_val_if_fail (ATSPI_IS_ACCESSIBLE (object), FALSE);
71

            
72
  g_signal_query (signal_hint->signal_id, &signal_query);
73
  name = signal_query.signal_name;
74
  if (signal_hint->detail)
75
    detail = g_quark_to_string (signal_hint->detail);
76
  if (n_param_values > 1)
77
    detail1 = g_value_get_int (param_values + 1);
78
  if (n_param_values > 2 && G_VALUE_HOLDS_INT (param_values + 2))
79
    detail2 = g_value_get_int (param_values + 2);
80
  accessible = ATSPI_ACCESSIBLE (object);
81

            
82
  dbus_name = _atspi_strdup_and_adjust_for_dbus (name);
83
  signal = dbus_message_new_signal (ATSPI_DBUS_PATH_SCREEN_READER,
84
                                    ATSPI_DBUS_INTERFACE_EVENT_SCREEN_READER,
85
                                    dbus_name);
86
  g_free (dbus_name);
87
  dbus_message_iter_init_append (signal, &iter);
88
  dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &detail);
89
  dbus_message_iter_append_basic (&iter, DBUS_TYPE_INT32, &detail1);
90
  dbus_message_iter_append_basic (&iter, DBUS_TYPE_INT32, &detail2);
91
  dbus_message_iter_open_container (&iter, DBUS_TYPE_VARIANT, "(so)",
92
                                    &iter_variant);
93
  dbus_message_iter_open_container (&iter_variant, DBUS_TYPE_STRUCT, NULL,
94
                                    &iter_struct);
95
  dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &accessible->parent.app->bus_name);
96
  dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_OBJECT_PATH, &accessible->parent.path);
97
  dbus_message_iter_close_container (&iter_variant, &iter_struct);
98
  dbus_message_iter_close_container (&iter, &iter_variant);
99
  dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "{sv}",
100
                                    &iter_array);
101
  dbus_message_iter_close_container (&iter, &iter_array);
102
  dbus_connection_send (_atspi_bus (), signal, NULL);
103
  dbus_message_unref (signal);
104
  return TRUE;
105
}
106

            
107
static void
108
2
atspi_action_interface_init (AtspiAction *action)
109
{
110
2
}
111

            
112
static void
113
2
atspi_collection_interface_init (AtspiCollection *component)
114
{
115
2
}
116

            
117
static void
118
2
atspi_component_interface_init (AtspiComponent *component)
119
{
120
2
}
121

            
122
static void
123
2
atspi_document_interface_init (AtspiDocument *document)
124
{
125
2
}
126

            
127
static void
128
2
atspi_editable_text_interface_init (AtspiEditableText *editable_text)
129
{
130
2
}
131

            
132
static void
133
2
atspi_hypertext_interface_init (AtspiHypertext *hypertext)
134
{
135
2
}
136

            
137
static void
138
2
atspi_image_interface_init (AtspiImage *image)
139
{
140
2
}
141

            
142
static void
143
2
atspi_selection_interface_init (AtspiSelection *selection)
144
{
145
2
}
146

            
147
static void
148
2
atspi_table_interface_init (AtspiTable *table)
149
{
150
2
}
151

            
152
static void
153
2
atspi_table_cell_interface_init (AtspiTableCell *cell)
154
{
155
2
}
156

            
157
static void
158
2
atspi_text_interface_init (AtspiText *text)
159
{
160
2
}
161

            
162
static void
163
2
atspi_value_interface_init (AtspiValue *value)
164
{
165
2
}
166

            
167
2
G_DEFINE_TYPE_WITH_CODE (AtspiAccessible, atspi_accessible, ATSPI_TYPE_OBJECT, G_ADD_PRIVATE (AtspiAccessible) G_IMPLEMENT_INTERFACE (ATSPI_TYPE_ACTION, atspi_action_interface_init) G_IMPLEMENT_INTERFACE (ATSPI_TYPE_COLLECTION, atspi_collection_interface_init) G_IMPLEMENT_INTERFACE (ATSPI_TYPE_COMPONENT, atspi_component_interface_init) G_IMPLEMENT_INTERFACE (ATSPI_TYPE_DOCUMENT, atspi_document_interface_init) G_IMPLEMENT_INTERFACE (ATSPI_TYPE_EDITABLE_TEXT, atspi_editable_text_interface_init) G_IMPLEMENT_INTERFACE (ATSPI_TYPE_HYPERTEXT, atspi_hypertext_interface_init) G_IMPLEMENT_INTERFACE (ATSPI_TYPE_IMAGE, atspi_image_interface_init) G_IMPLEMENT_INTERFACE (ATSPI_TYPE_SELECTION, atspi_selection_interface_init) G_IMPLEMENT_INTERFACE (ATSPI_TYPE_TABLE, atspi_table_interface_init) G_IMPLEMENT_INTERFACE (ATSPI_TYPE_TABLE_CELL, atspi_table_cell_interface_init) G_IMPLEMENT_INTERFACE (ATSPI_TYPE_TEXT, atspi_text_interface_init) G_IMPLEMENT_INTERFACE (ATSPI_TYPE_VALUE, atspi_value_interface_init))
168

            
169
#ifdef DEBUG_REF_COUNTS
170
static gint accessible_count = 0;
171
#endif
172

            
173
static void
174
1406
atspi_accessible_unref (GObject *accessible)
175
{
176
1406
  if (accessible != NULL)
177
1406
    g_object_unref (accessible);
178
1406
}
179

            
180
static void
181
1725
atspi_accessible_init (AtspiAccessible *accessible)
182
{
183
#ifdef DEBUG_REF_COUNTS
184
  accessible_count++;
185
  g_hash_table_insert (_atspi_get_live_refs (), accessible, NULL);
186
  g_print ("at-spi: init: %d objects\n", accessible_count);
187
#endif
188

            
189
1725
  accessible->priv = atspi_accessible_get_instance_private (accessible);
190

            
191
1725
  accessible->children = g_ptr_array_new_with_free_func ((GDestroyNotify) atspi_accessible_unref);
192
1725
}
193

            
194
static void
195
2659
atspi_accessible_dispose (GObject *object)
196
{
197
2659
  AtspiAccessible *accessible = ATSPI_ACCESSIBLE (object);
198
  AtspiEvent e;
199
  AtspiAccessible *parent;
200
  gint i;
201

            
202
  /* TODO: Only fire if object not already marked defunct */
203
2659
  memset (&e, 0, sizeof (e));
204
2659
  e.type = "object:state-changed:defunct";
205
2659
  e.source = accessible;
206
2659
  e.detail1 = 1;
207
2659
  e.detail2 = 0;
208
2659
  _atspi_send_event (&e);
209

            
210
2659
  g_clear_object (&accessible->states);
211

            
212
2659
  parent = accessible->accessible_parent;
213
2659
  if (parent)
214
    {
215
560
      accessible->accessible_parent = NULL;
216
560
      if (parent->children)
217
560
        g_ptr_array_remove (parent->children, accessible);
218
560
      g_object_unref (parent);
219
    }
220

            
221
2659
  if (accessible->children)
222
2254
    for (i = accessible->children->len - 1; i >= 0; i--)
223
      {
224
846
        AtspiAccessible *child = g_ptr_array_index (accessible->children, i);
225
846
        if (child && child->accessible_parent == accessible)
226
          {
227
846
            child->accessible_parent = NULL;
228
846
            g_object_unref (accessible);
229
          }
230
      }
231

            
232
2659
  if (accessible->children)
233
    {
234
1408
      g_ptr_array_free (accessible->children, TRUE);
235
1408
      accessible->children = NULL;
236
    }
237

            
238
2659
  G_OBJECT_CLASS (atspi_accessible_parent_class)->dispose (object);
239
2659
}
240

            
241
static void
242
1251
atspi_accessible_finalize (GObject *object)
243
{
244
1251
  AtspiAccessible *accessible = ATSPI_ACCESSIBLE (object);
245

            
246
1251
  g_free (accessible->description);
247
1251
  g_free (accessible->name);
248

            
249
1251
  if (accessible->attributes)
250
    g_hash_table_unref (accessible->attributes);
251

            
252
1251
  if (accessible->priv->cache)
253
    g_hash_table_destroy (accessible->priv->cache);
254

            
255
#ifdef DEBUG_REF_COUNTS
256
  accessible_count--;
257
  g_hash_table_remove (_atspi_get_live_refs (), accessible);
258
  g_print ("at-spi: finalize: %d objects\n", accessible_count);
259
#endif
260

            
261
1251
  G_OBJECT_CLASS (atspi_accessible_parent_class)->finalize (object);
262

            
263
  /* TODO: remove emission hook */
264
1251
}
265

            
266
static void
267
2
atspi_accessible_class_init (AtspiAccessibleClass *klass)
268
{
269
2
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
270

            
271
2
  object_class->dispose = atspi_accessible_dispose;
272
2
  object_class->finalize = atspi_accessible_finalize;
273

            
274
2
  quark_locale = g_quark_from_string ("accessible-locale");
275

            
276
  /**
277
   * AtspiAccessible::region-changed:
278
   * @atspiaccessible: the object which received the signal
279
   * @arg1: an integer specifying the current offset of the text being read,
280
   *        if the object is textual.
281
   * @arg2: an integer specifying the ending offset of the text being read,
282
   *        if the object is textual.
283
   *
284
   * The signal "region-changed" is emitted by a screen reader to indicate
285
   * that it is now reading or tracking a new object, or, a new piece of
286
   * text within an object. This allows a magnifier to gain the information
287
   * needed to highlight the object that the screen reader is reading.
288
   */
289
2
  atspi_accessible_signals[REGION_CHANGED] =
290
2
      g_signal_new ("region_changed",
291
                    G_TYPE_FROM_CLASS (klass),
292
                    G_SIGNAL_RUN_LAST,
293
                    G_STRUCT_OFFSET (AtspiAccessibleClass, region_changed),
294
                    NULL, NULL,
295
                    atspi_marshal_VOID__INT_INT,
296
                    G_TYPE_NONE,
297
                    2, G_TYPE_INT, G_TYPE_INT);
298

            
299
  /**
300
   * AtspiAccessible::mode-changed:
301
   * @atspiaccessible: the object which received the signal
302
   * @arg1: a boolean specifying whether the mode is being toggled on or off.
303
   * @why: an optional string explaining why the mode changed.
304
   *
305
   * The signal "mode-changed" is emitted by a screen reader to indicate
306
   * that its mode has changed. This signal supports the following details:
307
   * focus-tracking
308
   * flat-review
309
   * mouse-review
310
   * say-all
311
   * caret-tracking
312
   */
313
2
  atspi_accessible_signals[MODE_CHANGED] =
314
2
      g_signal_new ("mode_changed",
315
                    G_TYPE_FROM_CLASS (klass),
316
                    G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
317
                    G_STRUCT_OFFSET (AtspiAccessibleClass, mode_changed),
318
                    NULL, NULL,
319
                    atspi_marshal_VOID__INT_STRING,
320
                    G_TYPE_NONE,
321
                    2, G_TYPE_INT, G_TYPE_STRING);
322

            
323
2
  g_signal_add_emission_hook (atspi_accessible_signals[REGION_CHANGED], 0,
324
                              screen_reader_signal_watcher, NULL,
325
                              (GDestroyNotify) NULL);
326
2
  g_signal_add_emission_hook (atspi_accessible_signals[MODE_CHANGED], 0,
327
                              screen_reader_signal_watcher, NULL,
328
                              (GDestroyNotify) NULL);
329
2
}
330

            
331
/**
332
 * atspi_accessible_get_name:
333
 * @obj: a pointer to the #AtspiAccessible object on which to operate.
334
 *
335
 * Gets the name of an #AtspiAccessible object.
336
 *
337
 * Returns: a UTF-8 string indicating the name of the #AtspiAccessible object
338
 * or NULL on exception.
339
 **/
340
gchar *
341
464
atspi_accessible_get_name (AtspiAccessible *obj, GError **error)
342
{
343
464
  g_return_val_if_fail (obj != NULL, g_strdup (""));
344

            
345
464
  if (!_atspi_accessible_test_cache (obj, ATSPI_CACHE_NAME))
346
    {
347
201
      g_free (obj->name);
348
201
      obj->name = NULL;
349
201
      if (!_atspi_dbus_get_property (obj, atspi_interface_accessible, "Name", error,
350
201
                                     "s", &obj->name))
351
39
        return g_strdup ("");
352
162
      _atspi_accessible_add_cache (obj, ATSPI_CACHE_NAME);
353
    }
354
425
  return g_strdup (obj->name);
355
}
356

            
357
/**
358
 * atspi_accessible_get_description:
359
 * @obj: a pointer to the #AtspiAccessible object on which to operate.
360
 *
361
 * Gets the description of an #AtspiAccessible object.
362
 *
363
 * Returns: a UTF-8 string describing the #AtspiAccessible object
364
 * or NULL on exception.
365
 **/
366
gchar *
367
1
atspi_accessible_get_description (AtspiAccessible *obj, GError **error)
368
{
369
1
  g_return_val_if_fail (obj != NULL, g_strdup (""));
370

            
371
1
  if (!_atspi_accessible_test_cache (obj, ATSPI_CACHE_DESCRIPTION))
372
    {
373
1
      g_free (obj->description);
374
1
      obj->description = NULL;
375
1
      if (!_atspi_dbus_get_property (obj, atspi_interface_accessible,
376
                                     "Description", error, "s",
377
1
                                     &obj->description))
378
        return g_strdup ("");
379
1
      _atspi_accessible_add_cache (obj, ATSPI_CACHE_DESCRIPTION);
380
    }
381
1
  return g_strdup (obj->description);
382
}
383

            
384
const char *str_parent = "Parent";
385

            
386
/**
387
 * atspi_accessible_get_parent:
388
 * @obj: a pointer to the #AtspiAccessible object to query.
389
 *
390
 * Gets an #AtspiAccessible object's parent container.
391
 *
392
 * Returns: (nullable) (transfer full): a pointer to the
393
 *          #AtspiAccessible object which contains the given
394
 *          #AtspiAccessible instance, or NULL if the @obj has no
395
 *          parent container.
396
 *
397
 **/
398
AtspiAccessible *
399
3
atspi_accessible_get_parent (AtspiAccessible *obj, GError **error)
400
{
401
3
  g_return_val_if_fail (obj != NULL, NULL);
402

            
403
3
  if (!_atspi_accessible_test_cache (obj, ATSPI_CACHE_PARENT))
404
    {
405
      DBusMessage *message, *reply;
406
      DBusMessageIter iter, iter_variant;
407
3
      if (!obj->parent.app)
408
        return NULL;
409
3
      message = dbus_message_new_method_call (obj->parent.app->bus_name,
410
3
                                              obj->parent.path,
411
                                              DBUS_INTERFACE_PROPERTIES, "Get");
412
3
      if (!message)
413
        return NULL;
414
3
      dbus_message_append_args (message, DBUS_TYPE_STRING, &atspi_interface_accessible,
415
                                DBUS_TYPE_STRING, &str_parent,
416
                                DBUS_TYPE_INVALID);
417
3
      reply = _atspi_dbus_send_with_reply_and_block (message, error);
418
3
      if (!reply)
419
        return NULL;
420
3
      if (strcmp (dbus_message_get_signature (reply), "v") != 0)
421
        {
422
          dbus_message_unref (reply);
423
          return NULL;
424
        }
425
3
      dbus_message_iter_init (reply, &iter);
426
3
      dbus_message_iter_recurse (&iter, &iter_variant);
427
3
      g_clear_object (&obj->accessible_parent);
428
3
      obj->accessible_parent = _atspi_dbus_consume_accessible (&iter_variant);
429
3
      dbus_message_unref (reply);
430
3
      _atspi_accessible_add_cache (obj, ATSPI_CACHE_PARENT);
431
    }
432
3
  if (!obj->accessible_parent)
433
2
    return NULL;
434
1
  return g_object_ref (obj->accessible_parent);
435
}
436

            
437
/**
438
 * atspi_accessible_get_child_count:
439
 * @obj: a pointer to the #AtspiAccessible object on which to operate.
440
 *
441
 * Gets the number of children contained by an #AtspiAccessible object.
442
 *
443
 * Returns: a #long indicating the number of #AtspiAccessible children
444
 *          contained by an #AtspiAccessible object or -1 on exception.
445
 *
446
 **/
447
gint
448
2847
atspi_accessible_get_child_count (AtspiAccessible *obj, GError **error)
449
{
450
2847
  g_return_val_if_fail (obj != NULL, -1);
451

            
452
2847
  if (!_atspi_accessible_test_cache (obj, ATSPI_CACHE_CHILDREN))
453
    {
454
      dbus_int32_t ret;
455
2847
      if (!_atspi_dbus_get_property (obj, atspi_interface_accessible,
456
                                     "ChildCount", error, "i", &ret))
457
        return -1;
458
2847
      return ret;
459
    }
460

            
461
  if (!obj->children)
462
    return 0; /* assume it's disposed */
463

            
464
  return obj->children->len;
465
}
466

            
467
/**
468
 * atspi_accessible_get_child_at_index:
469
 * @obj: a pointer to the #AtspiAccessible object on which to operate.
470
 * @child_index: a #long indicating which child is specified.
471
 *
472
 * Gets the #AtspiAccessible child of an #AtspiAccessible object at a given index.
473
 *
474
 * Returns: (transfer full): a pointer to the #AtspiAccessible child object at
475
 * index @child_index or NULL on exception.
476
 **/
477
AtspiAccessible *
478
577
atspi_accessible_get_child_at_index (AtspiAccessible *obj,
479
                                     gint child_index,
480
                                     GError **error)
481
{
482
  AtspiAccessible *child;
483
  DBusMessage *reply;
484

            
485
577
  g_return_val_if_fail (obj != NULL, NULL);
486

            
487
577
  if (_atspi_accessible_test_cache (obj, ATSPI_CACHE_CHILDREN))
488
    {
489
22
      if (!obj->children)
490
        return NULL; /* assume disposed */
491

            
492
22
      child = g_ptr_array_index (obj->children, child_index);
493
22
      if (child)
494
22
        return g_object_ref (child);
495
    }
496

            
497
555
  reply = _atspi_dbus_call_partial (obj, atspi_interface_accessible,
498
                                    "GetChildAtIndex", error, "i", child_index);
499
555
  child = _atspi_dbus_return_accessible_from_message (reply);
500

            
501
555
  if (!child)
502
7
    return NULL;
503

            
504
548
  if (_atspi_accessible_test_cache (obj, ATSPI_CACHE_CHILDREN))
505
    {
506
110
      if (child_index >= obj->children->len)
507
        g_ptr_array_set_size (obj->children, child_index + 1);
508
110
      g_ptr_array_index (obj->children, child_index) = g_object_ref (child);
509
    }
510
548
  return child;
511
}
512

            
513
/**
514
 * atspi_accessible_get_index_in_parent:
515
 * @obj: a pointer to the #AtspiAccessible object on which to operate.
516
 *
517
 * Gets the index of an #AtspiAccessible object within its parent's
518
 * #AtspiAccessible children list.
519
 *
520
 * Returns: a #glong indicating the index of the #AtspiAccessible object
521
 *          in its parent,
522
 *          or -1 if @obj has no containing parent or on exception.
523
 **/
524
gint
525
1
atspi_accessible_get_index_in_parent (AtspiAccessible *obj, GError **error)
526
{
527
1
  gint i = 0;
528
1
  dbus_int32_t ret = -1;
529

            
530
1
  g_return_val_if_fail (obj != NULL, -1);
531
1
  if (_atspi_accessible_test_cache (obj, ATSPI_CACHE_PARENT))
532
    {
533
      if (!obj->accessible_parent)
534
        return -1;
535

            
536
      if (!_atspi_accessible_test_cache (obj->accessible_parent, ATSPI_CACHE_CHILDREN) || !obj->accessible_parent->children)
537
        goto dbus;
538

            
539
      for (i = 0; i < obj->accessible_parent->children->len; i++)
540
        if (g_ptr_array_index (obj->accessible_parent->children, i) == obj)
541
          return i;
542
    }
543

            
544
1
dbus:
545
1
  _atspi_dbus_call (obj, atspi_interface_accessible,
546
                    "GetIndexInParent", NULL, "=>i", &ret);
547
1
  return ret;
548
}
549

            
550
typedef struct
551
{
552
  dbus_uint32_t type;
553
  GArray *targets;
554
} Accessibility_Relation;
555

            
556
/**
557
 * atspi_accessible_get_relation_set:
558
 * @obj: a pointer to the #AtspiAccessible object on which to operate.
559
 *
560
 * Gets the set of #AtspiRelation objects which describes this #AtspiAccessible object's
561
 * relationships with other #AtspiAccessible objects.
562
 *
563
 * Returns: (element-type AtspiRelation*) (transfer full): a #GArray of
564
 *          #AtspiRelation pointers or NULL on exception.
565
 **/
566
GArray *
567
2
atspi_accessible_get_relation_set (AtspiAccessible *obj, GError **error)
568
{
569
  DBusMessage *reply;
570
  DBusMessageIter iter, iter_array;
571
  GArray *ret;
572

            
573
2
  g_return_val_if_fail (obj != NULL, NULL);
574

            
575
2
  reply = _atspi_dbus_call_partial (obj, atspi_interface_accessible, "GetRelationSet", error, "");
576
2
  if (!reply)
577
    return NULL;
578
2
  _ATSPI_DBUS_CHECK_SIG (reply, "a(ua(so))", error, NULL);
579

            
580
2
  ret = g_array_new (TRUE, TRUE, sizeof (AtspiRelation *));
581
2
  dbus_message_iter_init (reply, &iter);
582
2
  dbus_message_iter_recurse (&iter, &iter_array);
583
4
  while (dbus_message_iter_get_arg_type (&iter_array) != DBUS_TYPE_INVALID)
584
    {
585
      AtspiRelation *relation;
586
2
      relation = _atspi_relation_new_from_iter (&iter_array);
587
2
      ret = g_array_append_val (ret, relation);
588
2
      dbus_message_iter_next (&iter_array);
589
    }
590
2
  dbus_message_unref (reply);
591
2
  return ret;
592
}
593

            
594
/**
595
 * atspi_accessible_get_role:
596
 * @obj: a pointer to the #AtspiAccessible object on which to operate.
597
 *
598
 * Gets the UI role played by an #AtspiAccessible object.
599
 * This role's name can be obtained via atspi_accessible_get_role_name ().
600
 *
601
 * Returns: the #AtspiRole of an #AtspiAccessible object.
602
 *
603
 **/
604
AtspiRole
605
6
atspi_accessible_get_role (AtspiAccessible *obj, GError **error)
606
{
607
6
  g_return_val_if_fail (obj != NULL, ATSPI_ROLE_INVALID);
608

            
609
6
  if (!_atspi_accessible_test_cache (obj, ATSPI_CACHE_ROLE))
610
    {
611
      dbus_uint32_t role;
612
      /* TODO: Make this a property */
613
6
      if (_atspi_dbus_call (obj, atspi_interface_accessible, "GetRole", error, "=>u", &role))
614
        {
615
6
          obj->role = role;
616
6
          _atspi_accessible_add_cache (obj, ATSPI_CACHE_ROLE);
617
        }
618
    }
619
6
  return obj->role;
620
}
621

            
622
/**
623
 * atspi_accessible_get_role_name:
624
 * @obj: a pointer to the #AtspiAccessible object on which to operate.
625
 *
626
 * Gets a UTF-8 string corresponding to the name of the role played by an object.
627
 * This method will return useful values for roles that fall outside the
628
 * enumeration used in atspi_accessible_get_role ().
629
 *
630
 * Returns: a UTF-8 string specifying the type of UI role played by an
631
 * #AtspiAccessible object.
632
 *
633
 **/
634
gchar *
635
1
atspi_accessible_get_role_name (AtspiAccessible *obj, GError **error)
636
{
637
1
  gchar *retval = NULL;
638
  AtspiRole role;
639

            
640
1
  g_return_val_if_fail (obj != NULL, NULL);
641

            
642
1
  role = atspi_accessible_get_role (obj, error);
643
1
  if (role >= 0 && role < ATSPI_ROLE_COUNT && role != ATSPI_ROLE_EXTENDED)
644
1
    return atspi_role_get_name (role);
645

            
646
  _atspi_dbus_call (obj, atspi_interface_accessible, "GetRoleName", error, "=>s", &retval);
647

            
648
  if (!retval)
649
    retval = g_strdup ("");
650

            
651
  return retval;
652
}
653

            
654
/**
655
 * atspi_accessible_get_localized_role_name:
656
 * @obj: a pointer to the #AtspiAccessible object on which to operate.
657
 *
658
 * Gets a UTF-8 string corresponding to the name of the role played by an
659
 * object, translated to the current locale.
660
 * This method will return useful values for roles that fall outside the
661
 * enumeration used in atspi_accessible_getRole ().
662
 *
663
 * Returns: a localized, UTF-8 string specifying the type of UI role played
664
 * by an #AtspiAccessible object.
665
 *
666
 **/
667
gchar *
668
1
atspi_accessible_get_localized_role_name (AtspiAccessible *obj, GError **error)
669
{
670
1
  char *retval = NULL;
671

            
672
1
  g_return_val_if_fail (obj != NULL, NULL);
673

            
674
1
  _atspi_dbus_call (obj, atspi_interface_accessible, "GetLocalizedRoleName", error, "=>s", &retval);
675

            
676
1
  if (!retval)
677
    return g_strdup ("");
678

            
679
1
  return retval;
680
}
681

            
682
static AtspiStateSet *
683
defunct_set ()
684
{
685
  AtspiStateSet *set = atspi_state_set_new (NULL);
686
  atspi_state_set_add (set, ATSPI_STATE_DEFUNCT);
687
  return set;
688
}
689

            
690
/**
691
 * atspi_accessible_get_state_set:
692
 * @obj: a pointer to the #AtspiAccessible object on which to operate.
693
 *
694
 * Gets the states currently held by an object.
695
 *
696
 * Returns: (transfer full): a pointer to an #AtspiStateSet representing an
697
 * object's current state set.
698
 **/
699
AtspiStateSet *
700
15
atspi_accessible_get_state_set (AtspiAccessible *obj)
701
{
702
  /* TODO: Should take a GError **, but would be an API break */
703
15
  if (!obj->parent.app || !obj->parent.app->bus)
704
    return defunct_set ();
705

            
706
15
  if (!_atspi_accessible_test_cache (obj, ATSPI_CACHE_STATES))
707
    {
708
      DBusMessage *reply;
709
      DBusMessageIter iter;
710
2
      reply = _atspi_dbus_call_partial (obj, atspi_interface_accessible,
711
                                        "GetState", NULL, "");
712
2
      _ATSPI_DBUS_CHECK_SIG (reply, "au", NULL, defunct_set ());
713
2
      dbus_message_iter_init (reply, &iter);
714
2
      _atspi_dbus_set_state (obj, &iter);
715
2
      dbus_message_unref (reply);
716
2
      _atspi_accessible_add_cache (obj, ATSPI_CACHE_STATES);
717
    }
718

            
719
15
  return g_object_ref (obj->states);
720
}
721

            
722
/**
723
 * atspi_accessible_get_attributes:
724
 * @obj: The #AtspiAccessible being queried.
725
 *
726
 * Gets the #AttributeSet representing any assigned
727
 * name-value pair attributes or annotations for this object.
728
 * For typographic, textual, or textually-semantic attributes, see
729
 * atspi_text_get_attributes instead.
730
 *
731
 * Returns: (element-type gchar* gchar*) (transfer full): The name-value-pair
732
 * attributes assigned to this object.
733
 */
734
GHashTable *
735
1
atspi_accessible_get_attributes (AtspiAccessible *obj, GError **error)
736
{
737
  DBusMessage *message;
738

            
739
1
  g_return_val_if_fail (obj != NULL, NULL);
740

            
741
1
  if (obj->priv->cache)
742
    {
743
      GValue *val = g_hash_table_lookup (obj->priv->cache, "Attributes");
744
      if (val)
745
        return g_value_dup_boxed (val);
746
    }
747

            
748
1
  if (!_atspi_accessible_test_cache (obj, ATSPI_CACHE_ATTRIBUTES))
749
    {
750
1
      message = _atspi_dbus_call_partial (obj, atspi_interface_accessible,
751
                                          "GetAttributes", error, "");
752
1
      g_clear_pointer (&(obj->attributes), g_hash_table_unref);
753

            
754
1
      obj->attributes = _atspi_dbus_return_hash_from_message (message);
755
1
      _atspi_accessible_add_cache (obj, ATSPI_CACHE_ATTRIBUTES);
756
    }
757

            
758
1
  if (!obj->attributes)
759
    return NULL;
760
1
  return g_hash_table_ref (obj->attributes);
761
}
762

            
763
static void
764
add_to_attribute_array (gpointer key, gpointer value, gpointer data)
765
{
766
  GArray **array = (GArray **) data;
767
  gchar *str = g_strconcat (key, ":", value, NULL);
768
  *array = g_array_append_val (*array, str);
769
}
770

            
771
/**
772
 * atspi_accessible_get_attributes_as_array:
773
 * @obj: The #AtspiAccessible being queried.
774
 *
775
 * Gets a #GArray representing any assigned
776
 * name-value pair attributes or annotations for this object.
777
 * For typographic, textual, or textually-semantic attributes, see
778
 * atspi_text_get_attributes_as_array instead.
779
 *
780
 * Returns: (element-type gchar*) (transfer full): The name-value-pair
781
 *          attributes assigned to this object.
782
 */
783
GArray *
784
1
atspi_accessible_get_attributes_as_array (AtspiAccessible *obj, GError **error)
785
{
786
  DBusMessage *message;
787

            
788
1
  g_return_val_if_fail (obj != NULL, NULL);
789

            
790
1
  if (obj->priv->cache)
791
    {
792
      GValue *val = g_hash_table_lookup (obj->priv->cache, "Attributes");
793
      if (val)
794
        {
795
          GArray *array = g_array_new (TRUE, TRUE, sizeof (gchar *));
796
          GHashTable *attributes = g_value_get_boxed (val);
797
          g_hash_table_foreach (attributes, add_to_attribute_array, &array);
798
          return array;
799
        }
800
    }
801

            
802
1
  message = _atspi_dbus_call_partial (obj, atspi_interface_accessible, "GetAttributes", error, "");
803
1
  return _atspi_dbus_return_attribute_array_from_message (message);
804
}
805

            
806
/**
807
 * atspi_accessible_get_application:
808
 * @obj: The #AtspiAccessible being queried.
809
 *
810
 * Gets the containing #AtspiApplication for an object.
811
 *
812
 * Returns: (transfer full): the containing #AtspiApplication instance for
813
 *          this object.
814
 */
815
AtspiAccessible *
816
1
atspi_accessible_get_application (AtspiAccessible *obj, GError **error)
817
{
818
  AtspiAccessible *parent;
819

            
820
1
  g_object_ref (obj);
821
  for (;;)
822
    {
823
1
      parent = atspi_accessible_get_parent (obj, NULL);
824
2
      if (!parent && obj->parent.app &&
825
1
          atspi_accessible_get_role (obj, NULL) != ATSPI_ROLE_APPLICATION)
826
        {
827
1
          AtspiAccessible *root = g_object_ref (obj->parent.app->root);
828
1
          if (root)
829
            {
830
1
              g_object_unref (obj);
831
1
              if (atspi_accessible_get_role (root, NULL) == ATSPI_ROLE_DESKTOP_FRAME)
832
                {
833
                  g_object_unref (root);
834
                  return NULL;
835
                }
836
1
              return root;
837
            }
838
        }
839
      if (!parent || parent == obj ||
840
          atspi_accessible_get_role (parent, NULL) == ATSPI_ROLE_DESKTOP_FRAME)
841
        {
842
          if (parent)
843
            g_object_unref (parent);
844
          return obj;
845
        }
846
      g_object_unref (obj);
847
      obj = parent;
848
    }
849
}
850

            
851
/* Application-specific methods */
852

            
853
/**
854
 * atspi_accessible_get_toolkit_name:
855
 * @obj: a pointer to the #AtspiAccessible object on which to operate.
856
 *
857
 * Gets the toolkit name for an #AtspiAccessible object.
858
 * Only works on application root objects.
859
 *
860
 * Returns: a UTF-8 string indicating the toolkit name for the #AtspiAccessible object or NULL on exception.
861
 **/
862
gchar *
863
1
atspi_accessible_get_toolkit_name (AtspiAccessible *obj, GError **error)
864
{
865
1
  g_return_val_if_fail (obj != NULL, NULL);
866

            
867
1
  if (!obj->parent.app)
868
    return NULL;
869

            
870
1
  if (!obj->parent.app->toolkit_name)
871
1
    _atspi_dbus_get_property (obj, atspi_interface_application, "ToolkitName",
872
1
                              error, "s", &obj->parent.app->toolkit_name);
873

            
874
1
  return g_strdup (obj->parent.app->toolkit_name);
875
}
876

            
877
/**
878
 * atspi_accessible_get_toolkit_version:
879
 * @obj: a pointer to the #AtspiAccessible object on which to operate.
880
 *
881
 * Gets the toolkit version for an #AtspiAccessible object.
882
 * Only works on application root objects.
883
 *
884
 * Returns: a UTF-8 string indicating the toolkit version for the #AtspiAccessible object or NULL on exception.
885
 **/
886
gchar *
887
1
atspi_accessible_get_toolkit_version (AtspiAccessible *obj, GError **error)
888
{
889
1
  g_return_val_if_fail (obj != NULL, NULL);
890

            
891
1
  if (!obj->parent.app)
892
    return NULL;
893

            
894
1
  if (!obj->parent.app->toolkit_version)
895
1
    _atspi_dbus_get_property (obj, atspi_interface_application, "Version",
896
1
                              error, "s", &obj->parent.app->toolkit_version);
897

            
898
1
  return g_strdup (obj->parent.app->toolkit_version);
899
}
900

            
901
/**
902
 * atspi_accessible_get_atspi_version:
903
 * @obj: a pointer to the #AtspiAccessible object on which to operate.
904
 *
905
 * Gets the AT-SPI IPC specification version supported by the application
906
 * pointed to by the #AtspiAccessible object.
907
 * Only works on application root objects.
908
 *
909
 * Returns: a UTF-8 string indicating the AT-SPI version for the #AtspiAccessible object or NULL on exception.
910
 **/
911
gchar *
912
1
atspi_accessible_get_atspi_version (AtspiAccessible *obj, GError **error)
913
{
914
1
  g_return_val_if_fail (obj != NULL, NULL);
915

            
916
1
  if (!obj->parent.app)
917
    return NULL;
918

            
919
1
  if (!obj->parent.app->atspi_version)
920
1
    _atspi_dbus_get_property (obj, atspi_interface_application, "AtspiVersion",
921
1
                              error, "s", &obj->parent.app->atspi_version);
922

            
923
1
  return g_strdup (obj->parent.app->atspi_version);
924
}
925

            
926
/**
927
 * atspi_accessible_get_id:
928
 * @obj: a pointer to the #AtspiAccessible object on which to operate.
929
 *
930
 * Gets the application id for a #AtspiAccessible object.
931
 * Only works on application root objects.
932
 *
933
 * Returns: a positive #gint indicating the id for the #AtspiAccessible object
934
 * or -1 on exception.
935
 **/
936
gint
937
1
atspi_accessible_get_id (AtspiAccessible *obj, GError **error)
938
{
939
1
  gint ret = -1;
940

            
941
1
  g_return_val_if_fail (obj != NULL, -1);
942

            
943
1
  if (!_atspi_dbus_get_property (obj, atspi_interface_application, "Id", error, "i", &ret))
944
    return -1;
945
1
  return ret;
946
}
947

            
948
/* Interface query methods */
949

            
950
static gboolean
951
141
_atspi_accessible_is_a (AtspiAccessible *accessible,
952
                        const char *interface_name)
953
{
954
  int n;
955

            
956
141
  if (accessible == NULL)
957
    {
958
      return FALSE;
959
    }
960

            
961
141
  if (!_atspi_accessible_test_cache (accessible, ATSPI_CACHE_INTERFACES))
962
    {
963
      DBusMessage *reply;
964
      DBusMessageIter iter;
965
14
      reply = _atspi_dbus_call_partial (accessible, atspi_interface_accessible,
966
                                        "GetInterfaces", NULL, "");
967
14
      _ATSPI_DBUS_CHECK_SIG (reply, "as", NULL, FALSE);
968
14
      dbus_message_iter_init (reply, &iter);
969
14
      _atspi_dbus_set_interfaces (accessible, &iter);
970
14
      dbus_message_unref (reply);
971
    }
972

            
973
141
  n = _atspi_get_iface_num (interface_name);
974
141
  if (n == -1)
975
    return FALSE;
976
141
  return (gboolean) ((accessible->interfaces & (1 << n)) ? TRUE : FALSE);
977
}
978

            
979
/**
980
 * atspi_accessible_is_action:
981
 * @obj: a pointer to the #AtspiAccessible instance to query.
982
 *
983
 * Query whether the specified #AtspiAccessible implements the
984
 * #AtspiAction interface.
985
 *
986
 * Returns: #TRUE if @obj implements the #AtspiAction interface,
987
 *          #FALSE otherwise.
988
 **/
989
gboolean
990
1
atspi_accessible_is_action (AtspiAccessible *obj)
991
{
992
1
  return _atspi_accessible_is_a (obj,
993
                                 atspi_interface_action);
994
}
995

            
996
/**
997
 * atspi_accessible_is_application:
998
 * @obj: a pointer to the #AtspiAccessible instance to query.
999
 *
 * Query whether the specified #AtspiAccessible implements the
 * #AtspiApplication interface.
 *
 * Returns: #TRUE if @obj implements the #AtspiApplication interface,
 *          #FALSE otherwise.
 **/
gboolean
atspi_accessible_is_application (AtspiAccessible *obj)
{
  return _atspi_accessible_is_a (obj,
                                 atspi_interface_application);
}
/**
 * atspi_accessible_is_collection:
 * @obj: a pointer to the #AtspiAccessible instance to query.
 *
 * Query whether the specified #AtspiAccessible implements the
 * #AtspiCollection interface.
 *
 * Returns: #TRUE if @obj implements the #AtspiCollection interface,
 *          #FALSE otherwise.
 **/
gboolean
1
atspi_accessible_is_collection (AtspiAccessible *obj)
{
1
  return _atspi_accessible_is_a (obj,
                                 atspi_interface_collection);
}
/**
 * atspi_accessible_is_component:
 * @obj: a pointer to the #AtspiAccessible instance to query.
 *
 * Query whether the specified #AtspiAccessible implements #AtspiComponent.
 *
 * Returns: #TRUE if @obj implements the #AtspiComponent interface,
 *          #FALSE otherwise.
 **/
gboolean
1
atspi_accessible_is_component (AtspiAccessible *obj)
{
1
  return _atspi_accessible_is_a (obj,
                                 atspi_interface_component);
}
/**
 * atspi_accessible_is_document:
 * @obj: a pointer to the #AtspiAccessible instance to query.
 *
 * Query whether the specified #AtspiAccessible implements the
 * #AtspiDocument interface.
 *
 * Returns: #TRUE if @obj implements the #AtspiDocument interface,
 *          #FALSE otherwise.
 **/
gboolean
1
atspi_accessible_is_document (AtspiAccessible *obj)
{
1
  return _atspi_accessible_is_a (obj,
                                 atspi_interface_document);
}
/**
 * atspi_accessible_is_editable_text:
 * @obj: a pointer to the #AtspiAccessible instance to query.
 *
 * Query whether the specified #AtspiAccessible implements the
 * #AtspiEditableText interface.
 *
 * Returns: #TRUE if @obj implements the #AtspiEditableText interface,
 *          #FALSE otherwise.
 **/
gboolean
1
atspi_accessible_is_editable_text (AtspiAccessible *obj)
{
1
  return _atspi_accessible_is_a (obj,
                                 atspi_interface_editable_text);
}
/**
 * atspi_accessible_is_hypertext:
 * @obj: a pointer to the #AtspiAccessible instance to query.
 *
 * Query whether the specified #AtspiAccessible implements the
 * #AtspiHypertext interface.
 *
 * Returns: #TRUE if @obj implements the #AtspiHypertext interface,
 *          #FALSE otherwise.
 **/
gboolean
1
atspi_accessible_is_hypertext (AtspiAccessible *obj)
{
1
  return _atspi_accessible_is_a (obj,
                                 atspi_interface_hypertext);
}
/**
 * atspi_accessible_is_hyperlink:
 * @obj: a pointer to the #AtspiAccessible instance to query.
 *
 * Query whether the specified #AtspiAccessible implements the
 * #AtspiHyperlink interface.
 *
 * Returns: #TRUE if @obj implements the #AtspiHypertext interface,
 *          #FALSE otherwise.
 **/
gboolean
1
atspi_accessible_is_hyperlink (AtspiAccessible *obj)
{
1
  return _atspi_accessible_is_a (obj,
                                 atspi_interface_hyperlink);
}
/**
 * atspi_accessible_is_image:
 * @obj: a pointer to the #AtspiAccessible instance to query.
 *
 * Query whether the specified #AtspiAccessible implements the
 * #AtspiImage interface.
 *
 * Returns: #TRUE if @obj implements the #AtspiImage interface,
 *          #FALSE otherwise.
 **/
gboolean
1
atspi_accessible_is_image (AtspiAccessible *obj)
{
1
  return _atspi_accessible_is_a (obj,
                                 atspi_interface_image);
}
/**
 * atspi_accessible_is_selection:
 * @obj: a pointer to the #AtspiAccessible instance to query.
 *
 * Query whether the specified #AtspiAccessible implements the
 * #AtspiSelection interface.
 *
 * Returns: #TRUE if @obj implements the #AtspiSelection interface,
 *          #FALSE otherwise.
 **/
gboolean
1
atspi_accessible_is_selection (AtspiAccessible *obj)
{
1
  return _atspi_accessible_is_a (obj,
                                 atspi_interface_selection);
}
/**
 * atspi_accessible_is_table:
 * @obj: a pointer to the #AtspiAccessible instance to query.
 *
 * Query whether the specified #AtspiAccessible implements the
 * #AtspiTable interface.
 *
 * Returns: #TRUE if @obj implements the #AtspiTable interface,
 *          #FALSE otherwise.
 **/
gboolean
1
atspi_accessible_is_table (AtspiAccessible *obj)
{
1
  return _atspi_accessible_is_a (obj,
                                 atspi_interface_table);
}
/**
 * atspi_accessible_is_table_cell:
 * @obj: a pointer to the #AtspiAccessible instance to query.
 *
 * Query whether the specified #AtspiAccessible implements the
 * #AtspiTableCell interface.
 *
 * Returns: #TRUE if @obj implements the #AtspiTable interface,
 *          #FALSE otherwise.
 **/
gboolean
1
atspi_accessible_is_table_cell (AtspiAccessible *obj)
{
1
  return _atspi_accessible_is_a (obj,
                                 atspi_interface_table_cell);
}
/**
 * atspi_accessible_is_streamable_content:
 * @obj: a pointer to the #AtspiAccessible instance to query.
 *
 * Query whether the specified #AtspiAccessible implements the
 * #AtspiStreamableContent interface.
 *
 * Returns: #TRUE if @obj implements the #AtspiStreamableContent interface,
 *          #FALSE otherwise.
 **/
gboolean
atspi_accessible_is_streamable_content (AtspiAccessible *obj)
{
#if 0
  return _atspi_accessible_is_a (obj,
			      atspi_interface_streamable_content);
#else
  g_warning ("Streamable content not implemented");
  return FALSE;
#endif
}
/**
 * atspi_accessible_is_text:
 * @obj: a pointer to the #AtspiAccessible instance to query.
 *
 * Query whether the specified #AtspiAccessible implements the
 * #AtspiText interface.
 *
 * Returns: #TRUE if @obj implements the #AtspiText interface,
 *          #FALSE otherwise.
 **/
gboolean
1
atspi_accessible_is_text (AtspiAccessible *obj)
{
1
  return _atspi_accessible_is_a (obj,
                                 atspi_interface_text);
}
/**
 * atspi_accessible_is_value:
 * @obj: a pointer to the #AtspiAccessible instance to query.
 *
 * Query whether the specified #AtspiAccessible implements the
 * #AtspiValue interface.
 *
 * Returns: #TRUE if @obj implements the #AtspiValue interface,
 *          #FALSE otherwise.
 **/
gboolean
1
atspi_accessible_is_value (AtspiAccessible *obj)
{
1
  return _atspi_accessible_is_a (obj,
                                 atspi_interface_value);
}
/**
 * atspi_accessible_get_action: (rename-to atspi_accessible_get_action_iface)
 * @obj: a pointer to the #AtspiAccessible instance to query.
 *
 * Gets the #AtspiAction interface for an #AtspiAccessible.
 *
 * Returns: (transfer full): a pointer to an #AtspiAction interface
 *          instance, or NULL if @obj does not implement #AtspiAction.
 *
 * Deprecated: 2.10: Use atspi_accessible_get_action_iface instead.
 **/
AtspiAction *
atspi_accessible_get_action (AtspiAccessible *accessible)
{
  return (_atspi_accessible_is_a (accessible, atspi_interface_action) ? g_object_ref (ATSPI_ACTION (accessible)) : NULL);
}
/**
 * atspi_accessible_get_action_iface:
 * @obj: a pointer to the #AtspiAccessible instance to query.
 *
 * Gets the #AtspiAction interface for an #AtspiAccessible.
 *
 * Returns: (transfer full): a pointer to an #AtspiAction interface
 *          instance, or NULL if @obj does not implement #AtspiAction.
 **/
AtspiAction *
8
atspi_accessible_get_action_iface (AtspiAccessible *accessible)
{
8
  return (_atspi_accessible_is_a (accessible, atspi_interface_action) ? g_object_ref (ATSPI_ACTION (accessible)) : NULL);
}
/**
 * atspi_accessible_get_collection: (rename-to atspi_accessible_get_collection_iface)
 * @obj: a pointer to the #AtspiAccessible instance to query.
 *
 * Gets the #AtspiCollection interface for an #AtspiAccessible.
 *
 * Returns: (transfer full): a pointer to an #AtspiCollection interface
 *          instance, or NULL if @obj does not implement #AtspiCollection.
 *
 * Deprecated: 2.10: Use atspi_accessible_get_collection_iface instead.
 **/
AtspiCollection *
atspi_accessible_get_collection (AtspiAccessible *accessible)
{
  return (_atspi_accessible_is_a (accessible, atspi_interface_collection) ? g_object_ref (ATSPI_COLLECTION (accessible)) : NULL);
}
/**
 * atspi_accessible_get_collection_iface:
 * @obj: a pointer to the #AtspiAccessible instance to query.
 *
 * Gets the #AtspiCollection interface for an #AtspiAccessible.
 *
 * Returns: (transfer full): a pointer to an #AtspiCollection interface
 *          instance, or NULL if @obj does not implement #AtspiCollection.
 **/
AtspiCollection *
5
atspi_accessible_get_collection_iface (AtspiAccessible *accessible)
{
5
  return (_atspi_accessible_is_a (accessible, atspi_interface_collection) ? g_object_ref (ATSPI_COLLECTION (accessible)) : NULL);
}
/**
 * atspi_accessible_get_component: (rename-to atspi_accessible_get_component_iface)
 * @obj: a pointer to the #AtspiAccessible instance to query.
 *
 * Gets the #AtspiComponent interface for an #AtspiAccessible.
 *
 * Returns: (transfer full): a pointer to an #AtspiComponent interface
 *          instance, or NULL if @obj does not implement #AtspiComponent.
 *
 * Deprecated: 2.10: Use atspi_accessible_get_component_iface instead.
 **/
AtspiComponent *
atspi_accessible_get_component (AtspiAccessible *obj)
{
  return (_atspi_accessible_is_a (obj, atspi_interface_component) ? g_object_ref (ATSPI_COMPONENT (obj)) : NULL);
}
/**
 * atspi_accessible_get_component_iface:
 * @obj: a pointer to the #AtspiAccessible instance to query.
 *
 * Gets the #AtspiComponent interface for an #AtspiAccessible.
 *
 * Returns: (transfer full): a pointer to an #AtspiComponent interface
 *          instance, or NULL if @obj does not implement #AtspiComponent.
 **/
AtspiComponent *
10
atspi_accessible_get_component_iface (AtspiAccessible *obj)
{
10
  return (_atspi_accessible_is_a (obj, atspi_interface_component) ? g_object_ref (ATSPI_COMPONENT (obj)) : NULL);
}
/**
 * atspi_accessible_get_document: (rename-to atspi_accessible_get_document_iface)
 * @obj: a pointer to the #AtspiAccessible instance to query.
 *
 * Gets the #AtspiDocument interface for an #AtspiAccessible.
 *
 * Returns: (transfer full): a pointer to an #AtspiDocument interface
 *          instance, or NULL if @obj does not implement #AtspiDocument.
 *
 * Deprecated: 2.10: Use atspi_accessible_get_document_iface instead.
 **/
AtspiDocument *
atspi_accessible_get_document (AtspiAccessible *accessible)
{
  return (_atspi_accessible_is_a (accessible, atspi_interface_document) ? g_object_ref (ATSPI_DOCUMENT (accessible)) : NULL);
}
/**
 * atspi_accessible_get_document_iface:
 * @obj: a pointer to the #AtspiAccessible instance to query.
 *
 * Gets the #AtspiDocument interface for an #AtspiAccessible.
 *
 * Returns: (transfer full): a pointer to an #AtspiDocument interface
 *          instance, or NULL if @obj does not implement #AtspiDocument.
 **/
AtspiDocument *
5
atspi_accessible_get_document_iface (AtspiAccessible *accessible)
{
5
  return (_atspi_accessible_is_a (accessible, atspi_interface_document) ? g_object_ref (ATSPI_DOCUMENT (accessible)) : NULL);
}
/**
 * atspi_accessible_get_editable_text: (rename-to atspi_accessible_get_editable_text_iface)
 * @obj: a pointer to the #AtspiAccessible instance to query.
 *
 * Gets the #AtspiEditableText interface for an #AtspiAccessible.
 *
 * Returns: (transfer full): a pointer to an #AtspiEditableText interface
 *          instance, or NULL if @obj does not implement #AtspiEditableText.
 *
 * Deprecated: 2.10: Use atspi_accessible_get_editable_text_iface instead.
 **/
AtspiEditableText *
atspi_accessible_get_editable_text (AtspiAccessible *accessible)
{
  return (_atspi_accessible_is_a (accessible, atspi_interface_editable_text) ? g_object_ref (ATSPI_EDITABLE_TEXT (accessible)) : NULL);
}
/**
 * atspi_accessible_get_editable_text_iface:
 * @obj: a pointer to the #AtspiAccessible instance to query.
 *
 * Gets the #AtspiEditableText interface for an #AtspiAccessible.
 *
 * Returns: (transfer full): a pointer to an #AtspiEditableText interface
 *          instance, or NULL if @obj does not implement #AtspiEditableText.
 **/
AtspiEditableText *
7
atspi_accessible_get_editable_text_iface (AtspiAccessible *accessible)
{
7
  return (_atspi_accessible_is_a (accessible, atspi_interface_editable_text) ? g_object_ref (ATSPI_EDITABLE_TEXT (accessible)) : NULL);
}
/**
 * atspi_accessible_get_hyperlink:
 * @obj: a pointer to the #AtspiAccessible object on which to operate.
 *
 * Gets the #AtspiHyperlink interface for an #AtspiAccessible.
 *
 * Returns: (transfer full): the #AtspiHyperlink object associated with
 *          the given #AtspiAccessible, or NULL if not supported.
 **/
AtspiHyperlink *
atspi_accessible_get_hyperlink (AtspiAccessible *accessible)
{
  return (_atspi_accessible_is_a (accessible, atspi_interface_hyperlink) ? _atspi_hyperlink_new (accessible->parent.app, accessible->parent.path) : NULL);
}
/**
 * atspi_accessible_get_hypertext: (rename-to atspi_accessible_get_hypertext_iface)
 * @obj: a pointer to the #AtspiAccessible instance to query.
 *
 * Gets the #AtspiHypertext interface for an #AtspiAccessible.
 *
 * Returns: (transfer full): a pointer to an #AtspiHypertext interface
 *          instance, or NULL if @obj does not implement #AtspiHypertext.
 *
 * Deprecated: 2.10: Use atspi_accessible_get_hypertext_iface instead.
 **/
AtspiHypertext *
atspi_accessible_get_hypertext (AtspiAccessible *accessible)
{
  return (_atspi_accessible_is_a (accessible, atspi_interface_hypertext) ? g_object_ref (ATSPI_HYPERTEXT (accessible)) : NULL);
}
/**
 * atspi_accessible_get_hypertext_iface:
 * @obj: a pointer to the #AtspiAccessible instance to query.
 *
 * Gets the #AtspiHypertext interface for an #AtspiAccessible.
 *
 * Returns: (transfer full): a pointer to an #AtspiHypertext interface
 *          instance, or NULL if @obj does not implement #AtspiHypertext.
 **/
AtspiHypertext *
11
atspi_accessible_get_hypertext_iface (AtspiAccessible *accessible)
{
11
  return (_atspi_accessible_is_a (accessible, atspi_interface_hypertext) ? g_object_ref (ATSPI_HYPERTEXT (accessible)) : NULL);
}
/**
 * atspi_accessible_get_image: (rename-to atspi_accessible_get_image_iface)
 * @obj: a pointer to the #AtspiAccessible instance to query.
 *
 * Gets the #AtspiImage interface for an #AtspiAccessible.
 *
 * Returns: (transfer full): a pointer to an #AtspiImage interface instance, or
 *          NULL if @obj does not implement #AtspiImage.
 *
 * Deprecated: 2.10: Use atspi_accessible_get_image_iface instead.
 **/
AtspiImage *
atspi_accessible_get_image (AtspiAccessible *accessible)
{
  return (_atspi_accessible_is_a (accessible, atspi_interface_image) ? g_object_ref (ATSPI_IMAGE (accessible)) : NULL);
}
/**
 * atspi_accessible_get_image_iface:
 * @obj: a pointer to the #AtspiAccessible instance to query.
 *
 * Gets the #AtspiImage interface for an #AtspiAccessible.
 *
 * Returns: (transfer full): a pointer to an #AtspiImage interface instance, or
 *          NULL if @obj does not implement #AtspiImage.
 **/
AtspiImage *
7
atspi_accessible_get_image_iface (AtspiAccessible *accessible)
{
7
  return (_atspi_accessible_is_a (accessible, atspi_interface_image) ? g_object_ref (ATSPI_IMAGE (accessible)) : NULL);
}
/**
 * atspi_accessible_get_selection: (rename-to atspi_accessible_get_selection_iface)
 * @obj: a pointer to the #AtspiAccessible instance to query.
 *
 * Gets the #AtspiSelection interface for an #AtspiAccessible.
 *
 * Returns: (transfer full): a pointer to an #AtspiSelection interface
 *          instance, or NULL if @obj does not implement #AtspiSelection.
 *
 * Deprecated: 2.10: Use atspi_accessible_get_selection_iface instead.
 **/
AtspiSelection *
atspi_accessible_get_selection (AtspiAccessible *accessible)
{
  return (_atspi_accessible_is_a (accessible, atspi_interface_selection) ? g_object_ref (ATSPI_SELECTION (accessible)) : NULL);
}
/**
 * atspi_accessible_get_selection_iface:
 * @obj: a pointer to the #AtspiAccessible instance to query.
 *
 * Gets the #AtspiSelection interface for an #AtspiAccessible.
 *
 * Returns: (transfer full): a pointer to an #AtspiSelection interface
 *          instance, or NULL if @obj does not implement #AtspiSelection.
 **/
AtspiSelection *
10
atspi_accessible_get_selection_iface (AtspiAccessible *accessible)
{
10
  return (_atspi_accessible_is_a (accessible, atspi_interface_selection) ? g_object_ref (ATSPI_SELECTION (accessible)) : NULL);
}
#if 0
/**
 * atspi_accessible_get_streamable_content:
 * @obj: a pointer to the #AtspiAccessible instance to query.
 *
 * Gets the #AtspiStreamableContent interface for an #AtspiAccessible.
 *
 * Returns: (transfer full): a pointer to an #AtspiStreamableContent interface
 *          instance, or NULL if @obj does not implement #AtspiStreamableContent.
 **/
AtspiStreamableContent *
atspi_accessible_get_streamable_content (AtspiAccessible *accessible)
{
  return (_atspi_accessible_is_a (accessible, atspi_interface_streamable_content) ?
          accessible : NULL);  
}
#endif
/**
 * atspi_accessible_get_table: (rename-to atspi_accessible_get_table_iface)
 * @obj: a pointer to the #AtspiAccessible instance to query.
 *
 * Gets the #AtspiTable interface for an #AtspiAccessible.
 *
 * Returns: (transfer full): a pointer to an #AtspiTable interface instance, or
 *          NULL if @obj does not implement #AtspiTable.
 *
 * Deprecated: 2.10: Use atspi_accessible_get_table_iface instead.
 **/
AtspiTable *
atspi_accessible_get_table (AtspiAccessible *obj)
{
  return (_atspi_accessible_is_a (obj, atspi_interface_table) ? g_object_ref (ATSPI_TABLE (obj)) : NULL);
}
/**
 * atspi_accessible_get_table_iface:
 * @obj: a pointer to the #AtspiAccessible instance to query.
 *
 * Gets the #AtspiTable interface for an #AtspiAccessible.
 *
 * Returns: (transfer full): a pointer to an #AtspiTable interface instance, or
 *          NULL if @obj does not implement #AtspiTable.
 **/
AtspiTable *
27
atspi_accessible_get_table_iface (AtspiAccessible *obj)
{