Merge branch 'upstream/2.30.0' into tizen
[platform/upstream/atk.git] / atk / atkcomponent.c
old mode 100755 (executable)
new mode 100644 (file)
index 507a723..a618867
  * Boston, MA 02111-1307, USA.
  */
 
+#include "config.h"
 
 #include "atkcomponent.h"
 
-static AtkObject* atk_component_real_get_accessible_at_point (AtkComponent *component,
+/**
+ * SECTION:atkcomponent
+ * @Short_description: The ATK interface provided by UI components
+ * which occupy a physical area on the screen.
+ * which the user can activate/interact with.
+ * @Title:AtkComponent
+ *
+ * #AtkComponent should be implemented by most if not all UI elements
+ * with an actual on-screen presence, i.e. components which can be
+ * said to have a screen-coordinate bounding box.  Virtually all
+ * widgets will need to have #AtkComponent implementations provided
+ * for their corresponding #AtkObject class.  In short, only UI
+ * elements which are *not* GUI elements will omit this ATK interface.
+ *
+ * A possible exception might be textual information with a
+ * transparent background, in which case text glyph bounding box
+ * information is provided by #AtkText.
+ */
+
+enum {
+  BOUNDS_CHANGED,
+  LAST_SIGNAL
+};
+
+static void       atk_component_base_init (AtkComponentIface *class);
+
+static gboolean   atk_component_real_contains                (AtkComponent *component,
                                                               gint         x,
-                                                              gint         y);
+                                                              gint         y,
+                                                              AtkCoordType coord_type);
+
+static AtkObject* atk_component_real_ref_accessible_at_point (AtkComponent *component,
+                                                              gint         x,
+                                                              gint         y,
+                                                              AtkCoordType coord_type);
+
+static void      atk_component_real_get_position             (AtkComponent *component,
+                                                              gint         *x,
+                                                              gint         *y,
+                                                              AtkCoordType coord_type);
+
+static void      atk_component_real_get_size                 (AtkComponent *component,
+                                                              gint         *width,
+                                                              gint         *height);
+
+static guint atk_component_signals[LAST_SIGNAL] = { 0 };
 
 GType
-atk_component_get_type ()
+atk_component_get_type (void)
 {
   static GType type = 0;
 
@@ -33,8 +77,8 @@ atk_component_get_type ()
     static const GTypeInfo tinfo =
     {
       sizeof (AtkComponentIface),
-      NULL,
-      NULL,
+      (GBaseInitFunc) atk_component_base_init,
+      (GBaseFinalizeFunc) NULL,
 
     };
 
@@ -44,22 +88,62 @@ atk_component_get_type ()
   return type;
 }
 
