2009-27-09 Mark Doffman <mark.doffman@codethink.co.uk>
[platform/core/uifw/at-spi2-atk.git] / tests / dummyatk / my-atk-object.c
1
2 #include <stdio.h>
3 #include <atk/atk.h>
4
5 #include "my-atk-object.h"
6
7 static AtkObjectClass *atk_object_parent_class = NULL;
8
9 void my_atk_object_add_child(MyAtkObject* parent, MyAtkObject* child)
10 {
11     g_ptr_array_add(parent->children, child);
12     g_object_ref_sink(child);
13
14     atk_object_set_parent(ATK_OBJECT(child), ATK_OBJECT(parent));
15     
16     g_signal_emit_by_name(parent, "children-changed::add",
17         parent->children->len - 1, child);
18 }
19
20 void my_atk_object_remove_child(MyAtkObject* parent, MyAtkObject* child)
21 {
22     gint i;
23     for(i = parent->children->len - 1; i >= 0; i--)
24     {
25         if(g_ptr_array_index(parent->children, i) == child) break;
26     }
27     if(i < 0)return;
28
29     g_ptr_array_remove_index(parent->children, i);
30     g_object_unref(child);
31     g_signal_emit_by_name(parent, "children-changed::remove",
32         i, child);
33 }
34
35 static void my_atk_object_set_parent(AtkObject *accessible, AtkObject *parent)
36 {
37     g_return_if_fail(parent != NULL);
38
39     MyAtkObject *self = MY_ATK_OBJECT(accessible);
40     AtkObject *parent_old = (atk_object_get_parent(accessible));
41     
42     if(parent_old == parent)
43     {
44         //nothing to do because parent does not change
45         return;
46     }
47     
48     //set field 'parent' in child using 'base-method'
49     atk_object_parent_class->set_parent(accessible, parent);
50     
51     if(parent_old != NULL)
52     {
53         my_atk_object_remove_child((MyAtkObject*)parent_old, self);
54     }
55 }
56
57 static gint my_atk_object_get_n_children(AtkObject *accessible)
58 {
59     return MY_ATK_OBJECT(accessible)->children->len;
60 }
61
62 static AtkObject* my_atk_object_ref_child(AtkObject *accessible, gint i)
63 {
64     MyAtkObject *self = MY_ATK_OBJECT(accessible); 
65     if(i < 0 || i >= self->children->len)
66     {
67         printf("ref_child: Incorrect index of child.\n");
68         return NULL;
69     }
70
71     AtkObject* child = (AtkObject*)
72         g_ptr_array_index(self->children, i);
73
74     return (child == NULL) ? NULL : g_object_ref(child);
75 }
76
77 static gint my_atk_object_get_index_in_parent(AtkObject *accessible)
78 {
79     AtkObject *parent = atk_object_get_parent(accessible);
80     if(parent == NULL) return -1;//no parent
81     
82     MyAtkObject *parent_my = MY_ATK_OBJECT(parent);
83
84     int i = parent_my->children->len;
85     for(; i>=0; i--)
86     {
87         if(g_ptr_array_index(parent_my->children,i) == accessible)
88             break;
89     }
90     if(i < 0)printf("Something wrong in parent-child strucutre.\n");
91     return i;//if error, i will be equal to -1
92 }
93
94 static AtkStateSet *my_atk_object_ref_state_set(AtkObject *accessible)
95 {
96     MyAtkObject *obj = MY_ATK_OBJECT(accessible);
97
98     if (obj->state_set == NULL)
99         obj->state_set = atk_state_set_new();
100     return g_object_ref(G_OBJECT(obj->state_set));
101 }
102
103 static AtkAttributeSet *my_atk_object_get_attributes (AtkObject *accessible)
104 {
105     MyAtkObject *obj = MY_ATK_OBJECT(accessible);
106     AtkAttributeSet *rs = obj->attributes = NULL;
107     AtkAttribute *a, *b, *c;
108
109     a = g_new(AtkAttribute, 1);
110     b = g_new(AtkAttribute, 1);
111     c = g_new(AtkAttribute, 1);
112
113     a->name = g_strdup("foo");
114     a->value = g_strdup("bar");
115     b->name = g_strdup("baz");
116     b->value = g_strdup("qux");
117     c->name = g_strdup("quux");
118     c->value = g_strdup("corge");
119
120     rs = g_slist_append(rs, (gpointer) a); 
121     rs = g_slist_append(rs, (gpointer) b); 
122     rs = g_slist_append(rs, (gpointer) c); 
123 }
124
125 //function, needed in instance_finalize()
126 static void my_unref1(gpointer data, gpointer user_data)
127 {
128     g_object_unref(data);
129 }
130
131 static void my_atk_object_instance_finalize(GObject *obj)
132 {
133     MyAtkObject *self = (MyAtkObject*) obj;
134     //unrefs all children
135     g_ptr_array_foreach(self->children, my_unref1, NULL);
136     //then free array (without frees pointers)
137     g_ptr_array_free(self->children, FALSE);
138     //chain to parent class
139     G_OBJECT_CLASS(atk_object_parent_class)->finalize(obj);
140 }
141
142 void my_atk_object_class_init(gpointer g_class, gpointer g_class_data)
143 {
144     AtkObjectClass *atkObjectClass = (AtkObjectClass*)g_class;
145     
146     ((GObjectClass*)g_class)->finalize = my_atk_object_instance_finalize;
147     //set pointers to new functions in table of virtuals functions
148     atkObjectClass->set_parent = my_atk_object_set_parent;
149     atkObjectClass->get_n_children = my_atk_object_get_n_children;
150     atkObjectClass->ref_child = my_atk_object_ref_child;
151     atkObjectClass->get_index_in_parent = my_atk_object_get_index_in_parent;
152     atkObjectClass->ref_state_set = my_atk_object_ref_state_set;
153     atkObjectClass->get_attributes = my_atk_object_get_attributes;
154
155     atk_object_parent_class = g_type_class_peek_parent(g_class);
156 }
157
158 static void my_atk_object_instance_init(GTypeInstance *obj, gpointer g_class)
159 {
160     MyAtkObject *self = (MyAtkObject*)obj;
161
162     self->children = g_ptr_array_sized_new(10);
163     self->attributes =  g_slist_alloc();
164 }
165
166 GType my_atk_object_get_type()
167 {
168     static GType type = 0;
169     if(type == 0)
170     {
171         static const GTypeInfo typeInfo = 
172         {
173             sizeof(MyAtkObjectClass),
174             NULL, //base_init
175             NULL, //base_finalize
176             my_atk_object_class_init, //class_init
177             NULL, //class_finalize
178             NULL, //class_data
179             sizeof(MyAtkObject),
180             0, //n_preallocs
181             my_atk_object_instance_init //instance_init
182         };
183         type = g_type_register_static(ATK_TYPE_OBJECT,"MyAtkObject",&typeInfo,0);
184     }
185     return type;
186 }