summaryrefslogtreecommitdiff
path: root/atk/atkobject.c
diff options
context:
space:
mode:
Diffstat (limited to 'atk/atkobject.c')
-rw-r--r--atk/atkobject.c1514
1 files changed, 1514 insertions, 0 deletions
diff --git a/atk/atkobject.c b/atk/atkobject.c
new file mode 100644
index 0000000000..7ece1754f5
--- /dev/null
+++ b/atk/atkobject.c
@@ -0,0 +1,1514 @@
+/* ATK - Accessibility Toolkit
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <locale.h>
+
+#include <glib-object.h>
+#include <glib/gi18n-lib.h>
+
+#include "atk.h"
+#include "atkmarshal.h"
+#include "atkprivate.h"
+
+/**
+ * SECTION:atkobject
+ * @Short_description: The base object class for the Accessibility Toolkit API.
+ * @Title:AtkObject
+ *
+ * This class is the primary class for accessibility support via the
+ * Accessibility ToolKit (ATK). Objects which are instances of
+ * #AtkObject (or instances of AtkObject-derived types) are queried
+ * for properties which relate basic (and generic) properties of a UI
+ * component such as name and description. Instances of #AtkObject
+ * may also be queried as to whether they implement other ATK
+ * interfaces (e.g. #AtkAction, #AtkComponent, etc.), as appropriate
+ * to the role which a given UI component plays in a user interface.
+ *
+ * All UI components in an application which provide useful
+ * information or services to the user must provide corresponding
+ * #AtkObject instances on request (in GTK+, for instance, usually on
+ * a call to #gtk_widget_get_accessible ()), either via ATK support
+ * built into the toolkit for the widget class or ancestor class, or
+ * in the case of custom widgets, if the inherited #AtkObject
+ * implementation is insufficient, via instances of a new #AtkObject
+ * subclass.
+ *
+ * See also: #AtkObjectFactory, #AtkRegistry. (GTK+ users see also
+ * #GtkAccessible).
+ *
+ */
+
+static GPtrArray *role_names = NULL;
+
+enum
+{
+ PROP_0, /* gobject convention */
+
+ PROP_NAME,
+ PROP_DESCRIPTION,
+ PROP_PARENT, /* ancestry has changed */
+ PROP_ROLE,
+ PROP_LAYER,
+ PROP_MDI_ZORDER,
+ PROP_TABLE_SUMMARY,
+ PROP_TABLE_CAPTION_OBJECT,
+ PROP_HYPERTEXT_NUM_LINKS,
+ PROP_ACCESSIBLE_ID,
+ PROP_LAST /* gobject convention */
+};
+
+enum {
+ CHILDREN_CHANGED,
+ PROPERTY_CHANGE,
+ STATE_CHANGE,
+ VISIBLE_DATA_CHANGED,
+ ACTIVE_DESCENDANT_CHANGED,
+
+ LAST_SIGNAL
+};
+
+/* These are listed here for extraction by intltool */
+#if 0
+ N_("invalid")
+ N_("accelerator label")
+ N_("alert")
+ N_("animation")
+ N_("arrow")
+ N_("calendar")
+ N_("canvas")
+ N_("check box")
+ N_("check menu item")
+ N_("color chooser")
+ N_("column header")
+ N_("combo box")
+ N_("dateeditor")
+ N_("desktop icon")
+ N_("desktop frame")
+ N_("dial")
+ N_("dialog")
+ N_("directory pane")
+ N_("drawing area")
+ N_("file chooser")
+ N_("filler")
+ /* I know it looks wrong but that is what Java returns */
+ N_("fontchooser")
+ N_("frame")
+ N_("glass pane")
+ N_("html container")
+ N_("icon")
+ N_("image")
+ N_("internal frame")
+ N_("label")
+ N_("layered pane")
+ N_("list")
+ N_("list item")
+ N_("menu")
+ N_("menu bar")
+ N_("menu item")
+ N_("option pane")
+ N_("page tab")
+ N_("page tab list")
+ N_("panel")
+ N_("password text")
+ N_("popup menu")
+ N_("progress bar")
+ N_("push button")
+ N_("radio button")
+ N_("radio menu item")
+ N_("root pane")
+ N_("row header")
+ N_("scroll bar")
+ N_("scroll pane")
+ N_("separator")
+ N_("slider")
+ N_("split pane")
+ N_("spin button")
+ N_("statusbar")
+ N_("table")
+ N_("table cell")
+ N_("table column header")
+ N_("table row header")
+ N_("tear off menu item")
+ N_("terminal")
+ N_("text")
+ N_("toggle button")
+ N_("tool bar")
+ N_("tool tip")
+ N_("tree")
+ N_("tree table")
+ N_("unknown")
+ N_("viewport")
+ N_("window")
+ N_("header")
+ N_("footer")
+ N_("paragraph")
+ N_("ruler")
+ N_("application")
+ N_("autocomplete")
+ N_("edit bar")
+ N_("embedded component")
+ N_("entry")
+ N_("chart")
+ N_("caption")
+ N_("document frame")
+ N_("heading")
+ N_("page")
+ N_("section")
+ N_("redundant object")
+ N_("form")
+ N_("link")
+ N_("input method window")
+ N_("table row")
+ N_("tree item")
+ N_("document spreadsheet")
+ N_("document presentation")
+ N_("document text")
+ N_("document web")
+ N_("document email")
+ N_("comment")
+ N_("list box")
+ N_("grouping")
+ N_("image map")
+ N_("notification")
+ N_("info bar")
+ N_("level bar")
+ N_("title bar")
+ N_("block quote")
+ N_("audio")
+ N_("video")
+ N_("definition")
+ N_("article")
+ N_("landmark")
+ N_("log")
+ N_("marquee")
+ N_("math")
+ N_("rating")
+ N_("timer")
+ N_("description list")
+ N_("description term")
+ N_("description value")
+#endif /* 0 */
+
+typedef struct {
+ gchar *accessible_id;
+} AtkObjectPrivate;
+
+static gint AtkObject_private_offset;
+
+static void atk_object_class_init (AtkObjectClass *klass);
+static void atk_object_init (AtkObject *accessible,
+ AtkObjectClass *klass);
+static AtkRelationSet* atk_object_real_ref_relation_set
+ (AtkObject *accessible);
+static void atk_object_real_initialize (AtkObject *accessible,
+ gpointer data);
+static void atk_object_real_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void atk_object_real_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void atk_object_finalize (GObject *object);
+static const gchar* atk_object_real_get_name (AtkObject *object);
+static const gchar* atk_object_real_get_description
+ (AtkObject *object);
+static AtkObject* atk_object_real_get_parent (AtkObject *object);
+static AtkRole atk_object_real_get_role (AtkObject *object);
+static AtkLayer atk_object_real_get_layer (AtkObject *object);
+static AtkStateSet* atk_object_real_ref_state_set
+ (AtkObject *object);
+static void atk_object_real_set_name (AtkObject *object,
+ const gchar *name);
+static void atk_object_real_set_description
+ (AtkObject *object,
+ const gchar *description);
+static void atk_object_real_set_parent (AtkObject *object,
+ AtkObject *parent);
+static void atk_object_real_set_role (AtkObject *object,
+ AtkRole role);
+static void atk_object_notify (GObject *obj,
+ GParamSpec *pspec);
+static const gchar* atk_object_real_get_object_locale
+ (AtkObject *object);
+
+static guint atk_object_signals[LAST_SIGNAL] = { 0, };
+
+static gpointer parent_class = NULL;
+
+static const gchar* const atk_object_name_property_name = "accessible-name";
+static const gchar* const atk_object_name_property_description = "accessible-description";
+static const gchar* const atk_object_name_property_parent = "accessible-parent";
+static const gchar* const atk_object_name_property_role = "accessible-role";
+static const gchar* const atk_object_name_property_component_layer = "accessible-component-layer";
+static const gchar* const atk_object_name_property_component_mdi_zorder = "accessible-component-mdi-zorder";
+static const gchar* const atk_object_name_property_table_summary = "accessible-table-summary";
+static const gchar* const atk_object_name_property_table_caption_object = "accessible-table-caption-object";
+static const gchar* const atk_object_name_property_hypertext_num_links = "accessible-hypertext-nlinks";
+
+static void
+initialize_role_names ()
+{
+ GTypeClass *enum_class;
+ GEnumValue *enum_value;
+ int i;
+ gchar *role_name = NULL;
+
+ if (role_names)
+ return;
+
+ role_names = g_ptr_array_new ();
+ enum_class = g_type_class_ref (ATK_TYPE_ROLE);
+ if (!G_IS_ENUM_CLASS(enum_class))
+ return;
+
+ for (i = 0; i < ATK_ROLE_LAST_DEFINED; i++)
+ {
+ enum_value = g_enum_get_value (G_ENUM_CLASS (enum_class), i);
+ role_name = g_strdup (enum_value->value_nick);
+ // We want the role names to be in the format "check button" and not "check-button"
+ _compact_name (role_name);
+ g_ptr_array_add (role_names, role_name);
+ }
+
+ g_type_class_unref (enum_class);
+
+}
+
+GType
+atk_object_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type)
+ {
+ static const GTypeInfo typeInfo =
+ {
+ sizeof (AtkObjectClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) atk_object_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL,
+ sizeof (AtkObject),
+ 0,
+ (GInstanceInitFunc) atk_object_init,
+ } ;
+ type = g_type_register_static (G_TYPE_OBJECT, "AtkObject", &typeInfo, 0) ;
+
+ AtkObject_private_offset =
+ g_type_add_instance_private (type, sizeof (AtkObjectPrivate));
+ }
+ return type;
+}
+
+static inline gpointer
+atk_object_get_instance_private (AtkObject *self)
+{
+ return (G_STRUCT_MEMBER_P (self, AtkObject_private_offset));
+}
+
+static void
+atk_object_class_init (AtkObjectClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ if (AtkObject_private_offset != 0)
+ g_type_class_adjust_private_offset (klass, &AtkObject_private_offset);
+
+ gobject_class->set_property = atk_object_real_set_property;
+ gobject_class->get_property = atk_object_real_get_property;
+ gobject_class->finalize = atk_object_finalize;
+ gobject_class->notify = atk_object_notify;
+
+ klass->get_name = atk_object_real_get_name;
+ klass->get_description = atk_object_real_get_description;
+ klass->get_parent = atk_object_real_get_parent;
+ klass->get_n_children = NULL;
+ klass->ref_child = NULL;
+ klass->get_index_in_parent = NULL;
+ klass->ref_relation_set = atk_object_real_ref_relation_set;
+ klass->get_role = atk_object_real_get_role;
+ klass->get_layer = atk_object_real_get_layer;
+ klass->get_mdi_zorder = NULL;
+ klass->initialize = atk_object_real_initialize;
+ klass->ref_state_set = atk_object_real_ref_state_set;
+ klass->set_name = atk_object_real_set_name;
+ klass->set_description = atk_object_real_set_description;
+ klass->set_parent = atk_object_real_set_parent;
+ klass->set_role = atk_object_real_set_role;
+ klass->get_object_locale = atk_object_real_get_object_locale;
+
+ /*
+ * We do not define default signal handlers here
+ */
+ klass->children_changed = NULL;
+ klass->focus_event = NULL;
+ klass->property_change = NULL;
+ klass->visible_data_changed = NULL;
+ klass->active_descendant_changed = NULL;
+
+ _gettext_initialization ();
+
+ g_object_class_install_property (gobject_class,
+ PROP_NAME,
+ g_param_spec_string (atk_object_name_property_name,
+ _("Accessible Name"),
+ _("Object instance’s name formatted for assistive technology access"),
+ NULL,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (gobject_class,
+ PROP_DESCRIPTION,
+ g_param_spec_string (atk_object_name_property_description,
+ _("Accessible Description"),
+ _("Description of an object, formatted for assistive technology access"),
+ NULL,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (gobject_class,
+ PROP_PARENT,
+ g_param_spec_object (atk_object_name_property_parent,
+ _("Accessible Parent"),
+ _("Parent of the current accessible as returned by atk_object_get_parent()"),
+ ATK_TYPE_OBJECT,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_ROLE,
+ g_param_spec_enum (atk_object_name_property_role,
+ _("Accessible Role"),
+ _("The accessible role of this object"),
+ ATK_TYPE_ROLE,
+ ATK_ROLE_UNKNOWN,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (gobject_class,
+ PROP_LAYER,
+ g_param_spec_int (atk_object_name_property_component_layer,
+ _("Accessible Layer"),
+ _("The accessible layer of this object"),
+ 0,
+ G_MAXINT,
+ 0,
+ G_PARAM_READABLE));
+ g_object_class_install_property (gobject_class,
+ PROP_MDI_ZORDER,
+ g_param_spec_int (atk_object_name_property_component_mdi_zorder,
+ _("Accessible MDI Value"),
+ _("The accessible MDI value of this object"),
+ G_MININT,
+ G_MAXINT,
+ G_MININT,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_TABLE_SUMMARY,
+ g_param_spec_object (atk_object_name_property_table_summary,
+ _("Accessible Table Summary"),
+ _("Is used to notify that the table summary has changed"),
+ ATK_TYPE_OBJECT,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (gobject_class,
+ PROP_TABLE_CAPTION_OBJECT,
+ g_param_spec_object (atk_object_name_property_table_caption_object,
+ _("Accessible Table Caption Object"),
+ _("Is used to notify that the table caption has changed"),
+ ATK_TYPE_OBJECT,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (gobject_class,
+ PROP_HYPERTEXT_NUM_LINKS,
+ g_param_spec_int (atk_object_name_property_hypertext_num_links,
+ _("Number of Accessible Hypertext Links"),
+ _("The number of links which the current AtkHypertext has"),
+ 0,
+ G_MAXINT,
+ 0,
+ G_PARAM_READABLE));
+
+ /**
+ * AtkObject::children-changed:
+ * @atkobject: the object which received the signal.
+ * @arg1: The index of the added or removed child. The value can be
+ * -1. This is used if the value is not known by the implementor
+ * when the child is added/removed or irrelevant.
+ * @arg2: (type AtkObject): A gpointer to the child AtkObject which was added or
+ * removed. If the child was removed, it is possible that it is not
+ * available for the implementor. In that case this pointer can be
+ * NULL.
+ *
+ * The signal "children-changed" is emitted when a child is added or
+ * removed form an object. It supports two details: "add" and
+ * "remove"
+ */
+ atk_object_signals[CHILDREN_CHANGED] =
+ g_signal_new ("children_changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
+ G_STRUCT_OFFSET (AtkObjectClass, children_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__UINT_POINTER,
+ G_TYPE_NONE,
+ 2, G_TYPE_UINT, G_TYPE_POINTER);
+
+ /**
+ * AtkObject::property-change:
+ * @atkobject: the object which received the signal.
+ * @arg1: (type AtkPropertyValues): an #AtkPropertyValues containing the new
+ * value of the property which changed.
+ *
+ * The signal "property-change" is emitted when an object's property
+ * value changes. @arg1 contains an #AtkPropertyValues with the name
+ * and the new value of the property whose value has changed. Note
+ * that, as with GObject notify, getting this signal does not
+ * guarantee that the value of the property has actually changed; it
+ * may also be emitted when the setter of the property is called to
+ * reinstate the previous value.
+ *
+ * Toolkit implementor note: ATK implementors should use
+ * g_object_notify() to emit property-changed
+ * notifications. #AtkObject::property-changed is needed by the
+ * implementation of atk_add_global_event_listener() because GObject
+ * notify doesn't support emission hooks.
+ */
+ atk_object_signals[PROPERTY_CHANGE] =
+ g_signal_new ("property_change",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
+ G_STRUCT_OFFSET (AtkObjectClass, property_change),
+ (GSignalAccumulator) NULL, NULL,
+ g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1,
+ G_TYPE_POINTER);
+
+ /**
+ * AtkObject::state-change:
+ * @atkobject: the object which received the signal.
+ * @arg1: The name of the state which has changed
+ * @arg2: A boolean which indicates whether the state has been set or unset.
+ *
+ * The "state-change" signal is emitted when an object's state
+ * changes. The detail value identifies the state type which has
+ * changed.
+ */
+ atk_object_signals[STATE_CHANGE] =
+ g_signal_new ("state_change",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
+ G_STRUCT_OFFSET (AtkObjectClass, state_change),
+ (GSignalAccumulator) NULL, NULL,
+ atk_marshal_VOID__STRING_BOOLEAN,
+ G_TYPE_NONE, 2,
+ G_TYPE_STRING,
+ G_TYPE_BOOLEAN);
+
+ /**
+ * AtkObject::visible-data-changed:
+ * @atkobject: the object which received the signal.
+ *
+ * The "visible-data-changed" signal is emitted when the visual
+ * appearance of the object changed.
+ */
+ atk_object_signals[VISIBLE_DATA_CHANGED] =
+ g_signal_new ("visible_data_changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (AtkObjectClass, visible_data_changed),
+ (GSignalAccumulator) NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ /**
+ * AtkObject::active-descendant-changed:
+ * @atkobject: the object which received the signal.
+ * @arg1: (type AtkObject): the newly focused object.
+ *
+ * The "active-descendant-changed" signal is emitted by an object
+ * which has the state ATK_STATE_MANAGES_DESCENDANTS when the focus
+ * object in the object changes. For instance, a table will emit the
+ * signal when the cell in the table which has focus changes.
+ */
+ atk_object_signals[ACTIVE_DESCENDANT_CHANGED] =
+ g_signal_new ("active_descendant_changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
+ G_STRUCT_OFFSET (AtkObjectClass, active_descendant_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE,
+ 1, G_TYPE_POINTER);
+}
+
+static void
+atk_object_init (AtkObject *accessible,
+ AtkObjectClass *klass)
+{
+ AtkObjectPrivate *private = atk_object_get_instance_private (accessible);
+
+ accessible->name = NULL;
+ accessible->description = NULL;
+ accessible->accessible_parent = NULL;
+ accessible->relation_set = atk_relation_set_new();
+ accessible->role = ATK_ROLE_UNKNOWN;
+ private->accessible_id = NULL;
+}
+
+GType
+atk_implementor_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type)
+ {
+ static const GTypeInfo typeInfo =
+ {
+ sizeof (AtkImplementorIface),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ } ;
+
+ type = g_type_register_static (G_TYPE_INTERFACE, "AtkImplementorIface", &typeInfo, 0) ;
+ }
+
+ return type;
+}
+
+/**
+ * atk_object_get_name:
+ * @accessible: an #AtkObject
+ *
+ * Gets the accessible name of the accessible.
+ *
+ * Returns: a character string representing the accessible name of the object.
+ **/
+const gchar*
+atk_object_get_name (AtkObject *accessible)
+{
+ AtkObjectClass *klass;
+
+ g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
+
+ klass = ATK_OBJECT_GET_CLASS (accessible);
+ if (klass->get_name)
+ return (klass->get_name) (accessible);
+ else
+ return NULL;
+}
+
+/**
+ * atk_object_get_description:
+ * @accessible: an #AtkObject
+ *
+ * Gets the accessible description of the accessible.
+ *
+ * Returns: a character string representing the accessible description
+ * of the accessible.
+ *
+ **/
+const gchar*
+atk_object_get_description (AtkObject *accessible)
+{
+ AtkObjectClass *klass;
+
+ g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
+
+ klass = ATK_OBJECT_GET_CLASS (accessible);
+ if (klass->get_description)
+ return (klass->get_description) (accessible);
+ else
+ return NULL;
+}
+
+/**
+ * atk_object_get_parent:
+ * @accessible: an #AtkObject
+ *
+ * Gets the accessible parent of the accessible. By default this is
+ * the one assigned with atk_object_set_parent(), but it is assumed
+ * that ATK implementors have ways to get the parent of the object
+ * without the need of assigning it manually with
+ * atk_object_set_parent(), and will return it with this method.
+ *
+ * If you are only interested on the parent assigned with
+ * atk_object_set_parent(), use atk_object_peek_parent().
+ *
+ * Returns: (transfer none): an #AtkObject representing the accessible
+ * parent of the accessible
+ **/
+AtkObject*
+atk_object_get_parent (AtkObject *accessible)
+{
+ AtkObjectClass *klass;
+
+ g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
+
+ klass = ATK_OBJECT_GET_CLASS (accessible);
+ if (klass->get_parent)
+ return (klass->get_parent) (accessible);
+ else
+ return NULL;
+}
+
+/**
+ * atk_object_peek_parent:
+ * @accessible: an #AtkObject
+ *
+ * Gets the accessible parent of the accessible, if it has been
+ * manually assigned with atk_object_set_parent. Otherwise, this
+ * function returns %NULL.
+ *
+ * This method is intended as an utility for ATK implementors, and not
+ * to be exposed to accessible tools. See atk_object_get_parent() for
+ * further reference.
+ *
+ * Returns: (transfer none): an #AtkObject representing the accessible
+ * parent of the accessible if assigned
+ **/
+AtkObject*
+atk_object_peek_parent (AtkObject *accessible)
+{
+ return accessible->accessible_parent;
+}
+
+/**
+ * atk_object_get_n_accessible_children:
+ * @accessible: an #AtkObject
+ *
+ * Gets the number of accessible children of the accessible.
+ *
+ * Returns: an integer representing the number of accessible children
+ * of the accessible.
+ **/
+gint
+atk_object_get_n_accessible_children (AtkObject *accessible)
+{
+ AtkObjectClass *klass;
+
+ g_return_val_if_fail (ATK_IS_OBJECT (accessible), 0);
+
+ klass = ATK_OBJECT_GET_CLASS (accessible);
+ if (klass->get_n_children)
+ return (klass->get_n_children) (accessible);
+ else
+ return 0;
+}
+
+/**
+ * atk_object_ref_accessible_child:
+ * @accessible: an #AtkObject
+ * @i: a gint representing the position of the child, starting from 0
+ *
+ * Gets a reference to the specified accessible child of the object.
+ * The accessible children are 0-based so the first accessible child is
+ * at index 0, the second at index 1 and so on.
+ *
+ * Returns: (transfer full): an #AtkObject representing the specified
+ * accessible child of the accessible.
+ **/
+AtkObject*
+atk_object_ref_accessible_child (AtkObject *accessible,
+ gint i)
+{
+ AtkObjectClass *klass;
+
+ g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
+
+ klass = ATK_OBJECT_GET_CLASS (accessible);
+ if (klass->ref_child)
+ return (klass->ref_child) (accessible, i);
+ else
+ return NULL;
+}
+
+/**
+ * atk_object_ref_relation_set:
+ * @accessible: an #AtkObject
+ *
+ * Gets the #AtkRelationSet associated with the object.
+ *
+ * Returns: (transfer full): an #AtkRelationSet representing the relation set
+ * of the object.
+ **/
+AtkRelationSet*
+atk_object_ref_relation_set (AtkObject *accessible)
+{
+ AtkObjectClass *klass;
+
+ g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
+
+ klass = ATK_OBJECT_GET_CLASS (accessible);
+ if (klass->ref_relation_set)
+ return (klass->ref_relation_set) (accessible);
+ else
+ return NULL;
+}
+
+/**
+ * atk_object_get_role:
+ * @accessible: an #AtkObject
+ *
+ * Gets the role of the accessible.
+ *
+ * Returns: an #AtkRole which is the role of the accessible
+ **/
+AtkRole
+atk_object_get_role (AtkObject *accessible)
+{
+ AtkObjectClass *klass;
+
+ g_return_val_if_fail (ATK_IS_OBJECT (accessible), ATK_ROLE_UNKNOWN);
+
+ klass = ATK_OBJECT_GET_CLASS (accessible);
+ if (klass->get_role)
+ return (klass->get_role) (accessible);
+ else
+ return ATK_ROLE_UNKNOWN;
+}
+
+/**
+ * atk_object_ref_state_set:
+ * @accessible: an #AtkObject
+ *
+ * Gets a reference to the state set of the accessible; the caller must
+ * unreference it when it is no longer needed.
+ *
+ * Returns: (transfer full): a reference to an #AtkStateSet which is the state
+ * set of the accessible
+ **/
+AtkStateSet*
+atk_object_ref_state_set (AtkObject *accessible)
+{
+ AtkObjectClass *klass;
+
+ g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
+
+ klass = ATK_OBJECT_GET_CLASS (accessible);
+ if (klass->ref_state_set)
+ return (klass->ref_state_set) (accessible);
+ else
+ return NULL;
+}
+
+/**
+ * atk_object_get_index_in_parent:
+ * @accessible: an #AtkObject
+ *
+ * Gets the 0-based index of this accessible in its parent; returns -1 if the
+ * accessible does not have an accessible parent.
+ *
+ * Returns: an integer which is the index of the accessible in its parent
+ **/
+gint
+atk_object_get_index_in_parent (AtkObject *accessible)
+{
+ AtkObjectClass *klass;
+
+ g_return_val_if_fail (ATK_OBJECT (accessible), -1);
+
+ klass = ATK_OBJECT_GET_CLASS (accessible);
+ if (klass->get_index_in_parent)
+ return (klass->get_index_in_parent) (accessible);
+ else
+ return -1;
+}
+
+/**
+ * atk_object_set_name:
+ * @accessible: an #AtkObject
+ * @name: a character string to be set as the accessible name
+ *
+ * Sets the accessible name of the accessible. You can't set the name
+ * to NULL. This is reserved for the initial value. In this aspect
+ * NULL is similar to ATK_ROLE_UNKNOWN. If you want to set the name to
+ * a empty value you can use "".
+ **/
+void
+atk_object_set_name (AtkObject *accessible,
+ const gchar *name)
+{
+ AtkObjectClass *klass;
+ gboolean notify = FALSE;
+
+ g_return_if_fail (ATK_IS_OBJECT (accessible));
+ g_return_if_fail (name != NULL);
+
+ klass = ATK_OBJECT_GET_CLASS (accessible);
+ if (klass->set_name)
+ {
+ /* Do not notify for initial name setting. See bug 665870 */
+ notify = (accessible->name != NULL);
+
+ (klass->set_name) (accessible, name);
+ if (notify)
+ g_object_notify (G_OBJECT (accessible), atk_object_name_property_name);
+ }
+}
+
+/**
+ * atk_object_set_description:
+ * @accessible: an #AtkObject
+ * @description: a character string to be set as the accessible description
+ *
+ * Sets the accessible description of the accessible. You can't set
+ * the description to NULL. This is reserved for the initial value. In
+ * this aspect NULL is similar to ATK_ROLE_UNKNOWN. If you want to set
+ * the name to a empty value you can use "".
+ **/
+void
+atk_object_set_description (AtkObject *accessible,
+ const gchar *description)
+{
+ AtkObjectClass *klass;
+ gboolean notify = FALSE;
+
+ g_return_if_fail (ATK_IS_OBJECT (accessible));
+ g_return_if_fail (description != NULL);
+
+ klass = ATK_OBJECT_GET_CLASS (accessible);
+ if (klass->set_description)
+ {
+ /* Do not notify for initial name setting. See bug 665870 */
+ notify = (accessible->description != NULL);
+
+ (klass->set_description) (accessible, description);
+ if (notify)
+ g_object_notify (G_OBJECT (accessible),
+ atk_object_name_property_description);
+ }
+}
+
+/**
+ * atk_object_set_parent:
+ * @accessible: an #AtkObject
+ * @parent: an #AtkObject to be set as the accessible parent
+ *
+ * Sets the accessible parent of the accessible. @parent can be NULL.
+ **/
+void
+atk_object_set_parent (AtkObject *accessible,
+ AtkObject *parent)
+{
+ AtkObjectClass *klass;
+
+ g_return_if_fail (ATK_IS_OBJECT (accessible));
+
+ klass = ATK_OBJECT_GET_CLASS (accessible);
+ if (klass->set_parent)
+ {
+ (klass->set_parent) (accessible, parent);
+ g_object_notify (G_OBJECT (accessible), atk_object_name_property_parent);
+ }
+}
+
+/**
+ * atk_object_set_role:
+ * @accessible: an #AtkObject
+ * @role: an #AtkRole to be set as the role
+ *
+ * Sets the role of the accessible.
+ **/
+void
+atk_object_set_role (AtkObject *accessible,
+ AtkRole role)
+{
+ AtkObjectClass *klass;
+ AtkRole old_role;
+
+ g_return_if_fail (ATK_IS_OBJECT (accessible));
+
+ klass = ATK_OBJECT_GET_CLASS (accessible);
+ if (klass->set_role)
+ {
+ old_role = atk_object_get_role (accessible);
+ if (old_role != role)
+ {
+ (klass->set_role) (accessible, role);
+ if (old_role != ATK_ROLE_UNKNOWN)
+ /* Do not notify for initial role setting */
+ g_object_notify (G_OBJECT (accessible), atk_object_name_property_role);
+ }
+ }
+}
+
+/**
+ * atk_object_notify_state_change:
+ * @accessible: an #AtkObject
+ * @state: an #AtkState whose state is changed
+ * @value: a gboolean which indicates whether the state is being set on or off
+ *
+ * Emits a state-change signal for the specified state.
+ *
+ * Note that as a general rule when the state of an existing object changes,
+ * emitting a notification is expected.
+ **/
+void
+atk_object_notify_state_change (AtkObject *accessible,
+ AtkState state,
+ gboolean value)
+{
+ const gchar* name;
+
+ g_return_if_fail (ATK_IS_OBJECT (accessible));
+
+ name = atk_state_type_get_name (state);
+ g_signal_emit (accessible, atk_object_signals[STATE_CHANGE],
+ g_quark_from_string (name),
+ name, value, NULL);
+}
+
+/**
+ * atk_implementor_ref_accessible:
+ * @implementor: The #GObject instance which should implement #AtkImplementorIface
+ * if a non-null return value is required.
+ *
+ * Gets a reference to an object's #AtkObject implementation, if
+ * the object implements #AtkObjectIface
+ *
+ * Returns: (transfer full): a reference to an object's #AtkObject
+ * implementation
+ */
+AtkObject *
+atk_implementor_ref_accessible (AtkImplementor *implementor)
+{
+ AtkImplementorIface *iface;
+ AtkObject *accessible = NULL;
+
+ g_return_val_if_fail (ATK_IS_IMPLEMENTOR (implementor), NULL);
+
+ iface = ATK_IMPLEMENTOR_GET_IFACE (implementor);
+
+ if (iface != NULL)
+ accessible = iface->ref_accessible (implementor);
+
+ g_return_val_if_fail ((accessible != NULL), NULL);
+
+ return accessible;
+}
+
+
+/**
+ * atk_object_get_attributes:
+ * @accessible: An #AtkObject.
+ *
+ * Get a list of properties applied to this object as a whole, as an #AtkAttributeSet consisting of
+ * name-value pairs. As such these attributes may be considered weakly-typed properties or annotations,
+ * as distinct from strongly-typed object data available via other get/set methods.
+ * Not all objects have explicit "name-value pair" #AtkAttributeSet properties.
+ *
+ * Since: 1.12
+ *
+ * Returns: (transfer full): an #AtkAttributeSet consisting of all
+ * explicit properties/annotations applied to the object, or an empty
+ * set if the object has no name-value pair attributes assigned to
+ * it. This #atkattributeset should be freed by a call to
+ * atk_attribute_set_free().
+ */
+AtkAttributeSet *
+atk_object_get_attributes (AtkObject *accessible)
+{
+ AtkObjectClass *klass;
+
+ g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
+
+ klass = ATK_OBJECT_GET_CLASS (accessible);
+ if (klass->get_attributes)
+ return (klass->get_attributes) (accessible);
+ else
+ return NULL;
+
+}
+
+static AtkRelationSet*
+atk_object_real_ref_relation_set (AtkObject *accessible)
+{
+ g_return_val_if_fail (accessible->relation_set, NULL);
+ g_object_ref (accessible->relation_set);
+
+ return accessible->relation_set;
+}
+
+static void
+atk_object_real_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ AtkObject *accessible;
+
+ accessible = ATK_OBJECT (object);
+
+ switch (prop_id)
+ {
+ case PROP_NAME:
+ atk_object_set_name (accessible, g_value_get_string (value));
+ break;
+ case PROP_DESCRIPTION:
+ atk_object_set_description (accessible, g_value_get_string (value));
+ break;
+ case PROP_ROLE:
+ atk_object_set_role (accessible, g_value_get_enum (value));
+ break;
+ case PROP_PARENT:
+ atk_object_set_parent (accessible, g_value_get_object (value));
+ break;
+ case PROP_TABLE_SUMMARY:
+ if (ATK_IS_TABLE (accessible))
+ atk_table_set_summary (ATK_TABLE (accessible), g_value_get_object (value));
+ break;
+ case PROP_TABLE_CAPTION_OBJECT:
+ if (ATK_IS_TABLE (accessible))
+ atk_table_set_caption (ATK_TABLE (accessible), g_value_get_object (value));
+ break;
+ case PROP_ACCESSIBLE_ID:
+ atk_object_set_accessible_id (accessible, g_value_get_string (value));
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+atk_object_real_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ AtkObject *accessible;
+
+ accessible = ATK_OBJECT (object);
+
+ switch (prop_id)
+ {
+ case PROP_NAME:
+ g_value_set_string (value, atk_object_get_name (accessible));
+ break;
+ case PROP_DESCRIPTION:
+ g_value_set_string (value, atk_object_get_description (accessible));
+ break;
+ case PROP_ROLE:
+ g_value_set_enum (value, atk_object_get_role (accessible));
+ break;
+ case PROP_LAYER:
+ if (ATK_IS_COMPONENT (accessible))
+ g_value_set_int (value, atk_component_get_layer (ATK_COMPONENT (accessible)));
+ break;
+ case PROP_MDI_ZORDER:
+ if (ATK_IS_COMPONENT (accessible))
+ g_value_set_int (value, atk_component_get_mdi_zorder (ATK_COMPONENT (accessible)));
+ break;
+ case PROP_PARENT:
+ g_value_set_object (value, atk_object_get_parent (accessible));
+ break;
+ case PROP_TABLE_SUMMARY:
+ if (ATK_IS_TABLE (accessible))
+ g_value_set_object (value, atk_table_get_summary (ATK_TABLE (accessible)));
+ break;
+ case PROP_TABLE_CAPTION_OBJECT:
+ if (ATK_IS_TABLE (accessible))
+ g_value_set_object (value, atk_table_get_caption (ATK_TABLE (accessible)));
+ break;
+ case PROP_HYPERTEXT_NUM_LINKS:
+ if (ATK_IS_HYPERTEXT (accessible))
+ g_value_set_int (value, atk_hypertext_get_n_links (ATK_HYPERTEXT (accessible)));
+ break;
+ case PROP_ACCESSIBLE_ID:
+ g_value_set_string (value, atk_object_get_accessible_id (accessible));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+atk_object_finalize (GObject *object)
+{
+ AtkObject *accessible;
+ AtkObjectPrivate *private;
+
+ g_return_if_fail (ATK_IS_OBJECT (object));
+
+ accessible = ATK_OBJECT (object);
+ private = atk_object_get_instance_private (accessible);
+
+ g_free (accessible->name);
+ g_free (accessible->description);
+
+ /*
+ * Free memory allocated for relation set if it have been allocated.
+ */
+ if (accessible->relation_set)
+ g_object_unref (accessible->relation_set);
+
+ if (accessible->accessible_parent)
+ g_object_unref (accessible->accessible_parent);
+
+ g_free(private->accessible_id);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static const gchar*
+atk_object_real_get_name (AtkObject *object)
+{
+ return object->name;
+}
+
+static const gchar*
+atk_object_real_get_description (AtkObject *object)
+{
+ return object->description;
+}
+
+static AtkObject*
+atk_object_real_get_parent (AtkObject *object)
+{
+ return atk_object_peek_parent (object);
+}
+
+static AtkRole
+atk_object_real_get_role (AtkObject *object)
+{
+ return object->role;
+}
+
+static AtkLayer
+atk_object_real_get_layer (AtkObject *object)
+{
+ return object->layer;
+}
+
+static AtkStateSet*
+atk_object_real_ref_state_set (AtkObject *accessible)
+{
+ AtkStateSet *state_set;
+ AtkObject *focus_object;
+
+ state_set = atk_state_set_new ();
+
+ focus_object = atk_get_focus_object ();
+ if (focus_object == accessible)
+ atk_state_set_add_state (state_set, ATK_STATE_FOCUSED);
+
+ return state_set;
+}
+
+static void
+atk_object_real_set_name (AtkObject *object,
+ const gchar *name)
+{
+ g_free (object->name);
+ object->name = g_strdup (name);
+}
+
+static void
+atk_object_real_set_description (AtkObject *object,
+ const gchar *description)
+{
+ g_free (object->description);
+ object->description = g_strdup (description);
+}
+
+static void
+atk_object_real_set_parent (AtkObject *object,
+ AtkObject *parent)
+{
+ if (object->accessible_parent)
+ g_object_unref (object->accessible_parent);
+
+ object->accessible_parent = parent;
+ if (object->accessible_parent)
+ g_object_ref (object->accessible_parent);
+}
+
+static void
+atk_object_real_set_role (AtkObject *object,
+ AtkRole role)
+{
+ object->role = role;
+}
+
+/**
+ * atk_object_initialize:
+ * @accessible: a #AtkObject
+ * @data: a #gpointer which identifies the object for which the AtkObject was created.
+ *
+ * This function is called when implementing subclasses of #AtkObject.
+ * It does initialization required for the new object. It is intended
+ * that this function should called only in the ..._new() functions used
+ * to create an instance of a subclass of #AtkObject
+ **/
+void
+atk_object_initialize (AtkObject *accessible,
+ gpointer data)
+{
+ AtkObjectClass *klass;
+
+ g_return_if_fail (ATK_IS_OBJECT (accessible));
+
+ klass = ATK_OBJECT_GET_CLASS (accessible);
+ if (klass->initialize)
+ klass->initialize (accessible, data);
+}
+
+/*
+ * This function is a signal handler for notify signal which gets emitted
+ * when a property changes value.
+ *
+ * It constructs an AtkPropertyValues structure and emits a "property_changed"
+ * signal which causes the user specified AtkPropertyChangeHandler
+ * to be called.
+ */
+static void
+atk_object_notify (GObject *obj,
+ GParamSpec *pspec)
+{
+ AtkPropertyValues values = { NULL, };
+
+ g_value_init (&values.new_value, pspec->value_type);
+ g_object_get_property (obj, pspec->name, &values.new_value);
+ values.property_name = pspec->name;
+ g_signal_emit (obj, atk_object_signals[PROPERTY_CHANGE],
+ g_quark_from_string (pspec->name),
+ &values, NULL);
+ g_value_unset (&values.new_value);
+}
+
+/**
+ * atk_role_get_name:
+ * @role: The #AtkRole whose name is required
+ *
+ * Gets the description string describing the #AtkRole @role.
+ *
+ * Returns: the string describing the AtkRole
+ */
+const gchar*
+atk_role_get_name (AtkRole role)
+{
+ g_return_val_if_fail (role >= 0, NULL);
+
+ if (!role_names)
+ initialize_role_names ();
+
+ if (role < role_names->len)
+ return g_ptr_array_index (role_names, role);
+
+ return NULL;
+}
+
+/**
+ * atk_role_get_localized_name:
+ * @role: The #AtkRole whose localized name is required
+ *
+ * Gets the localized description string describing the #AtkRole @role.
+ *
+ * Returns: the localized string describing the AtkRole
+ **/
+const gchar*
+atk_role_get_localized_name (AtkRole role)
+{
+ _gettext_initialization ();
+
+ return dgettext (GETTEXT_PACKAGE, atk_role_get_name (role));
+}
+
+static const gchar*
+atk_object_real_get_object_locale (AtkObject *object)
+{
+ return setlocale (LC_MESSAGES, NULL);
+}
+
+/**
+ * atk_object_get_object_locale:
+ * @accessible: an #AtkObject
+ *
+ * Gets a UTF-8 string indicating the POSIX-style LC_MESSAGES locale
+ * of @accessible.
+ *
+ * Since: 2.8
+ *
+ * Returns: a UTF-8 string indicating the POSIX-style LC_MESSAGES
+ * locale of @accessible.
+ **/
+const gchar*
+atk_object_get_object_locale (AtkObject *accessible)
+{
+ AtkObjectClass *klass;
+
+ g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
+
+ klass = ATK_OBJECT_GET_CLASS (accessible);
+ if (klass->get_object_locale)
+ return (klass->get_object_locale) (accessible);
+ else
+ return NULL;
+}
+
+
+/**
+ * atk_role_for_name:
+ * @name: a string which is the (non-localized) name of an ATK role.
+ *
+ * Get the #AtkRole type corresponding to a rolew name.
+ *
+ * Returns: the #AtkRole enumerated type corresponding to the specified name,
+ * or #ATK_ROLE_INVALID if no matching role is found.
+ **/
+AtkRole
+atk_role_for_name (const gchar *name)
+{
+ AtkRole role = ATK_ROLE_INVALID;
+ gint i;
+
+ g_return_val_if_fail (name, ATK_ROLE_INVALID);
+
+ if (!role_names)
+ initialize_role_names ();
+
+ for (i = 0; i < role_names->len; i++)
+ {
+ gchar *role_name = (gchar *)g_ptr_array_index (role_names, i);
+
+ g_return_val_if_fail (role_name, ATK_ROLE_INVALID);
+
+ if (strcmp (name, role_name) == 0)
+ {
+ role = i;
+ break;
+ }
+ }
+
+ return role;
+}
+
+/**
+ * atk_object_add_relationship:
+ * @object: The #AtkObject to which an AtkRelation is to be added.
+ * @relationship: The #AtkRelationType of the relation
+ * @target: The #AtkObject which is to be the target of the relation.
+ *
+ * Adds a relationship of the specified type with the specified target.
+ *
+ * Returns: TRUE if the relationship is added.
+ **/
+gboolean
+atk_object_add_relationship (AtkObject *object,
+ AtkRelationType relationship,
+ AtkObject *target)
+{
+ AtkObject *array[1];
+ AtkRelation *relation;
+
+ g_return_val_if_fail (ATK_IS_OBJECT (object), FALSE);
+ g_return_val_if_fail (ATK_IS_OBJECT (target), FALSE);
+
+ if (atk_relation_set_contains_target (object->relation_set,
+ relationship, target))
+ return FALSE;
+
+ array[0] = target;
+ relation = atk_relation_new (array, 1, relationship);
+ atk_relation_set_add (object->relation_set, relation);
+ g_object_unref (relation);
+
+ return TRUE;
+}
+
+/**
+ * atk_object_remove_relationship:
+ * @object: The #AtkObject from which an AtkRelation is to be removed.
+ * @relationship: The #AtkRelationType of the relation
+ * @target: The #AtkObject which is the target of the relation to be removed.
+ *
+ * Removes a relationship of the specified type with the specified target.
+ *
+ * Returns: TRUE if the relationship is removed.
+ **/
+gboolean
+atk_object_remove_relationship (AtkObject *object,
+ AtkRelationType relationship,
+ AtkObject *target)
+{
+ gboolean ret = FALSE;
+ AtkRelation *relation;
+ GPtrArray *array;
+
+ g_return_val_if_fail (ATK_IS_OBJECT (object), FALSE);
+ g_return_val_if_fail (ATK_IS_OBJECT (target), FALSE);
+
+ relation = atk_relation_set_get_relation_by_type (object->relation_set, relationship);
+
+ if (relation)
+ {
+ ret = atk_relation_remove_target (relation, target);
+ array = atk_relation_get_target (relation);
+ if (!array || array->len == 0)
+ atk_relation_set_remove (object->relation_set, relation);
+ }
+ return ret;
+}
+
+/**
+ * atk_object_get_accessible_id:
+ * @accessible: an #AtkObject
+ *
+ * Gets the accessible id of the accessible.
+ *
+ * Since: 2.34
+ *
+ * Returns: a character string representing the accessible id of the object, or
+ * NULL if no such string was set.
+ **/
+const gchar*
+atk_object_get_accessible_id (AtkObject *accessible)
+{
+ AtkObjectPrivate *private = atk_object_get_instance_private (accessible);
+ return private->accessible_id;
+}
+
+/**
+ * atk_object_set_accessible_id:
+ * @accessible: an #AtkObject
+ * @name: a character string to be set as the accessible id
+ *
+ * Sets the accessible ID of the accessible. This is not meant to be presented
+ * to the user, but to be an ID which is stable over application development.
+ * Typically, this is the gtkbuilder ID. Such an ID will be available for
+ * instance to identify a given well-known accessible object for tailored screen
+ * reading, or for automatic regression testing.
+ *
+ * Since: 2.34
+ **/
+void
+atk_object_set_accessible_id (AtkObject *accessible, const gchar *id)
+{
+ AtkObjectPrivate *private = atk_object_get_instance_private (accessible);
+ g_free (private->accessible_id);
+ private->accessible_id = g_strdup (id);
+}
+
+static void
+atk_object_real_initialize (AtkObject *accessible,
+ gpointer data)
+{
+ return;
+}