+static void
+atk_component_base_init (AtkComponentIface *class)
+{
+  static gboolean initialized = FALSE;
+
+  if (! initialized)
+    {
+      class->ref_accessible_at_point = atk_component_real_ref_accessible_at_point;
+      class->contains = atk_component_real_contains;
+      class->get_position = atk_component_real_get_position;
+      class->get_size = atk_component_real_get_size;
+
+
+      /**
+       * AtkComponent::bounds-changed:
+       * @atkcomponent: the object which received the signal.
+       * @arg1: The AtkRectangle giving the new position and size.
+       *
+       * The 'bounds-changed" signal is emitted when the bposition or
+       * size of the component changes.
+       */
+      atk_component_signals[BOUNDS_CHANGED] =
+        g_signal_new ("bounds_changed",
+                      ATK_TYPE_COMPONENT,
+                      G_SIGNAL_RUN_LAST,
+                      G_STRUCT_OFFSET (AtkComponentIface, bounds_changed),
+                      (GSignalAccumulator) NULL, NULL,
+                      g_cclosure_marshal_VOID__BOXED,
+                      G_TYPE_NONE, 1,
+                      ATK_TYPE_RECTANGLE | G_SIGNAL_TYPE_STATIC_SCOPE);
+
+      initialized = TRUE;
+    }
+}
+
+
 /**
- *atk_component_add_focus_handler:
- *@component: The #AtkComponent to attach the @handler to
- *@handler: The #AtkFocusHandler to be attached to @component
+ * atk_component_add_focus_handler: (skip)
+ * @component: The #AtkComponent to attach the @handler to
+ * @handler: The #AtkFocusHandler to be attached to @component
  *
  * Add the specified handler to the set of functions to be called 
- * when this object receives focus (in or out) events.
+ * when this object receives focus events (in or out). If the handler is
+ * already added it is not added again
+ *
+ * Deprecated: 2.9.4: If you need to track when an object gains or
+ * lose the focus, use the #AtkObject::state-change "focused" notification instead.
  *
- * Returns:
+ * Returns: a handler id which can be used in atk_component_remove_focus_handler()
+ * or zero if the handler was already added.
  **/
 guint
 atk_component_add_focus_handler (AtkComponent    *component,
                                  AtkFocusHandler handler)
 {
   AtkComponentIface *iface = NULL;
-  g_return_val_if_fail (component != NULL, 0);
   g_return_val_if_fail (ATK_IS_COMPONENT (component), 0);
 
   iface = ATK_COMPONENT_GET_IFACE (component);
@@ -71,20 +155,24 @@ atk_component_add_focus_handler (AtkComponent    *component,
 }
 
 /**
- *atk_component_remove_focus_handler:
- *@component: the #AtkComponent to remove the focus handler from
- *@handler_id: the handler id of the focus handler to be removed
+ * atk_component_remove_focus_handler:
+ * @component: the #AtkComponent to remove the focus handler from
+ * @handler_id: the handler id of the focus handler to be removed
  * from @component
  *
  * Remove the handler specified by @handler_id from the list of
- * functions to be executed when this object receives focus (in or out)
+ * functions to be executed when this object receives focus events 
+ * (in or out).
+ *
+ * Deprecated: 2.9.4: If you need to track when an object gains or
+ * lose the focus, use the #AtkObject::state-change "focused" notification instead.
+ *
  **/
 void
 atk_component_remove_focus_handler (AtkComponent    *component,
                                     guint           handler_id)
 {
   AtkComponentIface *iface = NULL;
-  g_return_if_fail (component != NULL);
   g_return_if_fail (ATK_IS_COMPONENT (component));
 
   iface = ATK_COMPONENT_GET_IFACE (component);
@@ -94,76 +182,79 @@ atk_component_remove_focus_handler (AtkComponent    *component,
 }
 
 /**
- *atk_component_contains:
- *@component: the #AtkComponent
- *@x: x coordinate relative to the coordinate system of @component
- *@y: y coordinate relative to the coordinate system of @component
+ * atk_component_contains:
+ * @component: the #AtkComponent
+ * @x: x coordinate
+ * @y: y coordinate
+ * @coord_type: specifies whether the coordinates are relative to the screen
+ * or to the components top level window
+ *
+ * Checks whether the specified point is within the extent of the @component.
  *
- * Checks whether the specified point is within the extent of the @component,
- * the points x and y coordinates are defined to be relative to the 
- * coordinate system of the @component.
+ * Toolkit implementor note: ATK provides a default implementation for
+ * this virtual method. In general there are little reason to
+ * re-implement it.
  *
- * Returns: a #gboolean indicating whether the specified point is within
- *  the extent of the @component
+ * Returns: %TRUE or %FALSE indicating whether the specified point is within
+ * the extent of the @component or not
  **/
 gboolean
 atk_component_contains (AtkComponent    *component,
                         gint            x,
-                        gint            y)
+                        gint            y,
+                        AtkCoordType    coord_type)
 {
   AtkComponentIface *iface = NULL;
-  g_return_val_if_fail (component != NULL, FALSE);
   g_return_val_if_fail (ATK_IS_COMPONENT (component), FALSE);
 
   iface = ATK_COMPONENT_GET_IFACE (component);
 
   if (iface->contains)
-    return (iface->contains) (component, x, y);
+    return (iface->contains) (component, x, y, coord_type);
   else
     return FALSE;
 }
 
 /**
- *atk_component_get_accessible_at_point:
- *@component: the #AtkComponent
- *@x: local x coordinate
- *@y: local y coordinate
+ * atk_component_ref_accessible_at_point:
+ * @component: the #AtkComponent
+ * @x: x coordinate
+ * @y: y coordinate
+ * @coord_type: specifies whether the coordinates are relative to the screen
+ * or to the components top level window
  *
- * Gets the accessible child, if one exists, contained at the local
+ * Gets a reference to the accessible child, if one exists, at the
  * coordinate point specified by @x and @y.
  *
- *Returns: the accessible child, if one exists, contained at the local
- * coordinate point specified by @x and @y.
+ * Returns: (nullable) (transfer full): a reference to the accessible
+ * child, if one exists
  **/
 AtkObject*
-atk_component_get_accessible_at_point (AtkComponent    *component,
+atk_component_ref_accessible_at_point (AtkComponent    *component,
                                        gint            x,
-                                       gint            y)
+                                       gint            y,
+                                       AtkCoordType    coord_type)
 {
   AtkComponentIface *iface = NULL;
-  g_return_val_if_fail (component != NULL, NULL);
   g_return_val_if_fail (ATK_IS_COMPONENT (component), NULL);
 
   iface = ATK_COMPONENT_GET_IFACE (component);
 
-  if (iface->get_accessible_at_point)
-    return (iface->get_accessible_at_point) (component, x, y);
+  if (iface->ref_accessible_at_point)
+    return (iface->ref_accessible_at_point) (component, x, y, coord_type);
   else
-  {
-    /*
-     * if this method is not overridden use the default implementation.
-     */
-    return atk_component_real_get_accessible_at_point (component, x, y);
-  }
+    return NULL;
 }
 
 /**
- *atk_component_get_extents:
- *@component: an #AtkComponent
- *@x: address of #gint to put x coordinate
- *@y: address of #gint to put y coordinate
- *@width: address of #gint to put width
- *@height: address of #gint to put height
+ * atk_component_get_extents:
+ * @component: an #AtkComponent
+ * @x: (out) (optional): address of #gint to put x coordinate
+ * @y: (out) (optional): address of #gint to put y coordinate
+ * @width: (out) (optional): address of #gint to put width
+ * @height: (out) (optional): address of #gint to put height
+ * @coord_type: specifies whether the coordinates are relative to the screen
+ * or to the components top level window
  *
  * Gets the rectangle which gives the extent of the @component.
  *
@@ -173,192 +264,460 @@ atk_component_get_extents    (AtkComponent    *component,
                               gint            *x,
                               gint            *y,
                               gint            *width,
-                              gint            *height)
+                              gint            *height,
+                              AtkCoordType    coord_type)
 {
   AtkComponentIface *iface = NULL;
-  g_return_if_fail (component != NULL);
+  gint local_x, local_y, local_width, local_height;
+  gint *real_x, *real_y, *real_width, *real_height;
+
   g_return_if_fail (ATK_IS_COMPONENT (component));
 
+  if (x)
+    real_x = x;
+  else
+    real_x = &local_x;
+  if (y)
+    real_y = y;
+  else
+    real_y = &local_y;
+  if (width)
+    real_width = width;
+  else
+    real_width = &local_width;
+  if (height)
+    real_height = height;
+  else
+    real_height = &local_height;
+
   iface = ATK_COMPONENT_GET_IFACE (component);
 
   if (iface->get_extents)
-    (iface->get_extents) (component, x, y, width, height);
+    (iface->get_extents) (component, real_x, real_y, real_width, real_height, coord_type);
 }
 
 /**
- *atk_component_get_position:
- *@component: an #AtkComponent
- *@x: address of #gint to put x coordinate position
- *@y: address of #gint to put y coordinate position
- *
- * Gets the position of @component relative to the parent in the form of 
- * a point specifying @component's top-left corner in the screen's
- * coordinate space.
+ * atk_component_get_position:
+ * @component: an #AtkComponent
+ * @x: (out) (optional): address of #gint to put x coordinate position
+ * @y: (out) (optional): address of #gint to put y coordinate position
+ * @coord_type: specifies whether the coordinates are relative to the screen
+ * or to the components top level window
+ *
+ * Gets the position of @component in the form of 
+ * a point specifying @component's top-left corner.
+ *
+ * Deprecated: Since 2.12. Use atk_component_get_extents() instead.
  **/
 void
 atk_component_get_position   (AtkComponent    *component,
                               gint            *x,
-                              gint            *y)
+                              gint            *y,
+                              AtkCoordType    coord_type)
 {
   AtkComponentIface *iface = NULL;
-  g_return_if_fail (component != NULL);
+  gint local_x, local_y;
+  gint *real_x, *real_y;
+
   g_return_if_fail (ATK_IS_COMPONENT (component));
 
+  if (x)
+    real_x = x;
+  else
+    real_x = &local_x;
+  if (y)
+    real_y = y;
+  else
+    real_y = &local_y;
+
   iface = ATK_COMPONENT_GET_IFACE (component);
 
   if (iface->get_position)
-    (iface->get_position) (component, x, y);
+    (iface->get_position) (component, real_x, real_y, coord_type);
 }
 
 /**
- *atk_component_get_position_on_screen:
- *@component: an #AtkComponent
- *@x: address of #gint to put x coordinate position
- *@y: address of #gint to put y coordinate position
+ * atk_component_get_size:
+ * @component: an #AtkComponent
+ * @width: (out) (optional): address of #gint to put width of @component
+ * @height: (out) (optional): address of #gint to put height of @component
+ *
+ * Gets the size of the @component in terms of width and height.
  *
- * Gets the position of the @component on the screen
+ * Deprecated: Since 2.12. Use atk_component_get_extents() instead.
  **/
 void
