1
/*
2
 * AT-SPI - Assistive Technology Service Provider Interface
3
 * (Gnome Accessibility Project; https://wiki.gnome.org/Accessibility)
4
 *
5
 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
6
 *
7
 * This library is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * This library is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with this library; if not, write to the
19
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20
 * Boston, MA 02110-1301, USA.
21
 */
22

            
23
#include <atk/atk.h>
24
#include <stdio.h>
25

            
26
#include "my-atk-object.h"
27

            
28
GType my_atk_object_get_type (void);
29

            
30
161
G_DEFINE_TYPE (MyAtkObject,
31
               my_atk_object,
32
               ATK_TYPE_OBJECT);
33

            
34
void
35
1434
my_atk_object_add_child (MyAtkObject *parent,
36
                         MyAtkObject *child)
37
{
38
1434
  g_ptr_array_add (parent->children, child);
39
1434
  g_object_ref_sink (child);
40

            
41
1434
  atk_object_set_parent (ATK_OBJECT (child), ATK_OBJECT (parent));
42

            
43
1434
  g_signal_emit_by_name (parent, "children-changed::add",
44
1434
                         parent->children->len - 1,
45
                         child);
46
1434
}
47

            
48
void
49
my_atk_object_remove_child (MyAtkObject *parent,
50
                            MyAtkObject *child)
51
{
52
  gint i;
53
  for (i = parent->children->len - 1; i >= 0; i--)
54
    {
55
      if (g_ptr_array_index (parent->children, i) == child)
56
        break;
57
    }
58
  g_return_if_fail (i < 0);
59
  g_ptr_array_remove_index (parent->children, i);
60
  g_signal_emit_by_name (parent, "children-changed::remove", i, child);
61
}
62

            
63
static void
64
1434
my_atk_object_set_parent (AtkObject *accessible, AtkObject *parent)
65
{
66
1434
  MyAtkObject *self = MY_ATK_OBJECT (accessible);
67
1434
  AtkObject *parent_old = atk_object_get_parent (accessible);
68

            
69
1434
  if (parent_old == parent)
70
    return;
71

            
72
1434
  AtkObjectClass *klass = ATK_OBJECT_CLASS (my_atk_object_parent_class);
73
1434
  klass->set_parent (accessible, parent);
74

            
75
1434
  if (parent_old != NULL)
76
    my_atk_object_remove_child (MY_ATK_OBJECT (parent_old), self);
77
}
78

            
79
static gint
80
3234
my_atk_object_get_n_children (AtkObject *accessible)
81
{
82
3234
  MyAtkObject *self = MY_ATK_OBJECT (accessible);
83
3234
  return self->children->len;
84
}
85

            
86
static AtkObject *
87
4697
my_atk_object_ref_child (AtkObject *accessible, gint i)
88
{
89
4697
  MyAtkObject *self = MY_ATK_OBJECT (accessible);
90

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

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

            
95
4697
  return (child == NULL) ? NULL : g_object_ref (child);
96
}
97

            
98
static gint
99
1428
my_atk_object_get_index_in_parent (AtkObject *accessible)
100
{
101
1428
  AtkObject *parent = atk_object_get_parent (accessible);
102
1428
  if (parent == NULL)
103
136
    return -1; /*root object so no parent*/
104

            
105
1292
  MyAtkObject *parent_my = MY_ATK_OBJECT (parent);
106

            
107
1292
  int i = parent_my->children->len;
108
9600
  for (; i >= 0; i--)
109
    {
110
9600
      if (g_ptr_array_index (parent_my->children, i) == accessible)
111
1292
        break;
112
    }
113

            
114
1292
  g_return_val_if_fail (i >= 0, -1);
115

            
116
1292
  return i;
117
}
118

            
119
static AtkRelationSet *
120
52
my_atk_object_ref_relation_set (AtkObject *accessible)
121
{
122
52
  MyAtkObject *obj = MY_ATK_OBJECT (accessible);
123
52
  if (obj->relation_set == NULL)
124
50
    obj->relation_set = atk_relation_set_new ();
125
52
  return g_object_ref (ATK_RELATION_SET (obj->relation_set));
126
}
127

            
128
static AtkStateSet *
129
3810
my_atk_object_ref_state_set (AtkObject *accessible)
130
{
131
3810
  MyAtkObject *obj = MY_ATK_OBJECT (accessible);
132
3810
  if (obj->state_set == NULL)
133
1595
    obj->state_set = atk_state_set_new ();
134
3810
  return g_object_ref (ATK_STATE_SET (obj->state_set));
135
}
136

            
137
static AtkAttributeSet *
138
9
my_atk_object_get_attributes (AtkObject *accessible)
139
{
140
9
  AtkAttributeSet *attributes = NULL;
141
  AtkAttribute *attr;
142

            
143
9
  attr = g_new0 (AtkAttribute, 1);
144
9
  attr->name = g_strdup ("atspi1");
145
9
  attr->value = g_strdup ("test1");
146
9
  attributes = g_slist_prepend (attributes, attr);
147

            
148
9
  attr = g_new0 (AtkAttribute, 1);
149
9
  attr->name = g_strdup ("atspi2");
150
9
  attr->value = g_strdup ("test2");
151
9
  attributes = g_slist_prepend (attributes, attr);
152

            
153
9
  return attributes;
154
}
155

            
156
static void
157
1596
my_atk_object_init (MyAtkObject *self)
158
{
159
1596
  self->children = g_ptr_array_new_full (10, g_object_unref);
160
1596
}
161

            
162
static void
163
161
my_atk_object_class_init (MyAtkObjectClass *my_class)
164
{
165
161
  AtkObjectClass *object_class = ATK_OBJECT_CLASS (my_class);
166

            
167
161
  object_class->set_parent = my_atk_object_set_parent;
168
161
  object_class->get_n_children = my_atk_object_get_n_children;
169
161
  object_class->ref_child = my_atk_object_ref_child;
170
161
  object_class->get_index_in_parent = my_atk_object_get_index_in_parent;
171
161
  object_class->ref_state_set = my_atk_object_ref_state_set;
172
161
  object_class->get_attributes = my_atk_object_get_attributes;
173
161
  object_class->ref_relation_set = my_atk_object_ref_relation_set;
174
161
}