Add Hypertext and Hyperlink and some refactoring to support them
[platform/upstream/at-spi2-core.git] / atspi / atspi-accessible.c
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  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the
20  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21  * Boston, MA 02111-1307, USA.
22  */
23
24 #include "atspi-private.h"
25 #include <string.h>
26
27 static void
28 atspi_action_interface_init (AtspiAction *action)
29 {
30 }
31
32 static void
33 atspi_component_interface_init (AtspiComponent *component)
34 {
35 }
36
37 atspi_editable_text_interface_init (AtspiEditableText *editable_text)
38 {
39 }
40
41 static void
42 atspi_image_interface_init (AtspiImage *image)
43 {
44 }
45
46 static void
47 atspi_selection_interface_init (AtspiSelection *selection)
48 {
49 }
50
51 static void
52 atspi_table_interface_init (AtspiTable *table)
53 {
54 }
55
56 static void
57 atspi_text_interface_init (AtspiText *text)
58 {
59 }
60
61 static void
62 atspi_value_interface_init (AtspiValue *value)
63 {
64 }
65
66 G_DEFINE_TYPE_WITH_CODE (AtspiAccessible, atspi_accessible, ATSPI_TYPE_OBJECT,
67                          G_IMPLEMENT_INTERFACE (ATSPI_TYPE_ACTION, atspi_action_interface_init)
68                          G_IMPLEMENT_INTERFACE (ATSPI_TYPE_COMPONENT, atspi_component_interface_init)
69                          G_IMPLEMENT_INTERFACE (ATSPI_TYPE_EDITABLE_TEXT, atspi_editable_text_interface_init)
70                          G_IMPLEMENT_INTERFACE (ATSPI_TYPE_IMAGE, atspi_image_interface_init)
71                          G_IMPLEMENT_INTERFACE (ATSPI_TYPE_SELECTION, atspi_selection_interface_init)
72                          G_IMPLEMENT_INTERFACE (ATSPI_TYPE_TABLE, atspi_table_interface_init)
73                          G_IMPLEMENT_INTERFACE (ATSPI_TYPE_TEXT, atspi_text_interface_init)
74                          G_IMPLEMENT_INTERFACE (ATSPI_TYPE_VALUE, atspi_value_interface_init))
75
76 static void
77 atspi_accessible_init (AtspiAccessible *accessible)
78 {
79 }
80
81 static void
82 atspi_accessible_finalize (GObject *obj)
83 {
84   /*AtspiAccessible *accessible = ATSPI_ACCESSIBLE (obj); */
85
86   /* TODO: Unref parent/children, etc. */
87 }
88
89 static void
90 atspi_accessible_class_init (AtspiAccessibleClass *klass)
91 {
92   GObjectClass *object_class = G_OBJECT_CLASS (klass);
93
94   object_class->finalize = atspi_accessible_finalize;
95 }
96
97 /* TODO: Generate following from spec? */
98 static const char *role_names [] =
99 {
100   "invalid",
101   "accel-label",
102   "alert",
103   "animation",
104   "arrow",
105   "calendar",
106   "canvas",
107   "check-box",
108   "check-menu-item",
109   "color-chooser",
110   "column-header",
111   "combo-box",
112   "date-editor",
113   "desktop-icon",
114   "desktop-frame",
115   "dial",
116   "dialog",
117   "directory-pane",
118   "drawing-area",
119   "file-chooser",
120   "filler",
121   "font-chooser",
122   "frame",
123   "glass-pane",
124   "html-container",
125   "icon",
126   "image",
127   "internalframe",
128   "label",
129   "layered-pane",
130   "list",
131   "list-item",
132   "menu",
133   "menu-bar",
134   "menu-item",
135   "option-pane",
136   "page-tab",
137   "page-tab-list",
138   "panel",
139   "password-text",
140   "popup-menu",
141   "progress-bar",
142   "push-button",
143   "radio-button",
144   "radio-menu-item",
145   "root-pane",
146   "row-header",
147   "scroll-bar",
148   "scroll-pane",
149   "separator",
150   "slider",
151   "spin-button",
152   "split-pane",
153   "statusbar",
154   "table",
155   "table-cell",
156   "table-column-header",
157   "table-row-header",
158   "tear-off-menu-item",
159   "terminal",
160   "text",
161   "toggle-button",
162   "tool-bar",
163   "tool-tip",
164   "tree",
165   "tree-table",
166   "unknown",
167   "viewport",
168   "window",
169   NULL,
170   "header",
171   "fooler",
172   "paragraph",
173   "ruler",
174   "application",
175   "autocomplete",
176   "editbar",
177   "embedded",
178   "entry",
179   "chart",
180   "caption",
181   "document_frame",
182   "heading",
183   "page",
184   "section",
185   "form",
186   "redundant object",
187   "link",
188   "input method window"
189 };
190
191 #define MAX_ROLES (sizeof (role_names) / sizeof (char *))
192
193 /**
194  * atspi_role_get_name
195  * @role: an #AtspiAccessibleRole object to query.
196  *
197  * Get a localizeable string that indicates the name of an #AtspiAccessibleRole.
198  * <em>DEPRECATED.</em>
199  *
200  * Returns: a localizable string name for an #AtspiAccessibleRole enumerated type.
201  **/
202 gchar *
203 atspi_role_get_name (AtspiRole role)
204 {
205   if (role < MAX_ROLES && role_names [(int) role])
206     {
207       return g_strdup (role_names [(int) role]);
208     }
209   else
210     {
211       return g_strdup ("");
212     }
213 }
214
215 /**
216  * atspi_accessible_get_name:
217  * @obj: a pointer to the #AtspiAccessible object on which to operate.
218  *
219  * Get the name of an #AtspiAccessible object.
220  *
221  * Returns: a UTF-8 string indicating the name of the #AtspiAccessible object.
222  * or NULL on exception
223  **/
224 gchar *
225 atspi_accessible_get_name (AtspiAccessible *obj, GError **error)
226 {
227   g_return_val_if_fail (obj != NULL, NULL);
228   if (!(obj->cached_properties & ATSPI_CACHE_NAME))
229   {
230     if (!_atspi_dbus_get_property (obj, atspi_interface_accessible, "Name", NULL, "s", &obj->name))
231       return NULL;
232     obj->cached_properties |= ATSPI_CACHE_NAME;
233   }
234   return g_strdup (obj->name);
235 }
236
237 /**
238  * atspi_accessible_get_description:
239  * @obj: a pointer to the #AtspiAccessible object on which to operate.
240  *
241  * Get the description of an #AtspiAccessible object.
242  *
243  * Returns: a UTF-8 string describing the #AtspiAccessible object.
244  * or NULL on exception
245  **/
246 gchar *
247 atspi_accessible_get_description (AtspiAccessible *obj, GError **error)
248 {
249   g_return_val_if_fail (obj != NULL, NULL);
250
251   if (!(obj->cached_properties & ATSPI_CACHE_DESCRIPTION))
252   {
253     if (!_atspi_dbus_call (obj, atspi_interface_accessible, "GetDescription", NULL, "=>s", &obj->description))
254       return NULL;
255     obj->cached_properties |= ATSPI_CACHE_DESCRIPTION;
256   }
257   return g_strdup (obj->description);
258 }
259
260 const char *str_parent = "Parent";
261
262 /**
263  * atspi_accessible_get_parent:
264  * @obj: a pointer to the #AtspiAccessible object to query.
265  *
266  * Get an #AtspiAccessible object's parent container.
267  *
268  * Returns: (transfer full): a pointer to the #AtspiAccessible object which
269  *          contains the given #AtspiAccessible instance, or NULL if the @obj
270  *          has no parent container.
271  *
272  **/
273 AtspiAccessible *
274 atspi_accessible_get_parent (AtspiAccessible *obj, GError **error)
275 {
276   g_return_val_if_fail (obj != NULL, NULL);
277
278   if (!(obj->cached_properties & ATSPI_CACHE_PARENT))
279   {
280     DBusMessage *message, *reply;
281     DBusMessageIter iter, iter_variant;
282     message = dbus_message_new_method_call (obj->parent.app->bus_name,
283                                             obj->parent.path,
284                                             DBUS_INTERFACE_PROPERTIES, "Get");
285     if (!message)
286       return NULL;
287     dbus_message_append_args (message, DBUS_TYPE_STRING, &atspi_interface_accessible,
288                                DBUS_TYPE_STRING, &str_parent,
289                               DBUS_TYPE_INVALID);
290     reply = _atspi_dbus_send_with_reply_and_block (message);
291     if (!reply ||
292        (strcmp (dbus_message_get_signature (reply), "v") != 0))
293       return NULL;
294     dbus_message_iter_init (reply, &iter);
295     dbus_message_iter_recurse (&iter, &iter_variant);
296     obj->accessible_parent = _atspi_dbus_return_accessible_from_iter (&iter_variant);
297     dbus_message_unref (reply);
298     obj->cached_properties |= ATSPI_CACHE_PARENT;
299   }
300   if (!obj->accessible_parent)
301     return NULL;
302   return g_object_ref (obj->accessible_parent);
303 }
304
305 /**
306  * atspi_accessible_get_child_count:
307  * @obj: a pointer to the #AtspiAccessible object on which to operate.
308  *
309  * Get the number of children contained by an #AtspiAccessible object.
310  *
311  * Returns: a #long indicating the number of #AtspiAccessible children
312  *          contained by an #AtspiAccessible object. or -1 on exception
313  *
314  **/
315 gint
316 atspi_accessible_get_child_count (AtspiAccessible *obj, GError *error)
317 {
318   g_return_val_if_fail (obj != NULL, -1);
319
320   /* TODO: MANAGES_DESCENDANTS */
321   return g_list_length (obj->children);
322 }
323
324 /**
325  * atspi_accessible_get_child_at_index:
326  * @obj: a pointer to the #AtspiAccessible object on which to operate.
327  * @child_index: a #long indicating which child is specified.
328  *
329  * Get the #AtspiAccessible child of an #AtspiAccessible object at a given index.
330  *
331  * Returns: (transfer full): a pointer to the #AtspiAccessible child object at
332  * index @child_index. or NULL on exception
333  **/
334 AtspiAccessible *
335 atspi_accessible_get_child_at_index (AtspiAccessible *obj,
336                             gint    child_index,
337                             GError **error)
338 {
339   AtspiAccessible *child;
340
341   g_return_val_if_fail (obj != NULL, NULL);
342
343   /* TODO: ManagesDescendants */
344   child = g_list_nth_data (obj->children, child_index);
345   if (!child)
346     return NULL;
347   return g_object_ref (child);
348 }
349
350 /**
351  * atspi_accessible_get_index_in_parent
352  * @obj: a pointer to the #AtspiAccessible object on which to operate.
353  *
354  * Get the index of an #AtspiAccessible object in its containing #AtspiAccessible.
355  *
356  * Returns: a #glong indicating the index of the #AtspiAccessible object
357  *          in its parent (i.e. containing) #AtspiAccessible instance,
358  *          or -1 if @obj has no containing parent or on exception.
359  **/
360 gint
361 atspi_accessible_get_index_in_parent (AtspiAccessible *obj, GError **error)
362 {
363   GList *l;
364   gint i;
365
366   g_return_val_if_fail (obj != NULL, -1);
367   if (!obj->accessible_parent) return -1;
368   l = obj->accessible_parent->children;
369   while (l)
370   {
371     if (l->data == obj) return i;
372     l = g_list_next (l);
373     i++;
374   }
375   return -1;
376 }
377
378 typedef struct
379 {
380   dbus_uint32_t type;
381   GArray *targets;
382 } Accessibility_Relation;
383
384 /**
385  * atspi_accessible_get_relation_set:
386  * @obj: a pointer to the #AtspiAccessible object on which to operate.
387  *
388  * Get the set of #AtspiRelation objects which describe this #AtspiAccessible object's
389  *       relationships with other #AtspiAccessible objects.
390  *
391  * Returns: an array of #AtspiAccessibleRelation pointers. or NULL on exception
392  * TODO:: Annotate array type
393  **/
394 GArray *
395 atspi_accessible_get_relation_set (AtspiAccessible *obj, GError **error)
396 {
397   int i;
398   int n_relations;
399   GArray *relation_set;
400
401   g_return_val_if_fail (obj != NULL, NULL);
402
403   if (!_atspi_dbus_call (obj, atspi_interface_accessible, "GetRelationSet", error, "=>a(uao)", &relation_set))
404     return NULL;
405
406   return relation_set;
407 }
408
409 /**
410  * atspi_accessible_get_role:
411  * @obj: a pointer to the #AtspiAccessible object on which to operate.
412  *
413  * Get the UI role of an #AtspiAccessible object.
414  * A UTF-8 string describing this role can be obtained via atspi_accessible_getRoleName ().
415  *
416  * Returns: the #AtspiRole of the object.
417  *
418  **/
419 AtspiRole
420 atspi_accessible_get_role (AtspiAccessible *obj, GError **error)
421 {
422   g_return_val_if_fail (obj != NULL, ATSPI_ROLE_INVALID);
423
424   if (!(obj->cached_properties & ATSPI_CACHE_ROLE))
425   {
426     dbus_uint32_t role;
427     /* TODO: Make this a property */
428     if (_atspi_dbus_call (obj, atspi_interface_accessible, "GetRole", NULL, "=>u", &role))
429     {
430       obj->cached_properties |= ATSPI_CACHE_ROLE;
431       obj->role = role;
432     }
433   }
434   return obj->role;
435 }
436
437 /**
438  * atspi_accessible_get_role_name:
439  * @obj: a pointer to the #AtspiAccessible object on which to operate.
440  *
441  * Get a UTF-8 string describing the role this object plays in the UI.
442  * This method will return useful values for roles that fall outside the
443  * enumeration used in atspi_accessible_getRole ().
444  *
445  * Returns: a UTF-8 string specifying the role of this #AtspiAccessible object.
446  *
447  **/
448 gchar *
449 atspi_accessible_get_role_name (AtspiAccessible *obj, GError **error)
450 {
451   char *retval = NULL;
452
453   g_return_val_if_fail (obj != NULL, g_strdup ("invalid"));
454
455   _atspi_dbus_call (obj, atspi_interface_accessible, "GetRoleName", error, "=>s", &retval);
456
457   return retval;
458 }
459
460 /**
461  * atspi_accessible_get_localized_role_name:
462  * @obj: a pointer to the #AtspiAccessible object on which to operate.
463  *
464  * Get a UTF-8 string describing the (localized) role this object plays in the UI.
465  * This method will return useful values for roles that fall outside the
466  * enumeration used in atspi_accessible_getRole ().
467  *
468  * Returns: a UTF-8 string specifying the role of this #AtspiAccessible object.
469  *
470  **/
471 gchar *
472 atspi_accessible_get_localized_role_name (AtspiAccessible *obj, GError **error)
473 {
474   char *retval = NULL;
475
476   g_return_val_if_fail (obj != NULL, g_strdup ("invalid"));
477
478   _atspi_dbus_call (obj, atspi_interface_accessible, "GetLocalizedRoleName", error, "=>s", &retval);
479
480   return retval;
481 }
482
483 /**
484  * atspi_accessible_get_state_set:
485  * @obj: a pointer to the #AtspiAccessible object on which to operate.
486  *
487  * Gets the current state of an object.
488  *
489  * Returns: (transfer full): a pointer to an #AtspiStateSet representing the
490  *          object's current state.
491  **/
492 AtspiStateSet *
493 atspi_accessible_get_state_set (AtspiAccessible *obj)
494 {
495   return obj->states;
496 }
497
498 /**
499  * atspi_accessible_get_attributes:
500  * @obj: The #AtspiAccessible being queried.
501  *
502  * Get the #AttributeSet representing any assigned 
503  * name-value pair attributes or annotations for this object.
504  * For typographic, textual, or textually-semantic attributes, see
505  * atspi_text_get_attributes instead.
506  *
507  * Returns: (element-type gchar* gchar*) (transfer full): The name-value-pair
508  *          attributes assigned to this object.
509  */
510 GHashTable *
511 atspi_accessible_get_attributes (AtspiAccessible *obj, GError **error)
512 {
513   DBusMessage *message;
514   GHashTable *ret;
515
516     g_return_val_if_fail (obj != NULL, NULL);
517
518   message = _atspi_dbus_call_partial (obj, atspi_interface_accessible, "GetAttributes", error, "");
519   ret = _atspi_dbus_hash_from_message (message);
520   dbus_message_unref (message);
521   return ret;
522 }
523
524 /**
525  * atspi_accessible_get_attributes_as_array:
526  * @obj: The #AtspiAccessible being queried.
527  *
528  * Get the #AttributeSet representing any assigned 
529  * name-value pair attributes or annotations for this object.
530  * For typographic, textual, or textually-semantic attributes, see
531  * atspi_text_get_attributes_as_array instead.
532  *
533  * Returns: (element-type gchar*) (transfer full): The name-value-pair
534  *          attributes assigned to this object.
535  */
536 GArray *
537 atspi_accessible_get_attributes_as_array (AtspiAccessible *obj, GError **error)
538 {
539   DBusMessage *message;
540   GArray *ret;
541
542     g_return_val_if_fail (obj != NULL, NULL);
543
544   message = _atspi_dbus_call_partial (obj, atspi_interface_accessible, "GetAttributes", error, "");
545   ret = _atspi_dbus_attribute_array_from_message (message);
546   dbus_message_unref (message);
547   return ret;
548 }
549
550 /**
551  * atspi_accessible_get_host_application:
552  * @obj: The #AtspiAccessible being queried.
553  *
554  * Get the containing #AtspiApplication for an object.
555  *
556  * Returns: (transfer full): the containing AtspiApplication instance for
557  *          this object.
558  */
559 AtspiAccessible *
560 atspi_accessible_get_host_application (AtspiAccessible *obj, GError **error)
561 {
562   AtspiAccessible *parent;
563
564   for (;;)
565   {
566     parent = atspi_accessible_get_parent (obj, NULL);
567     if (!parent || parent == obj ||
568         atspi_accessible_get_role (parent, NULL) == ATSPI_ROLE_DESKTOP_FRAME)
569     return obj;
570     obj = parent;
571   }
572 }
573
574 /* Interface query methods */
575
576 /**
577  * atspi_accessible_is_action:
578  * @obj: a pointer to the #AtspiAccessible instance to query.
579  *
580  * Query whether the specified #AtspiAccessible implements #AtspiAction.
581  *
582  * Returns: #TRUE if @obj implements the #AtspiAction interface,
583  *          #FALSE otherwise.
584  **/
585 gboolean
586 atspi_accessible_is_action (AtspiAccessible *obj)
587 {
588   return _atspi_accessible_is_a (obj,
589                               atspi_interface_action);
590 }
591
592 /**
593  * atspi_accessible_is_application:
594  * @obj: a pointer to the #AtspiAccessible instance to query.
595  *
596  * Query whether the specified #AtspiAccessible implements #AtspiApplication.
597  *
598  * Returns: #TRUE if @obj implements the #AtspiApplication interface,
599  *          #FALSE otherwise.
600  **/
601 gboolean
602 atspi_accessible_is_application (AtspiAccessible *obj)
603 {
604   return _atspi_accessible_is_a (obj,
605                               atspi_interface_application);
606 }
607
608 /**                      
609  * atspi_accessible_is_collection:                                                                                                                                                                          * @obj: a pointer to the #AtspiAccessible instance to query.                                                                                                                                          
610  *                          
611  * Query whether the specified #AtspiAccessible implements #AtspiCollection.    
612  * Returns: #TRUE if @obj implements the #AtspiCollection interface,                                                                                                               
613  *          #FALSE otherwise.
614  **/
615 gboolean
616 atspi_accessible_is_collection (AtspiAccessible *obj)
617 {
618 #if 0
619      g_warning ("Collections not implemented");
620      return _atspi_accessible_is_a (obj,
621                               atspi_interface_collection);
622 #else
623      return FALSE;
624 #endif
625 }
626
627 /**
628  * atspi_accessible_is_component:
629  * @obj: a pointer to the #AtspiAccessible instance to query.
630  *
631  * Query whether the specified #AtspiAccessible implements #AtspiComponent.
632  *
633  * Returns: #TRUE if @obj implements the #AtspiComponent interface,
634  *          #FALSE otherwise.
635  **/
636 gboolean
637 atspi_accessible_is_component (AtspiAccessible *obj)
638 {
639   return _atspi_accessible_is_a (obj,
640                               atspi_interface_component);
641 }
642
643 /**
644  * atspi_accessible_is_document:
645  * @obj: a pointer to the #AtspiAccessible instance to query.
646  *
647  * Query whether the specified #AtspiAccessible implements #AtspiDocument.
648  *
649  * Returns: #TRUE if @obj implements the #AtspiDocument interface,
650  *          #FALSE otherwise.
651  **/
652 gboolean
653 atspi_accessible_is_document (AtspiAccessible *obj)
654 {
655   return _atspi_accessible_is_a (obj,
656                               atspi_interface_document);
657 }
658
659 /**
660  * atspi_accessible_is_editable_text:
661  * @obj: a pointer to the #AtspiAccessible instance to query.
662  *
663  * Query whether the specified #AtspiAccessible implements #AtspiEditableText.
664  *
665  * Returns: #TRUE if @obj implements the #AtspiEditableText interface,
666  *          #FALSE otherwise.
667  **/
668 gboolean
669 atspi_accessible_is_editable_text (AtspiAccessible *obj)
670 {
671   return _atspi_accessible_is_a (obj,
672                               atspi_interface_editable_text);
673 }
674                                                                                                                                                                         
675 /**
676  * atspi_accessible_is_hypertext:
677  * @obj: a pointer to the #AtspiAccessible instance to query.
678  *
679  * Query whether the specified #AtspiAccessible implements #AtspiHypertext.
680  *
681  * Returns: #TRUE if @obj implements the #AtspiHypertext interface,
682  *          #FALSE otherwise.
683  **/
684 gboolean
685 atspi_accessible_is_hypertext (AtspiAccessible *obj)
686 {
687   return _atspi_accessible_is_a (obj,
688                               atspi_interface_hypertext);
689 }
690
691 /**
692  * atspi_accessible_is_image:
693  * @obj: a pointer to the #AtspiAccessible instance to query.
694  *
695  * Query whether the specified #AtspiAccessible implements #AtspiImage.
696  *
697  * Returns: #TRUE if @obj implements the #AtspiImage interface,
698  *          #FALSE otherwise.
699 **/
700 gboolean
701 atspi_accessible_is_image (AtspiAccessible *obj)
702 {
703   return _atspi_accessible_is_a (obj,
704                               atspi_interface_image);
705 }
706
707 /**
708  * atspi_accessible_is_selection:
709  * @obj: a pointer to the #AtspiAccessible instance to query.
710  *
711  * Query whether the specified #AtspiAccessible implements #AtspiSelection.
712  *
713  * Returns: #TRUE if @obj implements the #AtspiSelection interface,
714  *          #FALSE otherwise.
715 **/
716 gboolean
717 atspi_accessible_is_selection (AtspiAccessible *obj)
718 {
719   return _atspi_accessible_is_a (obj,
720                               atspi_interface_selection);
721 }
722
723 /**
724  * atspi_accessible_is_table:
725  * @obj: a pointer to the #AtspiAccessible instance to query.
726  *
727  * Query whether the specified #AtspiAccessible implements #AtspiTable.
728  *
729  * Returns: #TRUE if @obj implements the #AtspiTable interface,
730  *          #FALSE otherwise.
731 **/
732 gboolean
733 atspi_accessible_is_table (AtspiAccessible *obj)
734 {
735   return _atspi_accessible_is_a (obj,
736                               atspi_interface_table);
737 }
738
739 /**
740  * atspi_accessible_is_streamable_content:
741  * @obj: a pointer to the #AtspiAccessible instance to query.
742  *
743  * Query whether the specified #AtspiAccessible implements
744  *          #AtspiStreamableContent.
745  *
746  * Returns: #TRUE if @obj implements the #AtspiStreamableContent interface,
747  *          #FALSE otherwise.
748 **/
749 gboolean
750 atspi_accessible_is_streamable_content (AtspiAccessible *obj)
751 {
752 #if 0
753   return _atspi_accessible_is_a (obj,
754                               atspi_interface_streamable_content);
755 #else
756   g_warning ("Streamable content not implemented");
757   return FALSE;
758 #endif
759 }
760
761 /**
762  * atspi_accessible_is_text:
763  * @obj: a pointer to the #AtspiAccessible instance to query.
764  *
765  * Query whether the specified #AtspiAccessible implements #AtspiText.
766  *
767  * Returns: #TRUE if @obj implements the #AtspiText interface,
768  *          #FALSE otherwise.
769 **/
770 gboolean
771 atspi_accessible_is_text (AtspiAccessible *obj)
772 {
773   return _atspi_accessible_is_a (obj,
774                               atspi_interface_text);
775 }
776
777 /**
778  * atspi_accessible_is_value:
779  * @obj: a pointer to the #AtspiAccessible instance to query.
780  *
781  * Query whether the specified #AtspiAccessible implements #AtspiValue.
782  *
783  * Returns: #TRUE if @obj implements the #AtspiValue interface,
784  *          #FALSE otherwise.
785 **/
786 gboolean
787 atspi_accessible_is_value (AtspiAccessible *obj)
788 {
789   return _atspi_accessible_is_a (obj,
790                               atspi_interface_value);
791 }
792
793 /**
794  * atspi_accessible_get_application:
795  * @obj: a pointer to the #AtspiAccessible instance to query.
796  *
797  * Get the #AtspiApplication interface for an #AtspiAccessible.
798  *
799  * Returns: a pointer to an #AtspiApplication interface instance, or
800  *          NULL if @obj does not implement #AtspiApplication.
801  **/
802 AtspiApplication *
803 atspi_accessible_get_application (AtspiAccessible *accessible)
804 {
805   return (_atspi_accessible_is_a (accessible, atspi_interface_application) ?
806           g_object_ref (ATSPI_ACTION (accessible)) : NULL);  
807 }
808
809 #if 0
810 /**
811  * atspi_accessible_get_action:
812  * @obj: a pointer to the #AtspiAccessible instance to query.
813  *
814  * Get the #AtspiAction interface for an #AtspiAccessible.
815  *
816  * Returns: (transfer full): a pointer to an #AtspiAction interface
817  *          instance, or NULL if @obj does not implement #AtspiAction.
818  **/
819 AtspiAction *
820 atspi_accessible_get_action (AtspiAccessible *accessible)
821 {
822   return (_atspi_accessible_is_a (accessible, atspi_interface_action) ?
823           accessible : NULL);  
824 }
825
826 /**
827  * atspi_accessible_get_collection:
828  * @obj: a pointer to the #AtspiAccessible instance to query.
829  *
830  * Get the #AtspiCollection interface for an #AtspiAccessible.
831  *
832  * Returns: (transfer full): a pointer to an #AtspiCollection interface
833  *          instance, or NULL if @obj does not implement #AtspiCollection.
834  **/
835 AtspiCollection *
836 atspi_accessible_get_collection (AtspiAccessible *accessible)
837 {
838   return (_atspi_accessible_is_a (accessible, atspi_interface_collection) ?
839           accessible : NULL);  
840 }
841 #endif
842
843 /**
844  * atspi_accessible_get_component:
845  * @obj: a pointer to the #AtspiAccessible instance to query.
846  *
847  * Get the #AtspiComponent interface for an #AtspiAccessible.
848  *
849  * Returns: (transfer full): a pointer to an #AtspiComponent interface
850  *          instance, or NULL if @obj does not implement #AtspiComponent.
851  **/
852 AtspiComponent *
853 atspi_accessible_get_component (AtspiAccessible *obj)
854 {
855   return (_atspi_accessible_is_a (obj, atspi_interface_component) ?
856           g_object_ref (ATSPI_COMPONENT (obj)) : NULL);
857 }
858
859 /**
860  * atspi_accessible_get_document:
861  * @obj: a pointer to the #AtspiAccessible instance to query.
862  *
863  * Get the #AtspiDocument interface for an #AtspiAccessible.
864  *
865  * Returns: (transfer full): a pointer to an #AtspiDocument interface
866  *          instance, or NULL if @obj does not implement #AtspiDocument.
867  **/
868 AtspiDocument *
869 atspi_accessible_get_document (AtspiAccessible *accessible)
870 {
871   return (_atspi_accessible_is_a (accessible, atspi_interface_document) ?
872           g_object_ref (ATSPI_DOCUMENT (accessible)) : NULL);  
873 }
874
875 /**
876  * atspi_accessible_get_editable_text:
877  * @obj: a pointer to the #AtspiAccessible instance to query.
878  *
879  * Get the #AtspiEditableText interface for an #AtspiAccessible.
880  *
881  * Returns: (transfer full): a pointer to an #AtspiEditableText interface
882  *          instance, or NULL if @obj does not implement #AtspiEditableText.
883  **/
884 AtspiEditableText *
885 atspi_accessible_get_editable_text (AtspiAccessible *accessible)
886 {
887   return (_atspi_accessible_is_a (accessible, atspi_interface_editable_text) ?
888           g_object_ref (ATSPI_EDITABLE_TEXT (accessible)) : NULL);  
889 }
890
891 /**
892  * atspi_accessible_get_hypertext:
893  * @obj: a pointer to the #AtspiAccessible instance to query.
894  *
895  * Get the #AtspiHypertext interface for an #AtspiAccessible.
896  *
897  * Returns: (transfer full): a pointer to an #AtspiHypertext interface
898  *          instance, or NULL if @obj does not implement #AtspiHypertext.
899  **/
900 AtspiHypertext *
901 atspi_accessible_get_hypertext (AtspiAccessible *accessible)
902 {
903   return (_atspi_accessible_is_a (accessible, atspi_interface_hypertext) ?
904           g_object_ref (ATSPI_HYPERTEXT (accessible)) : NULL);  
905 }
906
907 /**
908  * atspi_accessible_get_image:
909  * @obj: a pointer to the #AtspiAccessible instance to query.
910  *
911  * Get the #AtspiImage interface for an #AtspiAccessible.
912  *
913  * Returns: (transfer full): a pointer to an #AtspiImage interface instance, or
914  *          NULL if @obj does not implement #AtspiImage.
915  **/
916 AtspiImage *
917 atspi_accessible_get_image (AtspiAccessible *accessible)
918 {
919   return (_atspi_accessible_is_a (accessible, atspi_interface_image) ?
920           g_object_ref (ATSPI_IMAGE (accessible)) : NULL);  
921 }
922
923 /**
924  * atspi_accessible_get_selection:
925  * @obj: a pointer to the #AtspiAccessible instance to query.
926  *
927  * Get the #AtspiSelection interface for an #AtspiAccessible.
928  *
929  * Returns: (transfer full): a pointer to an #AtspiSelection interface
930  *          instance, or NULL if @obj does not implement #AtspiSelection.
931  **/
932 AtspiSelection *
933 atspi_accessible_get_selection (AtspiAccessible *accessible)
934 {
935   return (_atspi_accessible_is_a (accessible, atspi_interface_selection) ?
936           g_object_ref (ATSPI_SELECTION (accessible)) : NULL);  
937 }
938
939 #if 0
940 /**
941  * atspi_accessible_get_streamable_content:
942  * @obj: a pointer to the #AtspiAccessible instance to query.
943  *
944  * Get the #AtspiStreamableContent interface for an #AtspiAccessible.
945  *
946  * Returns: (transfer full): a pointer to an #AtspiStreamableContent interface
947  *          instance, or NULL if @obj does not implement #AtspiStreamableContent.
948  **/
949 AtspiStreamableContent *
950 atspi_accessible_get_streamable_content (AtspiAccessible *accessible)
951 {
952   return (_atspi_accessible_is_a (accessible, atspi_interface_streamable_content) ?
953           accessible : NULL);  
954 }
955 #endif
956
957 /**
958  * atspi_accessible_get_table:
959  * @obj: a pointer to the #AtspiAccessible instance to query.
960  *
961  * Get the #AtspiTable interface for an #AtspiAccessible.
962  *
963  * Returns: (transfer full): a pointer to an #AtspiTable interface instance, or
964  *          NULL if @obj does not implement #AtspiTable.
965  **/
966 AtspiTable *
967 atspi_accessible_get_table (AtspiAccessible *obj)
968 {
969   return (_atspi_accessible_is_a (obj, atspi_interface_table) ?
970           g_object_ref (ATSPI_TABLE (obj)) : NULL);  
971 }
972
973 /**
974  * atspi_accessible_get_text:
975  * @obj: a pointer to the #AtspiAccessible instance to query.
976  *
977  * Get the #AtspiTable interface for an #AtspiAccessible.
978  *
979  * Returns: (transfer full): a pointer to an #AtspiText interface instance, or
980  *          NULL if @obj does not implement #AtspiTable.
981  **/
982 AtspiText *
983 atspi_accessible_get_text (AtspiAccessible *obj)
984 {
985   return (_atspi_accessible_is_a (obj, atspi_interface_text) ?
986           g_object_ref (ATSPI_TEXT (obj)) : NULL);
987 }
988
989 /**
990  * atspi_accessible_get_value:
991  * @obj: a pointer to the #AtspiAccessible instance to query.
992  *
993  * Get the #AtspiTable interface for an #AtspiAccessible.
994  *
995  * Returns: (transfer full): a pointer to an #AtspiValue interface instance, or
996  *          NULL if @obj does not implement #AtspiValue.
997  **/
998 AtspiValue *
999 atspi_accessible_get_value (AtspiAccessible *accessible)
1000 {
1001   return (_atspi_accessible_is_a (accessible, atspi_interface_value) ?
1002           g_object_ref (ATSPI_VALUE (accessible)) : NULL);  
1003 }
1004
1005 #if 0
1006 static gboolean
1007 cspi_init_relation_type_table (AccessibleRelationType *relation_type_table)
1008 {
1009   int i;
1010   for (i = 0; i < Accessibility_RELATION_LAST_DEFINED; ++i)
1011     {
1012       relation_type_table [i] = SPI_RELATION_NULL;
1013     }
1014   relation_type_table [Accessibility_RELATION_NULL] = SPI_RELATION_NULL;
1015   relation_type_table [Accessibility_RELATION_LABEL_FOR] = SPI_RELATION_LABEL_FOR;
1016   relation_type_table [Accessibility_RELATION_LABELLED_BY] = SPI_RELATION_LABELED_BY;
1017   relation_type_table [Accessibility_RELATION_CONTROLLER_FOR] = SPI_RELATION_CONTROLLER_FOR;
1018   relation_type_table [Accessibility_RELATION_CONTROLLED_BY] = SPI_RELATION_CONTROLLED_BY;
1019   relation_type_table [Accessibility_RELATION_MEMBER_OF] = SPI_RELATION_MEMBER_OF;
1020   relation_type_table [Accessibility_RELATION_TOOLTIP_FOR] = SPI_RELATION_NULL;
1021   relation_type_table [Accessibility_RELATION_NODE_CHILD_OF] = SPI_RELATION_NODE_CHILD_OF;
1022   relation_type_table [Accessibility_RELATION_EXTENDED] = SPI_RELATION_EXTENDED;
1023   relation_type_table [Accessibility_RELATION_FLOWS_TO] = SPI_RELATION_FLOWS_TO;
1024   relation_type_table [Accessibility_RELATION_FLOWS_FROM] = SPI_RELATION_FLOWS_FROM;
1025   relation_type_table [Accessibility_RELATION_SUBWINDOW_OF] = SPI_RELATION_SUBWINDOW_OF;
1026   relation_type_table [Accessibility_RELATION_EMBEDS] = SPI_RELATION_EMBEDS;
1027   relation_type_table [Accessibility_RELATION_EMBEDDED_BY] = SPI_RELATION_EMBEDDED_BY;
1028   relation_type_table [Accessibility_RELATION_POPUP_FOR] = SPI_RELATION_POPUP_FOR;
1029   relation_type_table [Accessibility_RELATION_PARENT_WINDOW_OF] = SPI_RELATION_PARENT_WINDOW_OF;
1030   relation_type_table [Accessibility_RELATION_DESCRIBED_BY] = SPI_RELATION_DESCRIBED_BY;
1031   relation_type_table [Accessibility_RELATION_DESCRIPTION_FOR] = SPI_RELATION_DESCRIPTION_FOR;
1032   return TRUE;
1033 }
1034
1035 static AccessibleRelationType
1036 cspi_relation_type_from_spi_relation_type (Accessibility_RelationType type)
1037 {
1038   /* array is sized according to IDL RelationType because IDL RelationTypes are the index */    
1039   static AccessibleRelationType cspi_relation_type_table [Accessibility_RELATION_LAST_DEFINED];
1040   static gboolean is_initialized = FALSE;
1041   AccessibleRelationType cspi_type;
1042   if (!is_initialized)
1043     {
1044       is_initialized = cspi_init_relation_type_table (cspi_relation_type_table);            
1045     }
1046   if (type >= 0 && type < Accessibility_RELATION_LAST_DEFINED)
1047     {
1048       cspi_type = cspi_relation_type_table [type];          
1049     }
1050   else
1051     {
1052       cspi_type = SPI_RELATION_NULL;
1053     }
1054   return cspi_type; 
1055 }
1056 /**
1057  * AccessibleRelation_getRelationType:
1058  * @obj: a pointer to the #AtspiAccessibleRelation object to query.
1059  *
1060  * Get the type of relationship represented by an #AtspiAccessibleRelation.
1061  *
1062  * Returns: an #AtspiAccessibleRelationType indicating the type of relation
1063  *         encapsulated in this #AtspiAccessibleRelation object.
1064  *
1065  **/
1066 AccessibleRelationType
1067 AccessibleRelation_getRelationType (AccessibleRelation *obj)
1068 {
1069   cspi_return_val_if_fail (obj, SPI_RELATION_NULL);
1070   return cspi_relation_type_from_spi_relation_type (obj->type);
1071 }
1072
1073 /**
1074  * AccessibleRelation_getNTargets:
1075  * @obj: a pointer to the #AtspiAccessibleRelation object to query.
1076  *
1077  * Get the number of objects which this relationship has as its
1078  *       target objects (the subject is the #AtspiAccessible from which this
1079  *       #AtspiAccessibleRelation originated).
1080  *
1081  * Returns: a short integer indicating how many target objects which the
1082  *       originating #AtspiAccessible object has the #AtspiAccessibleRelation
1083  *       relationship with.
1084  **/
1085 int
1086 AccessibleRelation_getNTargets (AccessibleRelation *obj)
1087 {
1088   cspi_return_val_if_fail (obj, -1);
1089   return obj->targets->len;
1090 }
1091
1092 /**
1093  * AccessibleRelation_getTarget:
1094  * @obj: a pointer to the #AtspiAccessibleRelation object to query.
1095  * @i: a (zero-index) integer indicating which (of possibly several) target is requested.
1096  *
1097  * Get the @i-th target of a specified #AtspiAccessibleRelation relationship.
1098  *
1099  * Returns: an #AtspiAccessible which is the @i-th object with which the
1100  *      originating #AtspiAccessible has relationship specified in the
1101  *      #AtspiAccessibleRelation object.
1102  *
1103  **/
1104 Accessible *
1105 AccessibleRelation_getTarget (AccessibleRelation *obj, int i)
1106 {
1107   cspi_return_val_if_fail (obj, NULL);
1108
1109   if (i < 0 || i >= obj->targets->len) return NULL;
1110   return cspi_object_add (
1111                          g_array_index (obj->targets, Accessible *, i));
1112 }
1113
1114 /**
1115  * AccessibleStateSet_ref:
1116  * @obj: a pointer to the #AtspiAccessibleStateSet object on which to operate.
1117  *
1118  * Increment the reference count for an #AtspiAccessibleStateSet object.
1119  *
1120  **/
1121 void
1122 AccessibleStateSet_ref (AccessibleStateSet *obj)
1123 {
1124   spi_state_set_cache_ref (obj);
1125 }
1126
1127 /**
1128  * AccessibleStateSet_unref:
1129  * @obj: a pointer to the #AtspiAccessibleStateSet object on which to operate.
1130  *
1131  * Decrement the reference count for an #AtspiAccessibleStateSet object.
1132  *
1133  **/
1134 void
1135 AccessibleStateSet_unref (AccessibleStateSet *obj)
1136 {
1137   spi_state_set_cache_unref (obj);
1138 }
1139
1140 static Accessibility_StateType
1141 spi_state_to_dbus (AccessibleState state)
1142 {
1143 #define MAP_STATE(a) \
1144   case SPI_STATE_##a: \
1145     return Accessibility_STATE_##a
1146
1147   switch (state)
1148     {
1149       MAP_STATE (INVALID);
1150       MAP_STATE (ACTIVE);
1151       MAP_STATE (ARMED);
1152       MAP_STATE (BUSY);
1153       MAP_STATE (CHECKED);
1154       MAP_STATE (DEFUNCT);
1155       MAP_STATE (EDITABLE);
1156       MAP_STATE (ENABLED);
1157       MAP_STATE (EXPANDABLE);
1158       MAP_STATE (EXPANDED);
1159       MAP_STATE (FOCUSABLE);
1160       MAP_STATE (FOCUSED);
1161       MAP_STATE (HORIZONTAL);
1162       MAP_STATE (ICONIFIED);
1163       MAP_STATE (MODAL);
1164       MAP_STATE (MULTI_LINE);
1165       MAP_STATE (MULTISELECTABLE);
1166       MAP_STATE (OPAQUE);
1167       MAP_STATE (PRESSED);
1168       MAP_STATE (RESIZABLE);
1169       MAP_STATE (SELECTABLE);
1170       MAP_STATE (SELECTED);
1171       MAP_STATE (SENSITIVE);
1172       MAP_STATE (SHOWING);
1173       MAP_STATE (SINGLE_LINE);
1174       MAP_STATE (STALE);
1175       MAP_STATE (TRANSIENT);
1176       MAP_STATE (VERTICAL);
1177       MAP_STATE (VISIBLE);
1178       MAP_STATE (MANAGES_DESCENDANTS);
1179       MAP_STATE (INDETERMINATE);
1180       MAP_STATE (TRUNCATED);
1181       MAP_STATE (REQUIRED);
1182       MAP_STATE (INVALID_ENTRY);
1183       MAP_STATE (SUPPORTS_AUTOCOMPLETION);
1184       MAP_STATE (SELECTABLE_TEXT);
1185       MAP_STATE (IS_DEFAULT);
1186       MAP_STATE (VISITED);
1187     default:
1188       return Accessibility_STATE_INVALID;
1189   }
1190 #undef MAP_STATE
1191 }             
1192
1193 /**
1194  * AccessibleStateSet_contains:
1195  * @obj: a pointer to the #AtspiAccessibleStateSet object on which to operate.
1196  * @state: an #AtspiAccessibleState for which the specified #AtspiAccessibleStateSet
1197  *       will be queried.
1198  *
1199  * Determine whether a given #AtspiAccessibleStateSet includes a given state; that is,
1200  *       whether @state is true for the stateset in question.
1201  *
1202  * Returns: #TRUE if @state is true/included in the given #AtspiAccessibleStateSet,
1203  *          otherwise #FALSE.
1204  *
1205  **/
1206 gboolean
1207 AccessibleStateSet_contains (AccessibleStateSet *obj,
1208                              AccessibleState state)
1209 {
1210   return spi_state_set_cache_contains (obj, spi_state_to_dbus (state));
1211 }
1212
1213 /**
1214  * AccessibleStateSet_add:
1215  * @obj: a pointer to the #AtspiAccessibleStateSet object on which to operate.
1216  * @state: an #AtspiAccessibleState to be added to the specified #AtspiAccessibleStateSet
1217  *
1218  * Add a particular #AtspiAccessibleState to an #AtspiAccessibleStateSet (i.e. set the
1219  *       given state to #TRUE in the stateset.
1220  *
1221  **/
1222 void
1223 AccessibleStateSet_add (AccessibleStateSet *obj,
1224                         AccessibleState state)
1225 {
1226   spi_state_set_cache_add (obj, spi_state_to_dbus (state));
1227 }
1228
1229 /**
1230  * AccessibleStateSet_remove:
1231  * @obj: a pointer to the #AtspiAccessibleStateSet object on which to operate.
1232  * @state: an #AtspiAccessibleState to be removed from the specified #AtspiAccessibleStateSet
1233  *
1234  * Remove a particular #AtspiAccessibleState to an #AtspiAccessibleStateSet (i.e. set the
1235  *       given state to #FALSE in the stateset.)
1236  *
1237  **/
1238 void
1239 AccessibleStateSet_remove (AccessibleStateSet *obj,
1240                            AccessibleState state)
1241 {
1242   spi_state_set_cache_remove (obj, spi_state_to_dbus (state));
1243 }
1244
1245 /**
1246  * AccessibleStateSet_equals:
1247  * @obj: a pointer to the first #AtspiAccessibleStateSet object on which to operate.
1248  * @obj2: a pointer to the second #AtspiAccessibleStateSet object on which to operate.
1249  *
1250  * Determine whether two instances of #AtspiAccessibleStateSet are equivalent (i.e.
1251  *         consist of the same #AtspiAccessibleStates).  Useful for checking multiple
1252  *         state variables at once; construct the target state then compare against it.
1253  *
1254  * @see AccessibleStateSet_compare().
1255  *
1256  * Returns: #TRUE if the two #AtspiAccessibleStateSets are equivalent,
1257  *          otherwise #FALSE.
1258  *
1259  **/
1260 gboolean
1261 AccessibleStateSet_equals (AccessibleStateSet *obj,
1262                            AccessibleStateSet *obj2)
1263 {
1264   gboolean   eq;
1265   AtkStateSet *cmp;
1266
1267   if (obj == obj2)
1268     {
1269       return TRUE;
1270     }
1271
1272   cmp = spi_state_set_cache_xor (obj, obj2);
1273   eq = spi_state_set_cache_is_empty (cmp);
1274   spi_state_set_cache_unref (cmp);
1275
1276   return eq;
1277 }
1278
1279 /**
1280  * AccessibleStateSet_compare:
1281  * @obj: a pointer to the first #AtspiAccessibleStateSet object on which to operate.
1282  * @obj2: a pointer to the second #AtspiAccessibleStateSet object on which to operate.
1283  *
1284  * Determine the differences between two instances of #AtspiAccessibleStateSet.
1285  * Not Yet Implemented.
1286  *.
1287  * @see AccessibleStateSet_equals().
1288  *
1289  * Returns: an #AtspiAccessibleStateSet object containing all states contained on one of
1290  *          the two sets but not the other.
1291  *
1292  **/
1293 AccessibleStateSet *
1294 AccessibleStateSet_compare (AccessibleStateSet *obj,
1295                             AccessibleStateSet *obj2)
1296 {
1297   return spi_state_set_cache_xor (obj, obj2);
1298 }
1299
1300 /**
1301  * AccessibleStateSet_isEmpty:
1302  * @obj: a pointer to the #AtspiAccessibleStateSet object on which to operate.
1303  *
1304  * Determine whether a given #AtspiAccessibleStateSet is the empty set.
1305  *
1306  * Returns: #TRUE if the given #AtspiAccessibleStateSet contains no (true) states,
1307  *          otherwise #FALSE.
1308  *
1309  **/
1310 gboolean
1311 AccessibleStateSet_isEmpty (AccessibleStateSet *obj)
1312 {
1313   return spi_state_set_cache_is_empty (obj);
1314 }
1315 #endif
1316
1317 gboolean
1318 _atspi_accessible_is_a (AtspiAccessible *accessible,
1319                       const char *interface_name)
1320 {
1321   int n;
1322
1323   if (accessible == NULL)
1324     {
1325       return FALSE;
1326     }
1327
1328   n = _atspi_get_iface_num (interface_name);
1329   if (n == -1) return FALSE;
1330   return (gboolean) ((accessible->interfaces & (1 << n))? TRUE: FALSE);
1331 }
1332
1333 /* TODO: Move to a finalizer */
1334 static void
1335 cspi_object_destroyed (AtspiAccessible *accessible)
1336 {
1337   gboolean cached;
1338   AtspiEvent e;
1339
1340   /* TODO: Only fire if object not already marked defunct */
1341   memset (&e, 0, sizeof (e));
1342   e.type = "object:state-change:defunct";
1343   e.source = accessible;
1344   e.detail1 = 1;
1345   e.detail2 = 0;
1346   _atspi_send_event (&e);
1347
1348     g_free (accessible->parent.path);
1349
1350     if (accessible->states)
1351       g_object_unref (accessible->states);
1352     g_free (accessible->description);
1353     g_free (accessible->name);
1354 }
1355
1356 AtspiAccessible *
1357 atspi_accessible_new (AtspiApplication *app, const gchar *path)
1358 {
1359   AtspiAccessible *accessible;
1360   
1361   accessible = g_object_new (ATSPI_TYPE_ACCESSIBLE, NULL);
1362   g_return_val_if_fail (accessible != NULL, NULL);
1363
1364   accessible->parent.app = g_object_ref (app);
1365   accessible->parent.path = g_strdup (path);
1366
1367   return accessible;
1368 }