-atk_component_get_position_on_screen (AtkComponent    *component,
-                                      gint            *x,
-                                      gint            *y)
+atk_component_get_size       (AtkComponent    *component,
+                              gint            *width,
+                              gint            *height)
 {
   AtkComponentIface *iface = NULL;
-  g_return_if_fail (component != NULL);
+  gint local_width, local_height;
+  gint *real_width, *real_height;
+
+  g_return_if_fail (ATK_IS_COMPONENT (component));
+
+  if (width)
+    real_width = width;
+  else
+    real_width = &local_width;
+  if (height)
+    real_height = height;
+  else
+    real_height = &local_height;
+
   g_return_if_fail (ATK_IS_COMPONENT (component));
 
   iface = ATK_COMPONENT_GET_IFACE (component);
 
-  if (iface->get_position_on_screen)
-    return (iface->get_position_on_screen) (component, x, y);
+  if (iface->get_size)
+    (iface->get_size) (component, real_width, real_height);
 }
 
 /**
- *atk_component_get_size:
- *@component: an #AtkComponent
- *@width: address of #gint to put width of @component
- *@height: address of #gint to put height of @component
+ * atk_component_get_layer:
+ * @component: an #AtkComponent
  *
- * Gets the size of the @component.
+ * Gets the layer of the component.
+ *
+ * Returns: an #AtkLayer which is the layer of the component
  **/
