Blob Blame History Raw
/*
 * AT-SPI - Assistive Technology Service Provider Interface
 * (Gnome Accessibility Project; https://wiki.gnome.org/Accessibility)
 *
 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library 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 <stdio.h>
#include <atk/atk.h>

#include "my-atk-object.h"

GType my_atk_object_get_type (void);

G_DEFINE_TYPE (MyAtkObject,
               my_atk_object,
               ATK_TYPE_OBJECT);

void my_atk_object_add_child (MyAtkObject* parent,
                              MyAtkObject* child)
{
  g_ptr_array_add (parent->children, child);
  g_object_ref_sink (child);

  atk_object_set_parent (ATK_OBJECT (child), ATK_OBJECT (parent));

  g_signal_emit_by_name (parent, "children-changed::add",
                         parent->children->len - 1,
                         child);
}

void my_atk_object_remove_child (MyAtkObject* parent,
                                 MyAtkObject* child)
{
  gint i;
  for (i = parent->children->len - 1; i >= 0; i--) {
    if (g_ptr_array_index (parent->children, i) == child)
      break;
  }
  g_return_if_fail (i < 0);
  g_ptr_array_remove_index (parent->children, i);
  g_signal_emit_by_name (parent, "children-changed::remove", i, child);
}

static void my_atk_object_set_parent(AtkObject *accessible, AtkObject *parent)
{
  MyAtkObject *self = MY_ATK_OBJECT (accessible);
  AtkObject *parent_old = atk_object_get_parent (accessible);

  if (parent_old == parent)
    return;

  AtkObjectClass *klass = ATK_OBJECT_CLASS (my_atk_object_parent_class);
  klass->set_parent (accessible, parent);

  if (parent_old != NULL)
    my_atk_object_remove_child (MY_ATK_OBJECT (parent_old), self);
}

static gint my_atk_object_get_n_children (AtkObject *accessible)
{
  MyAtkObject *self = MY_ATK_OBJECT (accessible);
  return self->children->len;
}

static AtkObject* my_atk_object_ref_child (AtkObject *accessible, gint i)
{
  MyAtkObject *self = MY_ATK_OBJECT (accessible);

  g_return_val_if_fail (i >= 0 || i <= self->children->len, NULL);

  AtkObject* child = ATK_OBJECT (g_ptr_array_index (self->children, i));

  return (child == NULL) ? NULL : g_object_ref (child);
}

static gint my_atk_object_get_index_in_parent (AtkObject *accessible)
{
  AtkObject *parent = atk_object_get_parent (accessible);
  if (parent == NULL) return -1; /*root object so no parent*/

  MyAtkObject *parent_my = MY_ATK_OBJECT (parent);

  int i = parent_my->children->len;
  for (; i>=0; i--) {
    if (g_ptr_array_index (parent_my->children,i) == accessible)
      break;
  }

  g_return_val_if_fail (i>=0, -1);

  return i;
}

static AtkRelationSet *my_atk_object_ref_relation_set (AtkObject* accessible)
{
  MyAtkObject *obj = MY_ATK_OBJECT (accessible);
  if (obj->relation_set == NULL)
    obj->relation_set = atk_relation_set_new ();
  return g_object_ref (G_OBJECT (obj->relation_set));
}

static AtkStateSet *my_atk_object_ref_state_set (AtkObject *accessible)
{
  MyAtkObject *obj = MY_ATK_OBJECT (accessible);
  if (obj->state_set == NULL)
    obj->state_set = atk_state_set_new ();
  return g_object_ref (G_OBJECT (obj->state_set));
}

static AtkAttributeSet *my_atk_object_get_attributes (AtkObject *accessible)
{
  AtkAttributeSet *attributes;
  AtkAttribute *attr;

  attr = g_malloc (sizeof (AtkAttribute));
  attr->name = g_strdup ("atspi");
  attr->value = g_strdup ("test");

  attributes = g_slist_append (NULL, attr);

  return attributes;
}

static void my_atk_object_init (MyAtkObject *self)
{
  self->children = g_ptr_array_new_full (10, g_object_unref);
}

static void my_atk_object_class_init (MyAtkObjectClass *my_class)
{
  AtkObjectClass *object_class = ATK_OBJECT_CLASS (my_class);

  object_class->set_parent = my_atk_object_set_parent;
  object_class->get_n_children = my_atk_object_get_n_children;
  object_class->ref_child = my_atk_object_ref_child;
  object_class->get_index_in_parent = my_atk_object_get_index_in_parent;
  object_class->ref_state_set = my_atk_object_ref_state_set;
  object_class->get_attributes = my_atk_object_get_attributes;
  object_class->ref_relation_set = my_atk_object_ref_relation_set;

}