Fix memory leak. (bug #124877)
[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 <string.h>
21
22 #include <glib-object.h>
23
24 #ifdef G_OS_WIN32
25 #define STRICT
26 #include <windows.h>
27 #undef STRICT
28 #undef FOCUS_EVENT              /* <windows.h> pollutes the namespace
29                                  * like a six hundred pound gorilla */
30 #endif
31
32 #include "atk.h"
33 #include "atkmarshal.h"
34 #include "atk-enum-types.h"
35 #include "atkintl.h"
36
37 GPtrArray *extra_roles = NULL;
38
39 enum
40 {
41   PROP_0,  /* gobject convention */
42
43   PROP_NAME,
44   PROP_DESCRIPTION,
45   PROP_PARENT,      /* ancestry has changed */
46   PROP_VALUE,
47   PROP_ROLE,
48   PROP_LAYER,
49   PROP_MDI_ZORDER,
50   PROP_TABLE_CAPTION,
51   PROP_TABLE_COLUMN_DESCRIPTION,
52   PROP_TABLE_COLUMN_HEADER,
53   PROP_TABLE_ROW_DESCRIPTION,
54   PROP_TABLE_ROW_HEADER,
55   PROP_TABLE_SUMMARY,
56   PROP_TABLE_CAPTION_OBJECT,
57   PROP_LAST         /* gobject convention */
58 };
59
60 enum {
61   CHILDREN_CHANGED,
62   FOCUS_EVENT,
63   PROPERTY_CHANGE,
64   STATE_CHANGE,
65   VISIBLE_DATA_CHANGED,
66   ACTIVE_DESCENDANT_CHANGED,
67   
68   LAST_SIGNAL
69 };
70
71 static void            atk_object_class_init        (AtkObjectClass  *klass);
72 static void            atk_object_init              (AtkObject       *accessible,
73                                                      AtkObjectClass  *klass);
74 static AtkRelationSet* atk_object_real_ref_relation_set 
75                                                     (AtkObject       *accessible);
76 static void            atk_object_real_initialize   (AtkObject       *accessible,
77                                                      gpointer        data);
78 static void            atk_object_real_set_property (GObject         *object,
79                                                      guint            prop_id,
80                                                      const GValue    *value,
81                                                      GParamSpec      *pspec);
82 static void            atk_object_real_get_property (GObject         *object,
83                                                      guint            prop_id,
84                                                      GValue          *value,
85                                                      GParamSpec      *pspec);
86 static void            atk_object_finalize          (GObject         *object);
87 static G_CONST_RETURN gchar*
88                        atk_object_real_get_name     (AtkObject       *object);
89 static G_CONST_RETURN gchar*
90                        atk_object_real_get_description    
91                                                    (AtkObject       *object);
92 static AtkObject*      atk_object_real_get_parent  (AtkObject       *object);
93 static AtkRole         atk_object_real_get_role    (AtkObject       *object);
94 static AtkLayer        atk_object_real_get_layer   (AtkObject       *object);
95 static AtkStateSet*    atk_object_real_ref_state_set
96                                                    (AtkObject       *object);
97 static void            atk_object_real_set_name    (AtkObject       *object,
98                                                     const gchar     *name);
99 static void            atk_object_real_set_description
100                                                    (AtkObject       *object,
101                                                     const gchar     *description);
102 static void            atk_object_real_set_parent  (AtkObject       *object,
103                                                     AtkObject       *parent);
104 static void            atk_object_real_set_role    (AtkObject       *object,
105                                                     AtkRole         role);
106 static guint           atk_object_real_connect_property_change_handler
107                                                    (AtkObject       *obj,
108                                                     AtkPropertyChangeHandler
109                                                                     *handler);
110 static void            atk_object_real_remove_property_change_handler
111                                                    (AtkObject       *obj,
112                                                     guint           handler_id);
113 static void            atk_object_notify           (GObject         *obj,
114                                                     GParamSpec      *pspec);
115
116
117 static guint atk_object_signals[LAST_SIGNAL] = { 0, };
118
119 static gpointer parent_class = NULL;
120
121 static const gchar* atk_object_name_property_name = "accessible-name";
122 static const gchar* atk_object_name_property_description = "accessible-description";
123 static const gchar* atk_object_name_property_parent = "accessible-parent";
124 static const gchar* atk_object_name_property_value = "accessible-value";
125 static const gchar* atk_object_name_property_role = "accessible-role";
126 static const gchar* atk_object_name_property_component_layer = "accessible-component-layer";
127 static const gchar* atk_object_name_property_component_mdi_zorder = "accessible-component-mdi-zorder";
128 static const gchar* atk_object_name_property_table_caption = "accessible-table-caption";
129 static const gchar* atk_object_name_property_table_column_description = "accessible-table-column-description";
130 static const gchar* atk_object_name_property_table_column_header = "accessible-table-column-header";
131 static const gchar* atk_object_name_property_table_row_description = "accessible-table-row-description";
132 static const gchar* atk_object_name_property_table_row_header = "accessible-table-row-header";
133 static const gchar* atk_object_name_property_table_summary = "accessible-table-summary";
134 static const gchar* atk_object_name_property_table_caption_object = "accessible-table-caption-object";
135
136 GType
137 atk_object_get_type (void)
138 {
139   static GType type = 0;
140
141   if (!type)
142     {
143       static const GTypeInfo typeInfo =
144       {
145         sizeof (AtkObjectClass),
146         (GBaseInitFunc) NULL,
147         (GBaseFinalizeFunc) NULL,
148         (GClassInitFunc) atk_object_class_init,
149         (GClassFinalizeFunc) NULL,
150         NULL,
151         sizeof (AtkObject),
152         0,
153         (GInstanceInitFunc) atk_object_init,
154       } ;
155       type = g_type_register_static (G_TYPE_OBJECT, "AtkObject", &typeInfo, 0) ;
156     }
157   return type;
158 }
159
160 static void
161 atk_object_class_init (AtkObjectClass *klass)
162 {
163   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
164
165   parent_class = g_type_class_peek_parent (klass);
166
167   gobject_class->set_property = atk_object_real_set_property;
168   gobject_class->get_property = atk_object_real_get_property;
169   gobject_class->finalize = atk_object_finalize;
170   gobject_class->notify = atk_object_notify;
171
172   klass->get_name = atk_object_real_get_name;
173   klass->get_description = atk_object_real_get_description;
174   klass->get_parent = atk_object_real_get_parent;
175   klass->get_n_children = NULL;
176   klass->ref_child = NULL;
177   klass->get_index_in_parent = NULL;
178   klass->ref_relation_set = atk_object_real_ref_relation_set;
179   klass->get_role = atk_object_real_get_role;
180   klass->get_layer = atk_object_real_get_layer;
181   klass->get_mdi_zorder = NULL;
182   klass->initialize = atk_object_real_initialize;
183   klass->ref_state_set = atk_object_real_ref_state_set;
184   klass->set_name = atk_object_real_set_name;
185   klass->set_description = atk_object_real_set_description;
186   klass->set_parent = atk_object_real_set_parent;
187   klass->set_role = atk_object_real_set_role;
188   klass->connect_property_change_handler = 
189          atk_object_real_connect_property_change_handler;
190   klass->remove_property_change_handler = 
191          atk_object_real_remove_property_change_handler;
192
193   /*
194    * We do not define default signal handlers here
195    */
196   klass->children_changed = NULL;
197   klass->focus_event = NULL;
198   klass->property_change = NULL;
199   klass->visible_data_changed = NULL;
200   klass->active_descendant_changed = NULL;
201
202   g_object_class_install_property (gobject_class,
203                                    PROP_NAME,
204                                    g_param_spec_string (atk_object_name_property_name,
205                                                         "Accessible Name",
206                                                         "Object instance\'s name formatted for "
207                                                            "assistive technology access",
208                                                         NULL,
209                                                         G_PARAM_READWRITE));
210   g_object_class_install_property (gobject_class,
211                                    PROP_DESCRIPTION,
212                                    g_param_spec_string (atk_object_name_property_description,
213                                                         "Accessible Description",
214                                                         "Description of an object, formatted for "
215                                                         "assistive technology access",
216                                                         NULL,
217                                                         G_PARAM_READWRITE));
218   g_object_class_install_property (gobject_class,
219                                    PROP_PARENT,
220                                    g_param_spec_object (atk_object_name_property_parent,
221                                                         "Accessible Parent",
222                                                         "Is used to notify that the parent has changed ",
223                                                         ATK_TYPE_OBJECT,
224                                                         G_PARAM_READWRITE));
225   g_object_class_install_property (gobject_class,
226                                    PROP_VALUE,
227                                    g_param_spec_double (atk_object_name_property_value,
228                                                         "Accessible Value",
229                                                         "Is used to notify that the value has changed ",
230                                                         0.0,
231                                                         G_MAXDOUBLE,
232                                                         0.0,
233                                                         G_PARAM_READWRITE));
234   g_object_class_install_property (gobject_class,
235                                    PROP_ROLE,
236                                    g_param_spec_int    (atk_object_name_property_role,
237                                                         "Accessible Role",
238                                                         "The accessible role of this object ",
239                                                         0,
240                                                         G_MAXINT,
241                                                         0,
242                                                         G_PARAM_READWRITE));
243   g_object_class_install_property (gobject_class,
244                                    PROP_LAYER,
245                                    g_param_spec_int    (atk_object_name_property_component_layer,
246                                                         "Accessible Layer",
247                                                         "The accessible layer of this object ",
248                                                         0,
249                                                         G_MAXINT,
250                                                         0,
251                                                         G_PARAM_READABLE));
252   g_object_class_install_property (gobject_class,
253                                    PROP_MDI_ZORDER,
254                                    g_param_spec_int    (atk_object_name_property_component_mdi_zorder,
255                                                         "Accessible MDI Value",
256                                                         "The accessible MDI value of this object ",
257                                                         G_MININT,
258                                                         G_MAXINT,
259                                                         G_MININT,
260                                                         G_PARAM_READABLE));
261   g_object_class_install_property (gobject_class,
262                                    PROP_TABLE_CAPTION,
263                                    g_param_spec_string (atk_object_name_property_table_caption,
264                                                         "Accessible Table Caption",
265                                                         "Is used to notify that the table caption has changed; this property should not be used. accessible-table-caption-object should be used instead",
266                                                         NULL,
267                                                         G_PARAM_READWRITE));
268   g_object_class_install_property (gobject_class,
269                                    PROP_TABLE_COLUMN_HEADER,
270                                    g_param_spec_object (atk_object_name_property_table_column_header,
271                                                         "Accessible Table Column Header",
272                                                         "Is used to notify that the table column header has changed ",
273                                                         ATK_TYPE_OBJECT,
274                                                         G_PARAM_READWRITE));
275   g_object_class_install_property (gobject_class,
276                                    PROP_TABLE_COLUMN_DESCRIPTION,
277                                    g_param_spec_string (atk_object_name_property_table_column_description,
278                                                         "Accessible Table Column Description",
279                                                         "Is used to notify that the table columnscription has changed ",
280                                                         NULL,
281                                                         G_PARAM_READWRITE));
282   g_object_class_install_property (gobject_class,
283                                    PROP_TABLE_ROW_HEADER,
284                                    g_param_spec_object (atk_object_name_property_table_row_header,
285                                                         "Accessible Table Row Header",
286                                                         "Is used to notify that the table row header has changed ",
287                                                         ATK_TYPE_OBJECT,
288                                                         G_PARAM_READWRITE));
289   g_object_class_install_property (gobject_class,
290                                    PROP_TABLE_ROW_DESCRIPTION,
291                                    g_param_spec_string (atk_object_name_property_table_row_description,
292                                                         "Accessible Table Row Description",
293                                                         "Is used to notify that the table row description has changed ",
294                                                         NULL,
295                                                         G_PARAM_READWRITE));
296   g_object_class_install_property (gobject_class,
297                                    PROP_TABLE_SUMMARY,
298                                    g_param_spec_object (atk_object_name_property_table_summary,
299                                                         "Accessible Table Summary",
300                                                         "Is used to notify that the table summary has changed ",
301                                                         ATK_TYPE_OBJECT,
302                                                         G_PARAM_READWRITE));
303   g_object_class_install_property (gobject_class,
304                                    PROP_TABLE_CAPTION_OBJECT,
305                                    g_param_spec_object (atk_object_name_property_table_caption_object,
306                                                         "Accessible Table Caption Object",
307                                                         "Is used to notify that the table caption has changed ",
308                                                         ATK_TYPE_OBJECT,
309                                                         G_PARAM_READWRITE));
310   atk_object_signals[CHILDREN_CHANGED] =
311     g_signal_new ("children_changed",
312                   G_TYPE_FROM_CLASS (klass),
313                   G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
314                   G_STRUCT_OFFSET (AtkObjectClass, children_changed),
315                   NULL, NULL,
316                   g_cclosure_marshal_VOID__UINT_POINTER,
317                   G_TYPE_NONE,
318                   2, G_TYPE_UINT, G_TYPE_POINTER);
319   atk_object_signals[FOCUS_EVENT] =
320     g_signal_new ("focus_event",
321                   G_TYPE_FROM_CLASS (klass),
322                   G_SIGNAL_RUN_LAST,
323                   G_STRUCT_OFFSET (AtkObjectClass, focus_event), 
324                   NULL, NULL,
325                   g_cclosure_marshal_VOID__BOOLEAN,
326                   G_TYPE_NONE,
327                   1, G_TYPE_BOOLEAN);
328   atk_object_signals[PROPERTY_CHANGE] =
329     g_signal_new ("property_change",
330                   G_TYPE_FROM_CLASS (klass),
331                   G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
332                   G_STRUCT_OFFSET (AtkObjectClass, property_change),
333                   (GSignalAccumulator) NULL, NULL,
334                   g_cclosure_marshal_VOID__POINTER,
335                   G_TYPE_NONE, 1,
336                   G_TYPE_POINTER);
337   atk_object_signals[STATE_CHANGE] =
338     g_signal_new ("state_change",
339                   G_TYPE_FROM_CLASS (klass),
340                   G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
341                   G_STRUCT_OFFSET (AtkObjectClass, state_change),
342                   (GSignalAccumulator) NULL, NULL,
343                   atk_marshal_VOID__STRING_BOOLEAN,
344                   G_TYPE_NONE, 2,
345                   G_TYPE_STRING,
346                   G_TYPE_BOOLEAN);
347   atk_object_signals[VISIBLE_DATA_CHANGED] =
348     g_signal_new ("visible_data_changed",
349                   G_TYPE_FROM_CLASS (klass),
350                   G_SIGNAL_RUN_LAST,
351                   G_STRUCT_OFFSET (AtkObjectClass, visible_data_changed),
352                   (GSignalAccumulator) NULL, NULL,
353                   g_cclosure_marshal_VOID__VOID,
354                   G_TYPE_NONE, 0);
355   atk_object_signals[ACTIVE_DESCENDANT_CHANGED] =
356     g_signal_new ("active_descendant_changed",
357                   G_TYPE_FROM_CLASS (klass),
358                   G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
359                   G_STRUCT_OFFSET (AtkObjectClass, active_descendant_changed),
360                   NULL, NULL,
361                   g_cclosure_marshal_VOID__POINTER,
362                   G_TYPE_NONE,
363                   1, G_TYPE_POINTER);
364 }
365
366 static void
367 atk_object_init  (AtkObject        *accessible,
368                   AtkObjectClass   *klass)
369 {
370   accessible->name = NULL;
371   accessible->description = NULL;
372   accessible->accessible_parent = NULL;
373   accessible->relation_set = atk_relation_set_new();
374   accessible->role = ATK_ROLE_UNKNOWN;
375 }
376
377 GType
378 atk_implementor_get_type (void)
379 {
380   static GType type = 0;
381
382   if (!type)
383     {
384       static const GTypeInfo typeInfo =
385       {
386         sizeof (AtkImplementorIface),
387         (GBaseInitFunc) NULL,
388         (GBaseFinalizeFunc) NULL,
389       } ;
390
391       type = g_type_register_static (G_TYPE_INTERFACE, "AtkImplementorIface", &typeInfo, 0) ;
392     }
393
394   return type;
395 }
396
397 /**
398  * atk_object_get_name:
399  * @accessible: an #AtkObject
400  *
401  * Gets the accessible name of the accessible.
402  *
403  * Returns: a character string representing the accessible name of the object.
404  **/
405 G_CONST_RETURN gchar*
406 atk_object_get_name (AtkObject *accessible)
407 {
408   AtkObjectClass *klass;
409
410   g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
411
412   klass = ATK_OBJECT_GET_CLASS (accessible);
413   if (klass->get_name)
414     return (klass->get_name) (accessible);
415   else
416     return NULL;
417 }
418
419 /**
420  * atk_object_get_description:
421  * @accessible: an #AtkObject
422  *
423  * Gets the accessible description of the accessible.
424  *
425  * Returns: a character string representing the accessible description
426  * of the accessible.
427  *
428  **/
429 G_CONST_RETURN gchar*
430 atk_object_get_description (AtkObject *accessible)
431 {
432   AtkObjectClass *klass;
433
434   g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
435
436   klass = ATK_OBJECT_GET_CLASS (accessible);
437   if (klass->get_description)
438     return (klass->get_description) (accessible);
439   else
440     return NULL;
441 }
442
443 /**
444  * atk_object_get_parent:
445  * @accessible: an #AtkObject
446  *
447  * Gets the accessible parent of the accessible.
448  *
449  * Returns: a #AtkObject representing the accessible parent of the accessible
450  **/
451 AtkObject*
452 atk_object_get_parent (AtkObject *accessible)
453 {
454   AtkObjectClass *klass;
455
456   g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
457
458   klass = ATK_OBJECT_GET_CLASS (accessible);
459   if (klass->get_parent)
460     return (klass->get_parent) (accessible);
461   else
462     return NULL;
463 }
464
465 /**
466  * atk_object_get_n_accessible_children:
467  * @accessible: an #AtkObject
468  *
469  * Gets the number of accessible children of the accessible.
470  *
471  * Returns: an integer representing the number of accessible children
472  * of the accessible.
473  **/
474 gint
475 atk_object_get_n_accessible_children (AtkObject *accessible)
476 {
477   AtkObjectClass *klass;
478
479   g_return_val_if_fail (ATK_IS_OBJECT (accessible), 0);
480
481   klass = ATK_OBJECT_GET_CLASS (accessible);
482   if (klass->get_n_children)
483     return (klass->get_n_children) (accessible);
484   else
485     return 0;
486 }
487
488 /**
489  * atk_object_ref_accessible_child:
490  * @accessible: an #AtkObject
491  * @i: a gint representing the position of the child, starting from 0
492  *
493  * Gets a reference to the specified accessible child of the object.
494  * The accessible children are 0-based so the first accessible child is
495  * at index 0, the second at index 1 and so on.
496  *
497  * Returns: an #AtkObject representing the specified accessible child
498  * of the accessible.
499  **/
500 AtkObject*
501 atk_object_ref_accessible_child (AtkObject   *accessible,
502                                  gint        i)
503 {
504   AtkObjectClass *klass;
505
506   g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
507
508   klass = ATK_OBJECT_GET_CLASS (accessible);
509   if (klass->ref_child)
510     return (klass->ref_child) (accessible, i);
511   else
512     return NULL;
513 }
514
515 /**
516  * atk_object_ref_relation_set:
517  * @accessible: an #AtkObject
518  *
519  * Gets the #AtkRelationSet associated with the object.
520  *
521  * Returns: an #AtkRelationSet representing the relation set of the object.
522  **/
523 AtkRelationSet*
524 atk_object_ref_relation_set (AtkObject *accessible)
525 {
526   AtkObjectClass *klass;
527
528   g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
529
530   klass = ATK_OBJECT_GET_CLASS (accessible);
531   if (klass->ref_relation_set)
532     return (klass->ref_relation_set) (accessible);
533   else
534     return NULL;
535 }
536
537 /**
538  * atk_role_register:
539  * @name: a character string describing the new role.
540  *
541  * Registers the role specified by @name.
542  *
543  * Returns: an #AtkRole for the new role.
544  **/
545 AtkRole
546 atk_role_register (const gchar *name)
547 {
548   if (!extra_roles)
549     extra_roles = g_ptr_array_new ();
550
551   g_ptr_array_add (extra_roles, g_strdup (name));
552   return extra_roles->len + ATK_ROLE_LAST_DEFINED;
553 }
554
555 /**
556  * atk_object_get_role:
557  * @accessible: an #AtkObject
558  *
559  * Gets the role of the accessible.
560  *
561  * Returns: an #AtkRole which is the role of the accessible
562  **/
563 AtkRole
564 atk_object_get_role (AtkObject *accessible) 
565 {
566   AtkObjectClass *klass;
567
568   g_return_val_if_fail (ATK_IS_OBJECT (accessible), ATK_ROLE_UNKNOWN);
569
570   klass = ATK_OBJECT_GET_CLASS (accessible);
571   if (klass->get_role)
572     return (klass->get_role) (accessible);
573   else
574     return ATK_ROLE_UNKNOWN;
575 }
576
577 /**
578  * atk_object_get_layer:
579  * @accessible: an #AtkObject
580  *
581  * Gets the layer of the accessible.
582  * DEPRECATED: use atk_component_get_layer instead!
583  *
584  * Returns: an #AtkLayer which is the layer of the accessible
585  **/
586 AtkLayer
587 atk_object_get_layer (AtkObject *accessible) 
588 {
589   AtkObjectClass *klass;
590
591   g_return_val_if_fail (ATK_IS_OBJECT (accessible), ATK_LAYER_INVALID);
592
593   klass = ATK_OBJECT_GET_CLASS (accessible);
594   if (klass->get_layer)
595     return (klass->get_layer) (accessible);
596   else
597     return ATK_LAYER_INVALID;
598 }
599
600 /**
601  * atk_object_get_mdi_zorder:
602  * @accessible: an #AtkObject
603  *
604  * Gets the zorder of the accessible. The value G_MININT will be returned 
605  * if the layer of the accessible is not ATK_LAYER_MDI.
606  * DEPRECATED: use atk_component_get_mdi_zorder instead!
607  *
608  * Returns: a gint which is the zorder of the accessible, i.e. the depth at 
609  * which the component is shown in relation to other components in the same 
610  * container.
611  **/
612 gint
613 atk_object_get_mdi_zorder (AtkObject *accessible) 
614 {
615   AtkObjectClass *klass;
616
617   g_return_val_if_fail (ATK_IS_OBJECT (accessible), G_MININT);
618
619   klass = ATK_OBJECT_GET_CLASS (accessible);
620   if (klass->get_mdi_zorder)
621     return (klass->get_mdi_zorder) (accessible);
622   else
623     return G_MININT;
624 }
625
626 /**
627  * atk_object_ref_state_set:
628  * @accessible: an #AtkObject
629  *
630  * Gets a reference to the state set of the accessible; the caller must
631  * unreference it when it is no longer needed.
632  *
633  * Returns: a reference to an #AtkStateSet which is the state
634  * set of the accessible
635  **/
636 AtkStateSet*
637 atk_object_ref_state_set (AtkObject *accessible) 
638 {
639   AtkObjectClass *klass;
640
641   g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
642
643   klass = ATK_OBJECT_GET_CLASS (accessible);
644   if (klass->ref_state_set)
645     return (klass->ref_state_set) (accessible);
646   else
647     return NULL;
648 }
649
650 /**
651  * atk_object_get_index_in_parent:
652  * @accessible: an #AtkObject
653  *
654  * Gets the 0-based index of this accessible in its parent; returns -1 if the
655  * accessible does not have an accessible parent.
656  *
657  * Returns: an integer which is the index of the accessible in its parent
658  **/
659 gint
660 atk_object_get_index_in_parent (AtkObject *accessible)
661 {
662   AtkObjectClass *klass;
663
664   g_return_val_if_fail (ATK_OBJECT (accessible), -1);
665
666   klass = ATK_OBJECT_GET_CLASS (accessible);
667   if (klass->get_index_in_parent)
668     return (klass->get_index_in_parent) (accessible);
669   else
670     return -1;
671 }
672
673 /**
674  * atk_object_set_name:
675  * @accessible: an #AtkObject
676  * @name: a character string to be set as the accessible name
677  *
678  * Sets the accessible name of the accessible.
679  **/
680 void
681 atk_object_set_name (AtkObject    *accessible,
682                      const gchar  *name)
683 {
684   AtkObjectClass *klass;
685
686   g_return_if_fail (ATK_IS_OBJECT (accessible));
687   g_return_if_fail (name != NULL);
688
689   klass = ATK_OBJECT_GET_CLASS (accessible);
690   if (klass->set_name)
691     {
692       (klass->set_name) (accessible, name);
693       g_object_notify (G_OBJECT (accessible), atk_object_name_property_name);
694     }
695 }
696
697 /**
698  * atk_object_set_description:
699  * @accessible: an #AtkObject
700  * @description : a character string to be set as the accessible description
701  *
702  * Sets the accessible description of the accessible.
703  **/
704 void
705 atk_object_set_description (AtkObject   *accessible,
706                             const gchar *description)
707 {
708   AtkObjectClass *klass;
709
710   g_return_if_fail (ATK_IS_OBJECT (accessible));
711   g_return_if_fail (description != NULL);
712
713   klass = ATK_OBJECT_GET_CLASS (accessible);
714   if (klass->set_description)
715     {
716       (klass->set_description) (accessible, description);
717       g_object_notify (G_OBJECT (accessible), atk_object_name_property_description);
718     }
719 }
720
721 /**
722  * atk_object_set_parent:
723  * @accessible: an #AtkObject
724  * @parent : an #AtkObject to be set as the accessible parent
725  *
726  * Sets the accessible parent of the accessible.
727  **/
728 void
729 atk_object_set_parent (AtkObject *accessible,
730                        AtkObject *parent)
731 {
732   AtkObjectClass *klass;
733
734   g_return_if_fail (ATK_IS_OBJECT (accessible));
735
736   klass = ATK_OBJECT_GET_CLASS (accessible);
737   if (klass->set_parent)
738     {
739       (klass->set_parent) (accessible, parent);
740       g_object_notify (G_OBJECT (accessible), atk_object_name_property_parent);
741     }
742 }
743
744 /**
745  * atk_object_set_role:
746  * @accessible: an #AtkObject
747  * @role : an #AtkRole to be set as the role
748  *
749  * Sets the role of the accessible.
750  **/
751 void
752 atk_object_set_role (AtkObject *accessible, 
753                      AtkRole   role)
754 {
755   AtkObjectClass *klass;
756   AtkRole old_role;
757
758   g_return_if_fail (ATK_IS_OBJECT (accessible));
759
760   klass = ATK_OBJECT_GET_CLASS (accessible);
761   if (klass->set_role)
762     {
763       old_role = atk_object_get_role (accessible);
764       if (old_role != role)
765         {
766           (klass->set_role) (accessible, role);
767           if (old_role != ATK_ROLE_UNKNOWN)
768           /* Do not notify for initial role setting */
769             g_object_notify (G_OBJECT (accessible), atk_object_name_property_role);
770         }
771     }
772 }
773
774 /**
775  * atk_object_connect_property_change_handler:
776  * @accessible: an #AtkObject
777  * @handler : a function to be called when a property changes its value
778  *
779  * Specifies a function to be called when a property changes value.
780  *
781  * Returns: a #guint which is the handler id used in 
782  * atk_object_remove_property_change_handler()
783  **/
784 guint
785 atk_object_connect_property_change_handler (AtkObject *accessible,
786                                             AtkPropertyChangeHandler *handler)
787 {
788   AtkObjectClass *klass;
789
790   g_return_val_if_fail (ATK_IS_OBJECT (accessible), 0);
791   g_return_val_if_fail ((handler != NULL), 0);
792
793   klass = ATK_OBJECT_GET_CLASS (accessible);
794   if (klass->connect_property_change_handler)
795     return (klass->connect_property_change_handler) (accessible, handler);
796   else
797     return 0;
798 }
799
800 /**
801  * atk_object_remove_property_change_handler:
802  * @accessible: an #AtkObject
803  * @handler_id : a guint which identifies the handler to be removed.
804  * 
805  * Removes a property change handler.
806  **/
807 void
808 atk_object_remove_property_change_handler  (AtkObject *accessible,
809                                             guint      handler_id)
810 {
811   AtkObjectClass *klass;
812
813   g_return_if_fail (ATK_IS_OBJECT (accessible));
814
815   klass = ATK_OBJECT_GET_CLASS (accessible);
816   if (klass->remove_property_change_handler)
817     (klass->remove_property_change_handler) (accessible, handler_id);
818 }
819
820 /**
821  * atk_object_notify_state_change:
822  * @accessible: an #AtkObject
823  * @state: an #AtkState whose state is changed
824  * @value : a gboolean which indicates whether the state is being set on or off
825  * 
826  * Emits a state-change signal for the specified state. 
827  **/
828 void
829 atk_object_notify_state_change (AtkObject *accessible,
830                                 AtkState  state,
831                                 gboolean  value)
832 {
833   G_CONST_RETURN gchar* name;
834
835   name = atk_state_type_get_name (state);
836   g_signal_emit (accessible, atk_object_signals[STATE_CHANGE],
837                  g_quark_from_string (name),
838                  name, value, NULL);
839 }
840
841 /**
842  * atk_implementor_ref_accessible:
843  * @implementor: The #GObject instance which should implement #AtkImplementorIface
844  * if a non-null return value is required.
845  * 
846  * Gets a reference to an object's #AtkObject implementation, if
847  * the object implements #AtkObjectIface
848  *
849  * Returns: a reference to an object's #AtkObject implementation
850  */
851 AtkObject *
852 atk_implementor_ref_accessible (AtkImplementor *object)
853 {
854   AtkImplementorIface *iface;
855   AtkObject           *accessible = NULL;
856
857   g_return_val_if_fail (ATK_IS_IMPLEMENTOR (object), NULL);
858
859   iface = ATK_IMPLEMENTOR_GET_IFACE (object);
860
861   if (iface != NULL) 
862     accessible =  iface->ref_accessible (object);
863
864   g_return_val_if_fail ((accessible != NULL), NULL);
865
866   return accessible;
867 }
868
869 static AtkRelationSet*
870 atk_object_real_ref_relation_set (AtkObject *accessible)
871 {
872   g_return_val_if_fail (accessible->relation_set, NULL);
873   g_object_ref (accessible->relation_set); 
874
875   return accessible->relation_set;
876 }
877
878 static void
879 atk_object_real_set_property (GObject      *object,
880                               guint         prop_id,
881                               const GValue *value,
882                               GParamSpec   *pspec)
883 {
884   AtkObject *accessible;
885
886   accessible = ATK_OBJECT (object);
887
888   switch (prop_id)
889     {
890     case PROP_NAME:
891       atk_object_set_name (accessible, g_value_get_string (value));
892       break;
893     case PROP_DESCRIPTION:
894       atk_object_set_description (accessible, g_value_get_string (value));
895       break;
896     case PROP_ROLE:
897       atk_object_set_role (accessible, g_value_get_int (value));
898       break;
899     case PROP_PARENT:
900       atk_object_set_parent (accessible, g_value_get_object (value));
901       break;
902     case PROP_VALUE:
903       if (ATK_IS_VALUE (accessible))
904         atk_value_set_current_value (ATK_VALUE (accessible), value);
905       break;
906     case PROP_TABLE_SUMMARY:
907       if (ATK_IS_TABLE (accessible))
908         atk_table_set_summary (ATK_TABLE (accessible), g_value_get_object (value));
909       break;
910     case PROP_TABLE_CAPTION_OBJECT:
911       if (ATK_IS_TABLE (accessible))
912         atk_table_set_caption (ATK_TABLE (accessible), g_value_get_object (value));
913       break;
914     default:
915       break;
916     }
917 }
918
919 static void
920 atk_object_real_get_property (GObject      *object,
921                               guint         prop_id,
922                               GValue       *value,
923                               GParamSpec   *pspec)
924 {
925   AtkObject *accessible;
926
927   accessible = ATK_OBJECT (object);
928
929   switch (prop_id)
930     {
931     case PROP_NAME:
932       g_value_set_string (value, atk_object_get_name (accessible));
933       break;
934     case PROP_DESCRIPTION:
935       g_value_set_string (value, atk_object_get_description (accessible));
936       break;
937     case PROP_ROLE:
938       g_value_set_int (value, atk_object_get_role (accessible));
939       break;
940     case PROP_LAYER:
941       if (ATK_IS_COMPONENT (accessible))
942         g_value_set_int (value, atk_component_get_layer (ATK_COMPONENT (accessible)));
943       break;
944     case PROP_MDI_ZORDER:
945       if (ATK_IS_COMPONENT (accessible))
946         g_value_set_int (value, atk_component_get_mdi_zorder (ATK_COMPONENT (accessible)));
947       break;
948     case PROP_PARENT:
949       g_value_set_object (value, atk_object_get_parent (accessible));
950       break;
951     case PROP_VALUE:
952       if (ATK_IS_VALUE (accessible))
953         atk_value_get_current_value (ATK_VALUE (accessible), value);
954       break;
955     case PROP_TABLE_SUMMARY:
956       if (ATK_IS_TABLE (accessible))
957         g_value_set_object (value, atk_table_get_summary (ATK_TABLE (accessible)));
958       break;
959     case PROP_TABLE_CAPTION_OBJECT:
960       if (ATK_IS_TABLE (accessible))
961         g_value_set_object (value, atk_table_get_caption (ATK_TABLE (accessible)));
962       break;
963     default:
964       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
965       break;
966     }
967 }
968
969 static void
970 atk_object_finalize (GObject *object)
971 {
972   AtkObject        *accessible;
973
974   g_return_if_fail (ATK_IS_OBJECT (object));
975
976   accessible = ATK_OBJECT (object);
977
978   g_free (accessible->name);
979   g_free (accessible->description);
980
981   /*
982    * Free memory allocated for relation set if it have been allocated.
983    */
984   if (accessible->relation_set)
985     g_object_unref (accessible->relation_set);
986
987   if (accessible->accessible_parent)
988     g_object_unref (accessible->accessible_parent);
989
990   G_OBJECT_CLASS (parent_class)->finalize (object);
991 }
992
993 static G_CONST_RETURN gchar*
994 atk_object_real_get_name (AtkObject *object)
995 {
996   return object->name;
997 }
998
999 static G_CONST_RETURN gchar*
1000 atk_object_real_get_description (AtkObject *object)
1001 {
1002   return object->description;
1003 }
1004
1005 static AtkObject*
1006 atk_object_real_get_parent (AtkObject       *object)
1007 {
1008   return object->accessible_parent;
1009 }
1010
1011 static AtkRole
1012 atk_object_real_get_role (AtkObject       *object)
1013 {
1014   return object->role;
1015 }
1016
1017 static AtkLayer
1018 atk_object_real_get_layer (AtkObject       *object)
1019 {
1020   return object->layer;
1021 }
1022
1023 static AtkStateSet*
1024 atk_object_real_ref_state_set (AtkObject *accessible) 
1025 {
1026   AtkStateSet *state_set;
1027   AtkObject *ap;
1028
1029   state_set = atk_state_set_new ();
1030
1031   ap = atk_object_get_parent (accessible);
1032   if (ap)
1033     if (ATK_IS_SELECTION (ap))
1034       {
1035         int i;
1036
1037         atk_state_set_add_state (state_set, ATK_STATE_SELECTABLE);
1038
1039         i = atk_object_get_index_in_parent (accessible);
1040         if (i >= 0)
1041           if (atk_selection_is_child_selected(ATK_SELECTION (ap), i))
1042             atk_state_set_add_state (state_set, ATK_STATE_SELECTED);
1043       } 
1044
1045   return state_set; 
1046 }
1047
1048 static void
1049 atk_object_real_set_name (AtkObject       *object,
1050                           const gchar     *name)
1051 {
1052   g_free (object->name);
1053   object->name = g_strdup (name);
1054 }
1055
1056 static void
1057 atk_object_real_set_description (AtkObject       *object,
1058                                  const gchar     *description)
1059 {
1060   g_free (object->description);
1061   object->description = g_strdup (description);
1062 }
1063
1064 static void
1065 atk_object_real_set_parent (AtkObject       *object,
1066                             AtkObject       *parent)
1067 {
1068   if (object->accessible_parent)
1069     g_object_unref (object->accessible_parent);
1070
1071   object->accessible_parent = parent;
1072   if (object->accessible_parent)
1073     g_object_ref (object->accessible_parent);
1074 }
1075
1076 static void
1077 atk_object_real_set_role (AtkObject *object,
1078                           AtkRole   role)
1079 {
1080   object->role = role;
1081 }
1082
1083 static guint
1084 atk_object_real_connect_property_change_handler (AtkObject                *obj,
1085                                                  AtkPropertyChangeHandler *handler)
1086 {
1087   return g_signal_connect_closure_by_id (obj,
1088                                          atk_object_signals[PROPERTY_CHANGE],
1089                                          0,
1090                                          g_cclosure_new (
1091                                          G_CALLBACK (handler), NULL,
1092                                          (GClosureNotify) NULL),
1093                                          FALSE);
1094 }
1095
1096 static void
1097 atk_object_real_remove_property_change_handler (AtkObject           *obj,
1098                                           guint               handler_id)
1099 {
1100   g_signal_handler_disconnect (obj, handler_id);
1101 }
1102
1103 /**
1104  * atk_object_initialize:
1105  * @accessible: a #AtkObject
1106  * @data: a #gpointer which identifies the object for which the AtkObject was created.
1107  *
1108  * This function is called when implementing subclasses of #AtkObject.
1109  * It does initialization required for the new object. It is intended
1110  * that this function should called only in the ..._new() functions used
1111  * to create an instance of a subclass of #AtkObject
1112  **/
1113 void
1114 atk_object_initialize (AtkObject  *accessible,
1115                        gpointer   data)
1116 {
1117   AtkObjectClass *klass;
1118
1119   g_return_if_fail (ATK_IS_OBJECT (accessible));
1120
1121   klass = ATK_OBJECT_GET_CLASS (accessible);
1122   if (klass->initialize)
1123     klass->initialize (accessible, data);
1124 }
1125
1126 /*
1127  * This function is a signal handler for notify signal which gets emitted
1128  * when a property changes value.
1129  *
1130  * It constructs an AtkPropertyValues structure and emits a "property_changed"
1131  * signal which causes the user specified AtkPropertyChangeHandler
1132  * to be called.
1133  */
1134 static void
1135 atk_object_notify (GObject     *obj,
1136                    GParamSpec  *pspec)
1137 {
1138   AtkPropertyValues values = { 0, };
1139
1140   g_value_init (&values.new_value, pspec->value_type);
1141   g_object_get_property (obj, pspec->name, &values.new_value);
1142   values.property_name = pspec->name;
1143   g_signal_emit (obj, atk_object_signals[PROPERTY_CHANGE],
1144                  g_quark_from_string (pspec->name),
1145                  &values, NULL);
1146   g_value_unset (&values.new_value);
1147 }
1148
1149 /**
1150  * atk_role_get_name:
1151  * @role: The #AtkRole whose name is required
1152  *
1153  * Gets the description string describing the #AtkRole @role.
1154  *
1155  * Returns: the string describing the AtkRole
1156  */
1157 G_CONST_RETURN gchar*
1158 atk_role_get_name (AtkRole role)
1159 {
1160   GTypeClass *type_class;
1161   GEnumValue *value;
1162   gchar *name = NULL;
1163
1164   type_class = g_type_class_ref (ATK_TYPE_ROLE);
1165   g_return_val_if_fail (G_IS_ENUM_CLASS (type_class), NULL);
1166
1167   value = g_enum_get_value (G_ENUM_CLASS (type_class), role);
1168
1169   if (value)
1170     {
1171       name = value->value_nick;
1172     }
1173   else
1174     {
1175       if (extra_roles)
1176         {
1177           gint n = role;
1178
1179           n -= ATK_ROLE_LAST_DEFINED + 1;
1180
1181           if (n < extra_roles->len)
1182             name = g_ptr_array_index (extra_roles, n);
1183         }
1184     }
1185   g_type_class_unref (type_class);
1186   return name;
1187 }
1188
1189 #ifdef G_OS_WIN32
1190
1191 #undef ATKLOCALEDIR
1192
1193 #define ATKLOCALEDIR get_atk_locale_dir()
1194
1195 G_WIN32_DLLMAIN_FOR_DLL_NAME(static, dll_name)
1196
1197 static char *
1198 get_atk_locale_dir (void)
1199 {
1200   return g_win32_get_package_installation_subdirectory
1201     (GETTEXT_PACKAGE, dll_name, "lib/locale");
1202 }
1203
1204 #endif
1205
1206 /**
1207  * atk_role_get_localized_name:
1208  * @role: The #AtkRole whose localized name is required
1209  *
1210  * Gets the localized description string describing the #AtkRole @role.
1211  *
1212  * Returns: the localized string describing the AtkRole
1213  **/
1214 G_CONST_RETURN gchar*
1215 atk_role_get_localized_name (AtkRole role)
1216 {
1217   G_CONST_RETURN gchar *name;
1218   gboolean gettext_initialized = FALSE;
1219
1220 #ifdef ENABLE_NLS
1221   if (!gettext_initialized)
1222     {
1223       gettext_initialized = TRUE;
1224
1225       bindtextdomain (GETTEXT_PACKAGE, ATKLOCALEDIR);
1226 #ifdef HAVE_BIND_TEXTDOMAIN_CODESET
1227       bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
1228 #endif
1229     }
1230 #endif
1231
1232   switch (role)
1233     {
1234       case ATK_ROLE_INVALID:
1235         name = _("invalid");
1236         break;
1237       case ATK_ROLE_ACCEL_LABEL:
1238         name = _("accel-label");
1239         break;
1240       case ATK_ROLE_ALERT:
1241         name = _("alert");
1242         break;
1243       case ATK_ROLE_ANIMATION:
1244         name = _("animation");
1245         break;
1246       case ATK_ROLE_ARROW:
1247         name = _("arrow");
1248         break;
1249       case ATK_ROLE_CALENDAR:
1250         name = _("calendar");
1251         break;
1252       case ATK_ROLE_CANVAS:
1253         name = _("canvas");
1254         break;
1255       case ATK_ROLE_CHECK_BOX:
1256         name = _("check-box");
1257         break;
1258       case ATK_ROLE_CHECK_MENU_ITEM:
1259         name = _("check-menu-item");
1260         break;
1261       case ATK_ROLE_COLOR_CHOOSER:
1262         name = _("color-chooser");
1263         break;
1264       case ATK_ROLE_COLUMN_HEADER:
1265         name = _("column-header");
1266         break;
1267       case ATK_ROLE_COMBO_BOX:
1268         name = _("combo-box");
1269         break;
1270       case ATK_ROLE_DATE_EDITOR:
1271         name = _("date-editor");
1272         break;
1273       case ATK_ROLE_DESKTOP_ICON:
1274         name = _("desktop-icon");
1275         break;
1276       case ATK_ROLE_DESKTOP_FRAME:
1277         name = _("desktop-frame");
1278         break;
1279       case ATK_ROLE_DIAL:
1280         name = _("dial");
1281         break;
1282       case ATK_ROLE_DIALOG:
1283         name = _("dialog");
1284         break;
1285       case ATK_ROLE_DIRECTORY_PANE:
1286         name = _("directory-pane");
1287         break;
1288       case ATK_ROLE_DRAWING_AREA:
1289         name = _("drawing-area");
1290         break;
1291       case ATK_ROLE_FILE_CHOOSER:
1292         name = _("file-chooser");
1293         break;
1294       case ATK_ROLE_FILLER:
1295         name = _("filler");
1296         break;
1297       case ATK_ROLE_FONT_CHOOSER:
1298         name = _("font-chooser");
1299         break;
1300       case ATK_ROLE_FRAME:
1301         name = _("frame");
1302         break;
1303       case ATK_ROLE_GLASS_PANE:
1304         name = _("glass-pane");
1305         break;
1306       case ATK_ROLE_HTML_CONTAINER:
1307         name = _("html-container");
1308         break;
1309       case ATK_ROLE_ICON:
1310         name = _("icon");
1311         break;
1312       case ATK_ROLE_IMAGE:
1313         name = _("image");
1314         break;
1315       case ATK_ROLE_INTERNAL_FRAME:
1316         name = _("internal-frame");
1317         break;
1318       case ATK_ROLE_LABEL:
1319         name = _("label");
1320         break;
1321       case ATK_ROLE_LAYERED_PANE:
1322         name = _("layered-pane");
1323         break;
1324       case ATK_ROLE_LIST:
1325         name = _("list");
1326         break;
1327       case ATK_ROLE_LIST_ITEM:
1328         name = _("list-item");
1329         break;
1330       case ATK_ROLE_MENU:
1331         name = _("menu");
1332         break;
1333       case ATK_ROLE_MENU_BAR:
1334         name = _("menu-bar");
1335         break;
1336       case ATK_ROLE_MENU_ITEM:
1337         name = _("menu-item");
1338         break;
1339       case ATK_ROLE_OPTION_PANE:
1340         name = _("option-pane");
1341         break;
1342       case ATK_ROLE_PAGE_TAB:
1343         name = _("page-tab");
1344         break;
1345       case ATK_ROLE_PAGE_TAB_LIST:
1346         name = _("page-tab-list");
1347         break;
1348       case ATK_ROLE_PANEL:
1349         name = _("panel");
1350         break;
1351       case ATK_ROLE_PASSWORD_TEXT:
1352         name = _("password-text");
1353         break;
1354       case ATK_ROLE_POPUP_MENU:
1355         name = _("popup-menu");
1356         break;
1357       case ATK_ROLE_PROGRESS_BAR:
1358         name = _("progress-bar");
1359         break;
1360       case ATK_ROLE_PUSH_BUTTON:
1361         name = _("push-button");
1362         break;
1363       case ATK_ROLE_RADIO_BUTTON:
1364         name = _("radio-button");
1365         break;
1366       case ATK_ROLE_RADIO_MENU_ITEM:
1367         name = _("radio-menu-item");
1368         break;
1369       case ATK_ROLE_ROOT_PANE:
1370         name = _("root-pane");
1371         break;
1372       case ATK_ROLE_ROW_HEADER:
1373         name = _("row-header");
1374         break;
1375       case ATK_ROLE_SCROLL_BAR:
1376         name = _("scroll-bar");
1377         break;
1378       case ATK_ROLE_SCROLL_PANE:
1379         name = _("scroll-pane");
1380         break;
1381       case ATK_ROLE_SEPARATOR:
1382         name = _("separator");
1383         break;
1384       case ATK_ROLE_SLIDER:
1385         name = _("slider");
1386         break;
1387       case ATK_ROLE_SPLIT_PANE:
1388         name = _("split-pane");
1389         break;
1390       case ATK_ROLE_SPIN_BUTTON:
1391         name = _("spin-button");
1392         break;
1393       case ATK_ROLE_STATUSBAR:
1394         name = _("statusbar");
1395         break;
1396       case ATK_ROLE_TABLE:
1397         name = _("table");
1398         break;
1399       case ATK_ROLE_TABLE_CELL:
1400         name = _("table-cell");
1401         break;
1402       case ATK_ROLE_TABLE_COLUMN_HEADER:
1403         name = _("table-column-header");
1404         break;
1405       case ATK_ROLE_TABLE_ROW_HEADER:
1406         name = _("table-row-header");
1407         break;
1408       case ATK_ROLE_TEAR_OFF_MENU_ITEM:
1409         name = _("tear-off-menu-item");
1410         break;
1411       case ATK_ROLE_TERMINAL:
1412         name = _("terminal");
1413         break;
1414       case ATK_ROLE_TEXT:
1415         name = _("text");
1416         break;
1417       case ATK_ROLE_TOGGLE_BUTTON:
1418         name = _("toggle-button");
1419         break;
1420       case ATK_ROLE_TOOL_BAR:
1421         name = _("tool-bar");
1422         break;
1423       case ATK_ROLE_TOOL_TIP:
1424         name = _("tool-tip");
1425         break;
1426       case ATK_ROLE_TREE:
1427         name = _("tree");
1428         break;
1429       case ATK_ROLE_TREE_TABLE:
1430         name = _("tree-table");
1431         break;
1432       case ATK_ROLE_UNKNOWN:
1433         name = _("unknown");
1434         break;
1435       case ATK_ROLE_VIEWPORT:
1436         name = _("viewport");
1437         break;
1438       case ATK_ROLE_WINDOW:
1439         name = _("window");
1440         break;
1441       case ATK_ROLE_HEADER:
1442         name = _("header");
1443         break;
1444       case ATK_ROLE_FOOTER:
1445         name = _("footer");
1446         break;
1447       case ATK_ROLE_PARAGRAPH:
1448         name = _("paragraph");
1449         break;
1450       case ATK_ROLE_RULER:
1451         name = _("ruler");
1452         break;
1453       case ATK_ROLE_APPLICATION:
1454         name = _("application");
1455         break;
1456       default:
1457         name = atk_role_get_name (role);
1458         break;
1459     }
1460   return name;
1461 }
1462
1463 /**
1464  * atk_role_for_name:
1465  * @name: a string which is the (non-localized) name of an ATK role.
1466  *
1467  * Get the #AtkRole type corresponding to a rolew name.
1468  *
1469  * Returns: the #AtkRole enumerated type corresponding to the specified
1470 name,
1471  *          or #ATK_ROLE_INVALID if no matching role is found.
1472  **/
1473 AtkRole
1474 atk_role_for_name (const gchar *name)
1475 {
1476   GTypeClass *type_class;
1477   GEnumValue *value;
1478   AtkRole role = ATK_ROLE_INVALID;
1479
1480   g_return_val_if_fail (name, ATK_ROLE_INVALID);
1481
1482   type_class = g_type_class_ref (ATK_TYPE_ROLE);
1483   g_return_val_if_fail (G_IS_ENUM_CLASS (type_class), ATK_ROLE_INVALID);
1484
1485   value = g_enum_get_value_by_nick (G_ENUM_CLASS (type_class), name);
1486
1487   if (value)
1488     {
1489       role = value->value;
1490     }
1491   else
1492     {
1493      gint i;
1494
1495       if (extra_roles)
1496         {
1497           for (i = 0; i < extra_roles->len; i++)
1498             {
1499               gchar *extra_role = (gchar *)g_ptr_array_index (extra_roles, i);
1500
1501               g_return_val_if_fail (extra_role, ATK_ROLE_INVALID);
1502
1503               if (strcmp (name, extra_role) == 0)
1504                 {
1505                   role = i + 1 + ATK_ROLE_LAST_DEFINED;
1506                   break;
1507                 }
1508             }
1509         }
1510     }
1511   g_type_class_unref (type_class);
1512   
1513   return role;
1514 }
1515
1516 /**
1517  * atk_object_add_relationship:
1518  * @object: The #AtkObject to which an AtkRelation is to be added. 
1519  * @relationship: The #AtkRelationType of the relation
1520  * @target: The #AtkObject which is to be the target of the relation.
1521  *
1522  * Adds a relationship of the specified type with the specified target.
1523  *
1524  * Returns TRUE if the relationship is added.
1525  **/
1526 gboolean
1527 atk_object_add_relationship (AtkObject       *object,
1528                              AtkRelationType relationship,
1529                              AtkObject       *target)
1530 {
1531   AtkObject *array[1];
1532   AtkRelation *relation;
1533
1534   g_return_val_if_fail (ATK_IS_OBJECT (object), FALSE);
1535   g_return_val_if_fail (ATK_IS_OBJECT (target), FALSE);
1536
1537   array[0] = target;
1538   relation = atk_relation_new (array, 1, relationship);
1539   atk_relation_set_add (object->relation_set, relation);
1540   g_object_unref (relation);
1541
1542   return TRUE;
1543 }
1544
1545 /**
1546  * atk_object_remove_relationship:
1547  * @object: The #AtkObject from which an AtkRelation is to be removed. 
1548  * @relationship: The #AtkRelationType of the relation
1549  * @target: The #AtkObject which is the target of the relation to be removed.
1550  *
1551  * Removes a relationship of the specified type with the specified target.
1552  *
1553  * Returns TRUE if the relationship is removed.
1554  **/
1555 gboolean
1556 atk_object_remove_relationship (AtkObject       *object,
1557                                 AtkRelationType relationship,
1558                                 AtkObject       *target)
1559 {
1560   gint n_relations, i;
1561   gboolean ret = FALSE;
1562   AtkRelation *relation;
1563
1564   g_return_val_if_fail (ATK_IS_OBJECT (object), FALSE);
1565   g_return_val_if_fail (ATK_IS_OBJECT (target), FALSE);
1566
1567   n_relations = atk_relation_set_get_n_relations (object->relation_set);
1568   for (i = 0; i < n_relations; i++)
1569     {
1570       relation = atk_relation_set_get_relation (object->relation_set, i);
1571       if (atk_relation_get_relation_type (relation) == relationship)
1572         {
1573           GPtrArray *array;
1574
1575           array = atk_relation_get_target (relation);
1576         
1577           if (g_ptr_array_index (array, 0) == target)
1578             {
1579               atk_relation_set_remove (object->relation_set, relation); 
1580               ret = TRUE;
1581               break;
1582             }
1583         }
1584     }
1585
1586   return ret;
1587 }
1588
1589 static void
1590 atk_object_real_initialize (AtkObject *accessible,
1591                             gpointer  data)
1592 {
1593   return;
1594 }