-void
-atk_component_get_size       (AtkComponent    *component,
-                              gint            *x,
-                              gint            *y)
+AtkLayer
+atk_component_get_layer (AtkComponent *component) 
 {
-  AtkComponentIface *iface = NULL;
-  g_return_if_fail (component != NULL);
-  g_return_if_fail (ATK_IS_COMPONENT (component));
+  AtkComponentIface *iface;
+
+  g_return_val_if_fail (ATK_IS_COMPONENT (component), ATK_LAYER_INVALID);
 
   iface = ATK_COMPONENT_GET_IFACE (component);
+  if (iface->get_layer)
+    return (iface->get_layer) (component);
+  else
+    return ATK_LAYER_WIDGET;
+}
 
-  if (iface->get_size)
-    (iface->get_size) (component, x, y);
+/**
+ * atk_component_get_mdi_zorder:
+ * @component: an #AtkComponent
+ *
+ * Gets the zorder of the component. The value G_MININT will be returned 
+ * if the layer of the component is not ATK_LAYER_MDI or ATK_LAYER_WINDOW.
+ *
+ * Returns: a gint which is the zorder of the component, i.e. the depth at 
+ * which the component is shown in relation to other components in the same 
+ * container.
+ **/
+gint
+atk_component_get_mdi_zorder (AtkComponent *component) 
+{
+  AtkComponentIface *iface;
+
+  g_return_val_if_fail (ATK_IS_COMPONENT (component), G_MININT);
+
+  iface = ATK_COMPONENT_GET_IFACE (component);
+  if (iface->get_mdi_zorder)
+    return (iface->get_mdi_zorder) (component);
+  else
+    return G_MININT;
 }
 
 /**
- *atk_component_grab_focus:
- *@component: an #AtkComponent
+ * atk_component_get_alpha:
+ * @component: an #AtkComponent
  *
- * Grabs focus for this @component
+ * Returns the alpha value (i.e. the opacity) for this
+ * @component, on a scale from 0 (fully transparent) to 1.0
+ * (fully opaque).
+ *
+ * Returns: An alpha value from 0 to 1.0, inclusive.
+ * Since: 1.12
  **/
