42bb1b5f40bd7745cc676da2ee2661add4c64704
[platform/upstream/atk.git] / atk / atkobject.c
1 /* ATK -  Accessibility Toolkit
2  * Copyright 2001 Sun Microsystems Inc.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 #include <glib-object.h>
21
22 #include "atk.h"
23
24 #define NUM_POSSIBLE_STATES                     (sizeof(AtkStateMask)*8)
25
26 /* New GObject properties registered by AtkObject */
27 enum
28 {
29   PROP_0,  /* gobject convention */
30
31   PROP_NAME,
32   PROP_DESCRIPTION,
33   PROP_PARENT,      /* ancestry has changed */
34   PROP_CHILD,       /* children have changed in number or identity */
35   PROP_ROLE,        /* AtkRole has changed  */
36   PROP_STATE,       /* AtkState has changed */
37   PROP_TEXT,        /* Used only by AtkText implementors */
38   PROP_CARET,       /* Used only by AtkText implementors */
39   PROP_LAST         /* gobject convention */
40 };
41
42 enum {
43   CHILDREN_CHANGED,
44   LAST_SIGNAL
45 };
46
47 struct _AtkRelationSet
48 {
49   GArray     *relations;
50 };
51
52 struct _AtkRelation
53 {
54   GArray              *target;
55   AtkRelationType     relationship;
56 };
57
58
59 typedef struct
60 {
61   GObject  object;
62 } _AtkIfaceImplementor;
63
64 static void            atk_object_class_init       (AtkObjectClass  *klass);
65 static void            atk_object_init             (AtkObject       *accessible,
66                                                     AtkObjectClass  *klass);
67 static AtkRelationSet* atk_object_real_get_relation_set (AtkObject *accessible);
68
69 static void            atk_object_real_set_property(GObject         *object,
70                                                     guint            prop_id,
71                                                     const GValue    *value,
72                                                     GParamSpec      *pspec);
73 static void            atk_object_real_get_property(GObject         *object,
74                                                     guint            prop_id,
75                                                     GValue          *value,
76                                                     GParamSpec      *pspec);
77 static void            atk_object_finalize         (GObject         *object);
78
79 static gchar* state_names[NUM_POSSIBLE_STATES];
80
81 #if 0
82 static guint atk_object_signals[LAST_SIGNAL] = { 0, };
83 #endif
84
85 static gpointer parent_class = NULL;
86
87 static const gchar* atk_object_name_property_name = "accessible-name";
88 static const gchar* atk_object_name_property_state = "accessible-state";
89 static const gchar* atk_object_name_property_description = "accessible-description";
90
91 GType
92 atk_object_get_type (void)
93 {
94   static GType type = 0;
95
96   if (!type)
97     {
98       static const GTypeInfo typeInfo =
99       {
100         sizeof (AtkObjectClass),
101         (GBaseInitFunc) NULL,
102         (GBaseFinalizeFunc) NULL,
103         (GClassInitFunc) atk_object_class_init,
104         (GClassFinalizeFunc) NULL,
105         NULL,
106         sizeof (AtkObject),
107         0,
108         (GInstanceInitFunc) atk_object_init,
109       } ;
110       type = g_type_register_static (G_TYPE_OBJECT, "AtkObject", &typeInfo, 0) ;
111     }
112   return type;
113 }
114
115 static void
116 atk_object_class_init (AtkObjectClass *klass)
117 {
118   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
119
120   parent_class = g_type_class_ref (G_TYPE_OBJECT);
121
122   gobject_class->set_property = atk_object_real_set_property;
123   gobject_class->get_property = atk_object_real_get_property;
124   gobject_class->finalize = atk_object_finalize;
125
126   klass->get_relation_set = atk_object_real_get_relation_set;
127
128   state_names[ATK_STATE_ARMED]           = "armed";
129   state_names[ATK_STATE_BUSY]            = "busy";
130   state_names[ATK_STATE_CHECKED]         = "checked";
131   state_names[ATK_STATE_COLLAPSED]       = "collapsed";
132   state_names[ATK_STATE_EDITABLE]        = "editable";
133   state_names[ATK_STATE_EXPANDABLE]      = "expandable";
134   state_names[ATK_STATE_EXPANDED]        = "expanded";
135   state_names[ATK_STATE_FOCUSABLE]       = "focusable";
136   state_names[ATK_STATE_FOCUSED]         = "focused";
137   state_names[ATK_STATE_HORIZONTAL]      = "horizontal";
138   state_names[ATK_STATE_ICONIFIED]       = "iconified";
139   state_names[ATK_STATE_MODAL]           = "modal";
140   state_names[ATK_STATE_MULTI_LINE]      = "multi-line";
141   state_names[ATK_STATE_MULTISELECTABLE] = "multiselectable";
142   state_names[ATK_STATE_OPAQUE]          = "opaque";
143   state_names[ATK_STATE_PRESSED]         = "pressed";
144   state_names[ATK_STATE_RESIZABLE]       = "resizeable";
145   state_names[ATK_STATE_SELECTABLE]      = "selectable";
146   state_names[ATK_STATE_SELECTED]        = "selected";
147   state_names[ATK_STATE_SENSITIVE]       = "sensitive";
148   state_names[ATK_STATE_SHOWING]         = "showing";
149   state_names[ATK_STATE_SINGLE_LINE]     = "single-line";
150   state_names[ATK_STATE_TRANSIENT]       = "transient";
151   state_names[ATK_STATE_VERTICAL]        = "vertical";
152   state_names[ATK_STATE_VISIBLE]         = "visible";
153
154   klass->children_changed = NULL;
155
156   g_object_class_install_property (gobject_class,
157                                    PROP_NAME,
158                                    g_param_spec_string (atk_object_name_property_name,
159                                                         "Accessible Name",
160                                                         "Object instance\'s name formatted for "
161                                                            "assistive technology access",
162                                                         NULL,
163                                                         G_PARAM_READWRITE));
164   g_object_class_install_property (gobject_class,
165                                    PROP_DESCRIPTION,
166                                    g_param_spec_string (atk_object_name_property_description,
167                                                         "Accessible Description",
168                                                         "Description of an object, formatted for "
169                                                         "assistive technology access",
170                                                         NULL,
171                                                         G_PARAM_READWRITE));
172   g_object_class_install_property (gobject_class,
173                                    PROP_STATE,
174                                    g_param_spec_int    (atk_object_name_property_state,
175                                                         "Accessible State",
176                                                         "The current state of this object "
177                                                         "or its UI component",
178                                                         0,
179                                                         G_MAXINT,
180                                                         0,
181                                                         G_PARAM_WRITABLE));
182 #if 0
183   /* register some properties - these could be change signals instead */
184   g_object_class_install_property (gobject_class,
185                                    PROP_PARENT,
186                                    g_param_spec_ccallback ("accessible_parent", "Accessible Parent",
187                                                            "First accessible ancestor (container or object) "
188                                                            "which this object is a descendant of",
189                                                            G_PARAM_READWRITE));
190
191
192   g_object_class_install_property (gobject_class,
193                                    PROP_ROLE,
194                                    g_param_spec_ccallback ("accessible_role", "Accessible Role",
195                                                            "The user-interface role of this object",
196                                                            G_PARAM_READWRITE));
197   g_object_class_install_property (gobject_class,
198                                    PROP_STATE,
199                                    g_param_spec_ccallback ("accessible_state", "Accessible State",
200                                                            "The current state of this object "
201                                                            "or its UI component",
202                                                            G_PARAM_READWRITE));
203   g_object_class_install_property (gobject_class,
204                                    PROP_TEXT,
205                                    g_param_spec_ccallback ("accessible_text", "Accessible Text",
206                                                            "This object\'s accessible text contents",
207                                                            G_PARAM_READWRITE));
208   g_object_class_install_property (gobject_class,
209                                    PROP_CARET,
210                                    g_param_spec_ccallback ("accessible_caret", "Accessible Text Caret",
211                                                            "The current text caret state and position "
212                                                            "for this component",
213                                                            G_PARAM_READWRITE));
214   gaccessible_signals[CHILDREN_CHANGED] =
215     g_signal_newc ("accessible_children_changed",
216                    G_TYPE_FROM_CLASS (klass),
217                    G_SIGNAL_RUN_LAST,
218                    G_STRUCT_OFFSET (AtkObjectClass, children_changed), /* still need to declare and define this func */
219                    NULL,
220                    g_cclosure_marshal_VOID__UINT_POINTER,
221                    G_TYPE_NONE,
222                    2, G_TYPE_UINT, ATK_TYPE_OBJECT);
223 #endif
224 }
225
226 static void
227 atk_object_init  (AtkObject        *accessible,
228                   AtkObjectClass   *klass)
229 {
230     accessible->relation_set = g_malloc (sizeof (AtkRelationSet));
231     g_return_if_fail (accessible->relation_set != NULL);
232     accessible->relation_set->relations = NULL;
233 }
234
235 GType
236 atk_object_iface_get_type (void)
237 {
238   static GType type = 0;
239
240   if (!type)
241     {
242       static const GTypeInfo typeInfo =
243       {
244         sizeof (AtkObjectIface),
245         (GBaseInitFunc) NULL,
246         (GBaseFinalizeFunc) NULL,
247       } ;
248
249       type = g_type_register_static (G_TYPE_INTERFACE, "AtkObjectIface", &typeInfo, 0) ;
250     }
251
252   return type;
253 }
254
255 G_CONST_RETURN gchar*
256 atk_object_get_name (AtkObject *accessible)
257 {
258   AtkObjectClass *klass;
259
260   g_return_val_if_fail ((accessible != NULL), NULL);
261   g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
262
263   klass = ATK_OBJECT_GET_CLASS (accessible);
264   if (klass->get_name)
265     return (klass->get_name) (accessible);
266   else
267     return NULL;
268 }
269
270 G_CONST_RETURN gchar*
271 atk_object_get_description (AtkObject *accessible)
272 {
273   AtkObjectClass *klass;
274
275   g_return_val_if_fail ((accessible != NULL), NULL);
276   g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
277
278   klass = ATK_OBJECT_GET_CLASS (accessible);
279   if (klass->get_description)
280     return (klass->get_description) (accessible);
281   else
282     return NULL;
283 }
284
285 AtkObject*
286 atk_object_get_parent (AtkObject *accessible)
287 {
288   AtkObjectClass *klass;
289
290   g_return_val_if_fail ((accessible != NULL), NULL);
291   g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
292
293   klass = ATK_OBJECT_GET_CLASS (accessible);
294   if (klass->get_parent)
295     return (klass->get_parent) (accessible);
296   else
297     return NULL;
298 }
299
300 gint
301 atk_object_get_n_accessible_children (AtkObject *accessible)
302 {
303   AtkObjectClass *klass;
304
305   g_return_val_if_fail ((accessible != NULL), 0);
306   g_return_val_if_fail (ATK_IS_OBJECT (accessible), 0);
307
308   klass = ATK_OBJECT_GET_CLASS (accessible);
309   if (klass->get_n_children)
310     return (klass->get_n_children) (accessible);
311   else
312     return 0;
313 }
314
315 AtkObject*
316 atk_object_ref_accessible_child (AtkObject   *accessible,
317                                  gint        i)
318 {
319   AtkObjectClass *klass;
320
321   g_return_val_if_fail ((accessible != NULL), NULL);
322   g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
323
324   klass = ATK_OBJECT_GET_CLASS (accessible);
325   if (klass->ref_child)
326     return (klass->ref_child) (accessible, i);
327   else
328     return NULL;
329 }
330
331 AtkRelationSet*
332 atk_object_get_relation_set (AtkObject *accessible)
333 {
334   AtkObjectClass *klass;
335
336   g_return_val_if_fail ((accessible != NULL), NULL);
337   g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
338
339   klass = ATK_OBJECT_GET_CLASS (accessible);
340   if (klass->get_relation_set)
341     return (klass->get_relation_set) (accessible);
342   else
343     return NULL;
344 }
345
346 AtkRole
347 atk_role_register (gchar *name)
348 {
349   /* TODO: associate name with new type */
350   static guint type = ATK_ROLE_LAST_DEFINED;
351   return (++type);
352 }
353
354 AtkRole
355 atk_object_get_role (AtkObject *accessible) {
356   AtkObjectClass *klass;
357
358   g_return_val_if_fail ((accessible != NULL), ATK_ROLE_UNKNOWN);
359   g_return_val_if_fail (ATK_IS_OBJECT (accessible), ATK_ROLE_UNKNOWN);
360
361   klass = ATK_OBJECT_GET_CLASS (accessible);
362   if (klass->get_role)
363     return (klass->get_role) (accessible);
364   else
365     return ATK_ROLE_UNKNOWN;
366 }
367
368 AtkStateType
369 atk_state_type_register (gchar *name)
370 {
371   /* TODO: associate name with new type */
372   static guint type = ATK_STATE_LAST_DEFINED;
373   if (type < NUM_POSSIBLE_STATES) {
374     return (++type);
375   }
376   return ATK_STATE_INVALID; /* caller needs to check */
377 }
378
379 AtkState
380 atk_object_get_state (AtkObject *accessible) {
381   AtkObjectClass *klass;
382
383   g_return_val_if_fail ((accessible != NULL), 0);
384   g_return_val_if_fail (ATK_IS_OBJECT (accessible), 0);
385
386   klass = ATK_OBJECT_GET_CLASS (accessible);
387   if (klass->get_state)
388     return (klass->get_state) (accessible);
389   else
390     return 0;
391 }
392
393 gint
394 atk_object_get_index_in_parent (AtkObject *accessible)
395 {
396   AtkObjectClass *klass;
397
398   g_return_val_if_fail ((accessible != NULL), -1);
399   g_return_val_if_fail (ATK_OBJECT (accessible), -1);
400
401   klass = ATK_OBJECT_GET_CLASS (accessible);
402   if (klass->get_index_in_parent)
403     return (klass->get_index_in_parent) (accessible);
404   else
405     return -1;
406 }
407
408 void
409 atk_object_set_name (AtkObject    *accessible,
410                      const gchar  *name)
411 {
412   AtkObjectClass *klass;
413
414   g_return_if_fail ((accessible != NULL));
415   g_return_if_fail (ATK_IS_OBJECT (accessible));
416   g_return_if_fail ((name != NULL));
417
418   klass = ATK_OBJECT_GET_CLASS (accessible);
419   if (klass->set_name)
420   {
421     (klass->set_name) (accessible, name);
422     g_object_notify (G_OBJECT (accessible), atk_object_name_property_name);
423   }
424 }
425
426 void
427 atk_object_set_description (AtkObject   *accessible,
428                             const gchar *description)
429 {
430   AtkObjectClass *klass;
431
432   g_return_if_fail ((accessible != NULL));
433   g_return_if_fail (ATK_IS_OBJECT (accessible));
434   g_return_if_fail ((description != NULL));
435
436   klass = ATK_OBJECT_GET_CLASS (accessible);
437   if (klass->set_description)
438   {
439     (klass->set_description) (accessible, description);
440     g_object_notify (G_OBJECT (accessible), atk_object_name_property_description);
441   }
442 }
443
444 void
445 atk_object_set_parent (AtkObject *accessible,
446                        AtkObject *parent)
447 {
448   AtkObjectClass *klass;
449
450   g_return_if_fail ((accessible != NULL));
451   g_return_if_fail (ATK_IS_OBJECT (accessible));
452
453   klass = ATK_OBJECT_GET_CLASS (accessible);
454   if (klass->set_parent)
455     (klass->set_parent) (accessible, parent);
456 }
457
458 void
459 atk_object_set_role (AtkObject *accessible, 
460                      AtkRole   role)
461 {
462   AtkObjectClass *klass;
463
464   g_return_if_fail ((accessible != NULL));
465   g_return_if_fail (ATK_IS_OBJECT (accessible));
466
467   klass = ATK_OBJECT_GET_CLASS (accessible);
468   if (klass->set_role)
469     (klass->set_role) (accessible, role);
470 }
471
472 guint
473 atk_object_connect_property_change_handler (AtkObject *accessible,
474                                             AtkPropertyChangeHandler *handler)
475 {
476   AtkObjectClass *klass;
477
478   g_return_val_if_fail ((accessible != NULL), 0);
479   g_return_val_if_fail (ATK_IS_OBJECT (accessible), 0);
480   g_return_val_if_fail ((handler != NULL), 0);
481
482   klass = ATK_OBJECT_GET_CLASS (accessible);
483   if (klass->connect_property_change_handler)
484     return (klass->connect_property_change_handler) (accessible, handler);
485   else
486     return 0;
487 }
488
489 void
490 atk_object_remove_property_change_handler  (AtkObject *accessible,
491                                             guint      handler_id)
492 {
493   AtkObjectClass *klass;
494
495   g_return_if_fail ((accessible != NULL));
496   g_return_if_fail (ATK_IS_OBJECT (accessible));
497
498   klass = ATK_OBJECT_GET_CLASS (accessible);
499   if (klass->remove_property_change_handler)
500     (klass->remove_property_change_handler) (accessible, handler_id);
501 }
502
503 AtkRelationType
504 atk_relation_type_register (gchar *name)
505 {
506   /* TODO: associate name with new type */
507   static guint type = ATK_RELATION_LAST_DEFINED;
508   return (++type);
509 }
510
511 AtkRelation*
512 atk_relation_new (GArray          *target,
513                   AtkRelationType relationship)
514 {
515   AtkRelation* relation;
516   g_return_val_if_fail ((target != NULL), NULL);
517
518   relation = (AtkRelation *) g_malloc (sizeof (AtkRelation));
519
520   g_return_val_if_fail ((relation != NULL), NULL);
521
522   relation->target = target;
523   relation->relationship = relationship;
524
525   return relation;
526 }
527
528 gboolean
529 atk_relation_set_contains (AtkRelationSet   *set,
530                            AtkRelationType  relationship)
531 {
532   GArray *array_item;
533   AtkRelation *item;
534   gint  i;
535
536   g_return_val_if_fail ((set != NULL), FALSE);
537
538   array_item = set->relations;
539   if (array_item == NULL)
540     return FALSE;
541   for (i = 0; i < array_item->len; i++)
542   {
543     item = g_array_index (array_item, AtkRelation*, i);
544     if (item->relationship == relationship)
545       return TRUE;
546   }
547   return FALSE;
548 }
549
550 void
551 atk_relation_set_remove (AtkRelationSet *set,
552                          AtkRelation    *relation)
553 {
554   GArray *array_item;
555   AtkRelation *item;
556   gint  i;
557
558   g_return_if_fail (set != NULL);
559   g_return_if_fail (relation != NULL);
560
561   array_item = set->relations;
562   if (array_item == NULL)
563     return;
564   for (i = 0; i < array_item->len; i++)
565   {
566     item = g_array_index (array_item, AtkRelation*, i);
567     if (item == relation)
568     {
569       g_array_remove_index (array_item, i);
570       return;
571     }
572   }
573 }
574
575 void
576 atk_relation_set_add (AtkRelationSet *set,
577                       AtkRelation    *relation)
578 {
579   g_return_if_fail (set != NULL);
580   g_return_if_fail (relation != NULL);
581
582   if (set->relations == NULL)
583   {
584     set->relations = g_array_new (FALSE, TRUE, sizeof (AtkRelation));
585   }
586   set->relations = g_array_append_val (set->relations, relation);
587 }
588
589 gint
590 atk_relation_set_get_n_relations (AtkRelationSet *set)
591 {
592   g_return_val_if_fail (set != NULL, 0);
593
594   if (set->relations == NULL)
595     return 0;
596
597   return set->relations->len;
598 }
599
600 AtkRelation*
601 atk_relation_set_get_relation (AtkRelationSet *set,
602                                gint           i)
603 {
604   GArray *array_item;
605   AtkRelation* item;
606
607   g_return_val_if_fail (set != NULL, NULL);
608   g_return_val_if_fail (i >= 0, NULL);
609
610   array_item = set->relations;
611   if (array_item == NULL)
612     return NULL;
613   item = g_array_index (array_item, AtkRelation*, i);
614   if (item == NULL)
615     return NULL;
616
617   return item;
618 }
619
620 AtkRelation*
621 atk_relation_set_get_relation_by_type (AtkRelationSet  *set,
622                                        AtkRelationType relationship)
623 {
624   GArray *array_item;
625   AtkRelation *item;
626   gint i;
627
628   g_return_val_if_fail (set != NULL, NULL);
629
630   array_item = set->relations;
631   if (array_item == NULL)
632     return NULL;
633   for (i = 0; i < array_item->len; i++)
634   {
635     item = g_array_index (array_item, AtkRelation*, i);
636     if (item->relationship == relationship)
637       return item;
638   }
639   return NULL;
640 }
641
642 AtkRelationType
643 atk_relation_get_type (AtkRelation *relation)
644 {
645   g_return_val_if_fail (relation != NULL, 0);
646   return relation->relationship;
647 }
648
649 GArray*
650 atk_relation_get_target (AtkRelation *relation)
651 {
652   g_return_val_if_fail (relation != NULL, 0);
653   return relation->target;
654 }
655
656 gchar*
657 atk_state_mask_get_name (AtkStateMask state)
658 {
659   gint n;
660
661   if (state == 0)
662     return NULL;
663
664   for (n=0; n<NUM_POSSIBLE_STATES; ++n)
665     {
666       /* fall through and return null if multiple bits are set */
667       if (state == (1 << n)) return state_names[n];
668     }
669
670   return NULL;
671 }
672
673 AtkStateMask
674 atk_state_mask_for_name (gchar *name)
675 {
676   gint i;
677
678   g_return_val_if_fail ((strlen(name)>0), 0);
679   for (i=0; i<NUM_POSSIBLE_STATES; ++i)
680     {
681       if (!strcmp(name, state_names[i])) return ATK_STATE(i);
682     }
683   return 0;
684 }
685
686 /**
687  * Return a reference to an object's AtkObject implementation, if
688  * the object implements AtkObjectIface.
689  * @object: The GObject instance which should implement #AtkObjectIface
690  * if a non-null return value is required.
691  */
692 AtkObject *
693 atk_object_ref_accessible (AtkIfaceImplementor *object)
694 {
695   AtkObjectIface     *iface;
696   AtkObject          *accessible = NULL;
697
698   g_return_val_if_fail ((object != NULL), NULL);
699   g_return_val_if_fail ((iface = ATK_OBJECT_GET_IFACE (object)), NULL );
700
701   if (iface != NULL) accessible =  (*(iface->ref_accessible)) (object) ;
702
703   g_return_val_if_fail ((accessible != NULL), NULL);
704
705   return ATK_OBJECT (accessible) ;
706 }
707
708 AtkRelationSet*
709 atk_object_real_get_relation_set (AtkObject *accessible)
710 {
711     return accessible->relation_set;
712 }
713
714 static void
715 atk_object_real_set_property (GObject      *object,
716                          guint         prop_id,
717                          const GValue *value,
718                          GParamSpec   *pspec)
719 {
720   AtkObject *accessible;
721
722   accessible = ATK_OBJECT (object);
723
724   switch (prop_id)
725   {
726     case PROP_NAME:
727       atk_object_set_name (accessible, g_value_get_string (value));
728       break;
729     case PROP_DESCRIPTION:
730       atk_object_set_description (accessible, g_value_get_string (value));
731       break;
732     case PROP_STATE:
733       g_print ("This interface does not support setting the state of an accessible object\n");
734       break;
735     default:
736       break;
737   }
738 }
739
740 static void
741 atk_object_real_get_property (GObject      *object,
742                          guint         prop_id,
743                          GValue       *value,
744                          GParamSpec   *pspec)
745 {
746   AtkObject *accessible;
747
748   accessible = ATK_OBJECT (object);
749
750   switch (prop_id)
751   {
752     case PROP_NAME:
753       g_value_set_string (value, atk_object_get_name (accessible));
754       break;
755     case PROP_DESCRIPTION:
756       g_value_set_string (value, atk_object_get_description (accessible));
757       break;
758     case PROP_STATE:
759       g_value_set_int (value, atk_object_get_state (accessible));
760       break;
761     default:
762       break;
763   }
764 }
765
766 static void
767 atk_object_finalize (GObject *object)
768 {
769   AtkObject        *accessible;
770   GArray           *relations;
771
772   g_return_if_fail (ATK_IS_OBJECT (object));
773
774   accessible = ATK_OBJECT (object);
775
776   g_free (accessible->name);
777   g_free (accessible->description);
778
779   /*
780    * Free memory allocated for relations and relation sets;
781    */
782   relations = accessible->relation_set->relations;
783   if (relations)
784   {
785     gint        len = relations->len;
786     gint        i;
787     AtkRelation *relation;
788
789     for (i = 0; i < len; i++)
790     {
791       relation = g_array_index (relations, AtkRelation*, i);
792       g_array_free (relation->target, TRUE);
793     }
794     g_array_free (relations, TRUE);
795   }
796   g_free (accessible->relation_set);
797
798   G_OBJECT_CLASS (parent_class)->finalize (object);
799 }