-void
+gdouble
+atk_component_get_alpha (AtkComponent    *component)
+{
+  AtkComponentIface *iface;
+
+  g_return_val_if_fail (ATK_IS_COMPONENT (component), G_MININT);
+
+  iface = ATK_COMPONENT_GET_IFACE (component);
+  if (iface->get_alpha)
+    return (iface->get_alpha) (component);
+  else
+    return (gdouble) 1.0;
+}
+
+/**
+ * atk_component_grab_focus:
+ * @component: an #AtkComponent
+ *
+ * Grabs focus for this @component.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ **/
+gboolean
 atk_component_grab_focus (AtkComponent    *component)
 {
   AtkComponentIface *iface = NULL;
-  g_return_if_fail (component != NULL);
-  g_return_if_fail (ATK_IS_COMPONENT (component));
+  g_return_val_if_fail (ATK_IS_COMPONENT (component), FALSE);
 
   iface = ATK_COMPONENT_GET_IFACE (component);
 
   if (iface->grab_focus)
-    (iface->grab_focus) (component);
+    return (iface->grab_focus) (component);
+  else
+    return FALSE;
 }
 
 /**
- *atk_component_set_extents:
- *@component: an #AtkComponent
- *@x: x coordinate to set for @component
- *@y: y coordinate to set for @component
- *@width: width to set for @component
- *@height: height to set for @component
- *
- * Sets the extents of @component
+ * atk_component_grab_highlight:
+ * @component: an #AtkComponent
+ *
+ * Grabs highlight for this @component.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
  **/
-void
+gboolean
+atk_component_grab_highlight (AtkComponent    *component)
+{
+  AtkComponentIface *iface = NULL;
+  g_return_val_if_fail (ATK_IS_COMPONENT (component), FALSE);
+
+  iface = ATK_COMPONENT_GET_IFACE (component);
+
+  if (iface->grab_highlight)
+    return (iface->grab_highlight) (component);
+  else
+    return FALSE;
+}
+
+/**
+ * atk_component_clear_highlight:
+ * @component: an #AtkComponent
+ *
+ * Clears highlight for this @component.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ **/
+gboolean
+atk_component_clear_highlight (AtkComponent    *component)
+{
+  AtkComponentIface *iface = NULL;
+  g_return_val_if_fail (ATK_IS_COMPONENT (component), FALSE);
+
+  iface = ATK_COMPONENT_GET_IFACE (component);
+
+  if (iface->clear_highlight)
+    return (iface->clear_highlight) (component);
+  else
+    return FALSE;
+}
+
+/**
+ * atk_component_get_highlight_index:
+ * @component: an #AtkComponent
+ *
+ * Returns: highlight index of the @component (if >0),
+ * 0 if highlight index is not set or -1 if an error occured.
+ *
+ **/
+gint
+atk_component_get_highlight_index (AtkComponent    *component)
+{
+  AtkComponentIface *iface = NULL;
+  g_return_val_if_fail (ATK_IS_COMPONENT (component), -1);
+
+  iface = ATK_COMPONENT_GET_IFACE (component);
+
+  if (iface->get_highlight_index)
+    return (iface->get_highlight_index) (component);
+  else
+    return -1;
+}
+
+/**
+ * atk_component_set_extents:
+ * @component: an #AtkComponent
+ * @x: x coordinate
+ * @y: y coordinate
+ * @width: width to set for @component
+ * @height: height to set for @component
+ * @coord_type: specifies whether the coordinates are relative to the screen
+ * or to the components top level window
+ *
+ * Sets the extents of @component.
+ *
+ * Returns: %TRUE or %FALSE whether the extents were set or not
+ **/
+gboolean
 atk_component_set_extents   (AtkComponent    *component,
                              gint            x,
                              gint            y,
                              gint            width,
-                             gint            height)
+                             gint            height,
+                             AtkCoordType    coord_type)
 {
   AtkComponentIface *iface = NULL;
-  g_return_if_fail (component != NULL);
-  g_return_if_fail (ATK_IS_COMPONENT (component));
+  g_return_val_if_fail (ATK_IS_COMPONENT (component), FALSE);
 
   iface = ATK_COMPONENT_GET_IFACE (component);
 
   if (iface->set_extents)
-    (iface->set_extents) (component, x, y, width, height);
+    return (iface->set_extents) (component, x, y, width, height, coord_type);
+  else
+    return FALSE;
 }
 
 /**
- *atk_component_set_position:
- *@component: an #AtkComponent
- *@x: x coordinate
- *@y: y coordinate
+ * atk_component_set_position:
+ * @component: an #AtkComponent
+ * @x: x coordinate
+ * @y: y coordinate
+ * @coord_type: specifies whether the coordinates are relative to the screen
+ * or to the component's top level window
  *
- * Sets the postition of @component
+ * Sets the position of @component.
+ *
+ * Contrary to atk_component_scroll_to, this does not trigger any scrolling,
+ * this just moves @component in its parent.
+ *
+ * Returns: %TRUE or %FALSE whether or not the position was set or not
  **/
-void
+gboolean
 atk_component_set_position   (AtkComponent    *component,
                               gint            x,
-                              gint            y)
+                              gint            y,
+                              AtkCoordType    coord_type)
 {
   AtkComponentIface *iface = NULL;
-  g_return_if_fail (component != NULL);
-  g_return_if_fail (ATK_IS_COMPONENT (component));
+  g_return_val_if_fail (ATK_IS_COMPONENT (component), FALSE);
 
   iface = ATK_COMPONENT_GET_IFACE (component);
 
   if (iface->set_position)
-    (iface->set_position) (component, x, y);
+    return (iface->set_position) (component, x, y, coord_type);
+  else
+    return FALSE;
 }
 
 /**
- *atk_component_set_size:
- *@component: an #AtkComponent
- *@width: width to set for @component
- *@height: height to set for @component
+ * atk_component_set_size:
+ * @component: an #AtkComponent
+ * @width: width to set for @component
+ * @height: height to set for @component
+ *
+ * Set the size of the @component in terms of width and height.
  *
- * Set the size of the @component
+ * Returns: %TRUE or %FALSE whether the size was set or not
  **/
-void
+gboolean
 atk_component_set_size       (AtkComponent    *component,
                               gint            x,
                               gint            y)
 {
   AtkComponentIface *iface = NULL;
-  g_return_if_fail (component != NULL);
-  g_return_if_fail (ATK_IS_COMPONENT (component));
+  g_return_val_if_fail (ATK_IS_COMPONENT (component), FALSE);
 
   iface = ATK_COMPONENT_GET_IFACE (component);
 
   if (iface->set_size)
-    (iface->set_size) (component, x, y);
+    return (iface->set_size) (component, x, y);
+  else
+    return FALSE;
+}
+
+/**
+ * atk_component_scroll_to:
+ * @component: an #AtkComponent
+ * @type: specify where the object should be made visible.
+ *
+ * Makes @component visible on the screen by scrolling all necessary parents.
+ *
+ * Contrary to atk_component_set_position, this does not actually move
+ * @component in its parent, this only makes the parents scroll so that the
+ * object shows up on the screen, given its current position within the parents.
+ *
+ * Returns: whether scrolling was successful.
+ *
+ * Since: 2.30
+ */
+gboolean
+atk_component_scroll_to (AtkComponent  *component,
+                         AtkScrollType  type)
+{
+  AtkComponentIface *iface = NULL;
+  g_return_val_if_fail (ATK_IS_COMPONENT (component), FALSE);
+
+  iface = ATK_COMPONENT_GET_IFACE (component);
+
+  if (iface->scroll_to)
+    return (iface->scroll_to) (component, type);
+
+  return FALSE;
+}
+
+/**
+ * atk_component_scroll_to_point:
+ * @component: an #AtkComponent
+ * @coords: specify whether coordinates are relative to the screen or to the
+ * parent object.
+ * @x: x-position where to scroll to
+ * @y: y-position where to scroll to
+ *
+ * Makes an object visible on the screen at a given position by scrolling all
+ * necessary parents.
+ *
+ * Returns: whether scrolling was successful.
+ *
+ * Since: 2.30
+ */
+gboolean
+atk_component_scroll_to_point (AtkComponent *component,
+                               AtkCoordType  coords,
+                               gint          x,
+                               gint          y)
+{
+  AtkComponentIface *iface = NULL;
+  g_return_val_if_fail (ATK_IS_COMPONENT (component), FALSE);
+
+  iface = ATK_COMPONENT_GET_IFACE (component);
+
+  if (iface->scroll_to_point)
+    return (iface->scroll_to_point) (component, coords, x, y);
+
+  return FALSE;
+}
+
+static gboolean
+atk_component_real_contains (AtkComponent *component,
+                             gint         x,
+                             gint         y,
+                             AtkCoordType coord_type)
+{
+  gint real_x, real_y, width, height;
+
+  real_x = real_y = width = height = 0;
+
+  atk_component_get_extents (component, &real_x, &real_y, &width, &height, coord_type);
+
+  if ((x >= real_x) &&
+      (x < real_x + width) &&
+      (y >= real_y) &&
+      (y < real_y + height))
+    return TRUE;
+  else
+    return FALSE;
 }
 
 static AtkObject* 
-atk_component_real_get_accessible_at_point (AtkComponent *component,
+atk_component_real_ref_accessible_at_point (AtkComponent *component,
                                             gint         x,
-                                            gint         y)
+                                            gint         y,
+                                            AtkCoordType coord_type)
 {
   gint count, i;
 
   count = atk_object_get_n_accessible_children (ATK_OBJECT (component));
 
-  g_return_val_if_fail (count != 0, NULL);
-
   for (i = 0; i < count; i++)
   {
     AtkObject *obj;
@@ -367,9 +726,8 @@ atk_component_real_get_accessible_at_point (AtkComponent *component,
 
     if (obj != NULL)
     {
-      if (atk_component_contains (ATK_COMPONENT (obj), x, y))
+      if (atk_component_contains (ATK_COMPONENT (obj), x, y, coord_type))
       {
-        g_object_unref (obj);
         return obj;
       }
       else
@@ -380,3 +738,52 @@ atk_component_real_get_accessible_at_point (AtkComponent *component,
   }
   return NULL;
 }
+
+static void
+atk_component_real_get_position (AtkComponent *component,
+                                 gint         *x,
+                                 gint         *y,
+                                 AtkCoordType coord_type)
+{
+  gint width, height;
+
+  atk_component_get_extents (component, x, y, &width, &height, coord_type);
+}
+
+static void
+atk_component_real_get_size (AtkComponent *component,
+                             gint         *width,
+                             gint         *height)
+{
+  gint x, y;
+  AtkCoordType coord_type;
+
+  /*
+   * Pick one coordinate type; it does not matter for size
+   */
+  coord_type = ATK_XY_WINDOW;
+
+  atk_component_get_extents (component, &x, &y, width, height, coord_type);
+}
+
+static AtkRectangle *
+atk_rectangle_copy (const AtkRectangle *rectangle)
+{
+  AtkRectangle *result = g_new (AtkRectangle, 1);
+  *result = *rectangle;
+
+  return result;
+}
+
+GType
+atk_rectangle_get_type (void)
+{
+  static GType our_type = 0;
+
+  if (our_type == 0)
+    our_type = g_boxed_type_register_static ("AtkRectangle",
+                                             (GBoxedCopyFunc)atk_rectangle_copy,
+                                             (GBoxedFreeFunc)g_free);
+  return our_type;
+}
+