Dist atk-zip.sh.in, not atk-zip.sh.
[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
77 static void            atk_object_real_set_property (GObject         *object,
78                                                      guint            prop_id,
79                                                      const GValue    *value,
80                                                      GParamSpec      *pspec);
81 static void            atk_object_real_get_property (GObject         *object,
82                                                      guint            prop_id,
83                                                      GValue          *value,
84                                                      GParamSpec      *pspec);
85 static void            atk_object_finalize          (GObject         *object);
86 static G_CONST_RETURN gchar*
87                        atk_object_real_get_name     (AtkObject       *object);
88 static G_CONST_RETURN gchar*
89                        atk_object_real_get_description    
90                                                    (AtkObject       *object);
91 static AtkObject*      atk_object_real_get_parent  (AtkObject       *object);
92 static AtkRole         atk_object_real_get_role    (AtkObject       *object);
93 static AtkLayer        atk_object_real_get_layer   (AtkObject       *object);
94 static AtkStateSet*    atk_object_real_ref_state_set
95                                                    (AtkObject       *object);
96 static void            atk_object_real_set_name    (AtkObject       *object,
97                                                     const gchar     *name);
98 static void            atk_object_real_set_description
99                                                    (AtkObject       *object,
100                                                     const gchar     *description);
101 static void            atk_object_real_set_parent  (AtkObject       *object,
102                                                     AtkObject       *parent);
103 static void            atk_object_real_set_role    (AtkObject       *object,
104                                                     AtkRole         role);
105 static guint           atk_object_real_connect_property_change_handler
106                                                    (AtkObject       *obj,
107                                                     AtkPropertyChangeHandler
108                                                                     *handler);
109 static void            atk_object_real_remove_property_change_handler
110                                                    (AtkObject       *obj,
111                                                     guint           handler_id);
112 static void            atk_object_notify           (GObject         *obj,
113                                                     GParamSpec      *pspec);
114
115
116 static guint atk_object_signals[LAST_SIGNAL] = { 0, };
117
118 static gpointer parent_class = NULL;
119
120 static const gchar* atk_object_name_property_name = "accessible-name";
121 static const gchar* atk_object_name_property_description = "accessible-description";
122 static const gchar* atk_object_name_property_parent = "accessible-parent";
123 static const gchar* atk_object_name_property_value = "accessible-value";
124 static const gchar* atk_object_name_property_role = "accessible-role";
125 static const gchar* atk_object_name_property_component_layer = "accessible-component-layer";
126 static const gchar* atk_object_name_property_component_mdi_zorder = "accessible-component-mdi-zorder";
127 static const gchar* atk_object_name_property_table_caption = "accessible-table-caption";
128 static const gchar* atk_object_name_property_table_column_description = "accessible-table-column-description";
129 static const gchar* atk_object_name_property_table_column_header = "accessible-table-column-header";
130 static const gchar* atk_object_name_property_table_row_description = "accessible-table-row-description";
131 static const gchar* atk_object_name_property_table_row_header = "accessible-table-row-header";
132 static const gchar* atk_object_name_property_table_summary = "accessible-table-summary";
133 static const gchar* atk_object_name_property_table_caption_object = "accessible-table-caption-object";
134
135 GType
136 atk_object_get_type (void)
137 {
138   static GType type = 0;
139
140   if (!type)
141     {
142       static const GTypeInfo typeInfo =
143       {
144         sizeof (AtkObjectClass),
145         (GBaseInitFunc) NULL,
146         (GBaseFinalizeFunc) NULL,
147         (GClassInitFunc) atk_object_class_init,
148         (GClassFinalizeFunc) NULL,
149         NULL,
150         sizeof (AtkObject),
151         0,
152         (GInstanceInitFunc) atk_object_init,
153       } ;
154       type = g_type_register_static (G_TYPE_OBJECT, "AtkObject", &typeInfo, 0) ;
155     }
156   return type;
157 }
158
159 static void
160 atk_object_class_init (AtkObjectClass *klass)
161 {
162   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
163
164   parent_class = g_type_class_peek_parent (klass);
165
166   gobject_class->set_property = atk_object_real_set_property;
167   gobject_class->get_property = atk_object_real_get_property;
168   gobject_class->finalize = atk_object_finalize;
169   gobject_class->notify = atk_object_notify;
170
171   klass->get_name = atk_object_real_get_name;
172   klass->get_description = atk_object_real_get_description;
173   klass->get_parent = atk_object_real_get_parent;
174   klass->get_n_children = NULL;
175   klass->ref_child = NULL;
176   klass->get_index_in_parent = NULL;
177   klass->ref_relation_set = atk_object_real_ref_relation_set;
178   klass->get_role = atk_object_real_get_role;
179   klass->get_layer = atk_object_real_get_layer;
180   klass->get_mdi_zorder = NULL;
181   klass->ref_state_set = atk_object_real_ref_state_set;
182   klass->set_name = atk_object_real_set_name;
183   klass->set_description = atk_object_real_set_description;
184   klass->set_parent = atk_object_real_set_parent;
185   klass->set_role = atk_object_real_set_role;
186   klass->connect_property_change_handler = 
187          atk_object_real_connect_property_change_handler;
188   klass->remove_property_change_handler = 
189          atk_object_real_remove_property_change_handler;
190
191   /*
192    * We do not define default signal handlers here
193    */
194   klass->children_changed = NULL;
195   klass->focus_event = NULL;
196   klass->property_change = NULL;
197   klass->visible_data_changed = NULL;
198   klass->active_descendant_changed = NULL;
199
200   g_object_class_install_property (gobject_class,
201                                    PROP_NAME,
202                                    g_param_spec_string (atk_object_name_property_name,
203                                                         "Accessible Name",
204                                                         "Object instance\'s name formatted for "
205                                                            "assistive technology access",
206                                                         NULL,
207                                                         G_PARAM_READWRITE));
208   g_object_class_install_property (gobject_class,
209                                    PROP_DESCRIPTION,
210                                    g_param_spec_string (atk_object_name_property_description,
211                                                         "Accessible Description",
212                                                         "Description of an object, formatted for "
213                                                         "assistive technology access",
214                                                         NULL,
215                                                         G_PARAM_READWRITE));
216   g_object_class_install_property (gobject_class,
217                                    PROP_PARENT,
218                                    g_param_spec_object (atk_object_name_property_parent,
219                                                         "Accessible Parent",
220                                                         "Is used to notify that the parent has changed ",
221                                                         ATK_TYPE_OBJECT,
222                                                         G_PARAM_READWRITE));
223   g_object_class_install_property (gobject_class,
224                                    PROP_VALUE,
225                                    g_param_spec_double (atk_object_name_property_value,
226                                                         "Accessible Value",
227                                                         "Is used to notify that the value has changed ",
228                                                         0.0,
229                                                         G_MAXDOUBLE,
230                                                         0.0,
231                                                         G_PARAM_READWRITE));
232   g_object_class_install_property (gobject_class,
233                                    PROP_ROLE,
234                                    g_param_spec_int    (atk_object_name_property_role,
235                                                         "Accessible Role",
236                                                         "The accessible role of this object ",
237                                                         0,
238                                                         G_MAXINT,
239                                                         0,
240                                                         G_PARAM_READWRITE));
241   g_object_class_install_property (gobject_class,
242                                    PROP_LAYER,
243                                    g_param_spec_int    (atk_object_name_property_component_layer,
244                                                         "Accessible Layer",
245                                                         "The accessible layer of this object ",
246                                                         0,
247                                                         G_MAXINT,
248                                                         0,
249                                                         G_PARAM_READABLE));
250   g_object_class_install_property (gobject_class,
251                                    PROP_MDI_ZORDER,
252                                    g_param_spec_int    (atk_object_name_property_component_mdi_zorder,
253                                                         "Accessible MDI Value",
254                                                         "The accessible MDI value of this object ",
255                                                         G_MININT,
256                                                         G_MAXINT,
257                                                         G_MININT,
258                                                         G_PARAM_READABLE));
259   g_object_class_install_property (gobject_class,
260                                    PROP_TABLE_CAPTION,
261                                    g_param_spec_string (atk_object_name_property_table_caption,
262                                                         "Accessible Table Caption",
263                                                         "Is used to notify that the table caption has changed; this property should not be used. accessible-table-caption-object should be used instead",
264                                                         NULL,
265                                                         G_PARAM_READWRITE));
266   g_object_class_install_property (gobject_class,
267                                    PROP_TABLE_COLUMN_HEADER,
268                                    g_param_spec_object (atk_object_name_property_table_column_header,
269                                                         "Accessible Table Column Header",
270                                                         "Is used to notify that the table column header has changed ",
271                                                         ATK_TYPE_OBJECT,
272                                                         G_PARAM_READWRITE));
273   g_object_class_install_property (gobject_class,
274                                    PROP_TABLE_COLUMN_DESCRIPTION,
275                                    g_param_spec_string (atk_object_name_property_table_column_description,
276                                                         "Accessible Table Column Description",
277                                                         "Is used to notify that the table columnscription has changed ",
278                                                         NULL,
279                                                         G_PARAM_READWRITE));
280   g_object_class_install_property (gobject_class,
281                                    PROP_TABLE_ROW_HEADER,
282                                    g_param_spec_object (atk_object_name_property_table_row_header,
283                                                         "Accessible Table Row Header",
284                                                         "Is used to notify that the table row header has changed ",
285                                                         ATK_TYPE_OBJECT,
286                                                         G_PARAM_READWRITE));
287   g_object_class_install_property (gobject_class,
288                                    PROP_TABLE_ROW_DESCRIPTION,
289                                    g_param_spec_string (atk_object_name_property_table_row_description,
290                                                         "Accessible Table Row Description",
291                                                         "Is used to notify that the table row description has changed ",
292                                                         NULL,
293                                                         G_PARAM_READWRITE));
294   g_object_class_install_property (gobject_class,
295                                    PROP_TABLE_SUMMARY,
296                                    g_param_spec_object (atk_object_name_property_table_summary,
297                                                         "Accessible Table Summary",
298                                                         "Is used to notify that the table summary has changed ",
299                                                         ATK_TYPE_OBJECT,
300                                                         G_PARAM_READWRITE));
301   g_object_class_install_property (gobject_class,
302                                    PROP_TABLE_CAPTION_OBJECT,
303                                    g_param_spec_object (atk_object_name_property_table_caption_object,
304                                                         "Accessible Table Caption Object",
305                                                         "Is used to notify that the table caption has changed ",
306                                                         ATK_TYPE_OBJECT,
307                                                         G_PARAM_READWRITE));
308   /*
309    * The signal "children_changed" supports two details:
310    * "add" and "remove"
311    */
312   atk_object_signals[CHILDREN_CHANGED] =
313     g_signal_new ("children_changed",
314                   G_TYPE_FROM_CLASS (klass),
315                   G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
316                   G_STRUCT_OFFSET (AtkObjectClass, children_changed),
317                   NULL, NULL,
318                   g_cclosure_marshal_VOID__UINT_POINTER,
319                   G_TYPE_NONE,
320                   2, G_TYPE_UINT, G_TYPE_POINTER);
321   atk_object_signals[FOCUS_EVENT] =
322     g_signal_new ("focus_event",
323                   G_TYPE_FROM_CLASS (klass),
324                   G_SIGNAL_RUN_LAST,
325                   G_STRUCT_OFFSET (AtkObjectClass, focus_event), 
326                   NULL, NULL,
327                   g_cclosure_marshal_VOID__BOOLEAN,
328                   G_TYPE_NONE,
329                   1, G_TYPE_BOOLEAN);
330   atk_object_signals[PROPERTY_CHANGE] =
331     g_signal_new ("property_change",
332                   G_TYPE_FROM_CLASS (klass),
333                   G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
334                   G_STRUCT_OFFSET (AtkObjectClass, property_change),
335                   (GSignalAccumulator) NULL, NULL,
336                   g_cclosure_marshal_VOID__POINTER,
337                   G_TYPE_NONE, 1,
338                   G_TYPE_POINTER);
339   /*
340    * The "state_change" signal supports details, one for each accessible 
341    * state type
342    * (see atkstate.c).
343    */
344   atk_object_signals[STATE_CHANGE] =
345     g_signal_new ("state_change",
346                   G_TYPE_FROM_CLASS (klass),
347                   G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
348                   G_STRUCT_OFFSET (AtkObjectClass, state_change),
349                   (GSignalAccumulator) NULL, NULL,
350                   atk_marshal_VOID__STRING_BOOLEAN,
351                   G_TYPE_NONE, 2,
352                   G_TYPE_STRING,
353                   G_TYPE_BOOLEAN);
354   atk_object_signals[VISIBLE_DATA_CHANGED] =
355     g_signal_new ("visible_data_changed",
356                   G_TYPE_FROM_CLASS (klass),
357                   G_SIGNAL_RUN_LAST,
358                   G_STRUCT_OFFSET (AtkObjectClass, visible_data_changed),
359                   (GSignalAccumulator) NULL, NULL,
360                   g_cclosure_marshal_VOID__VOID,
361                   G_TYPE_NONE, 0);
362   atk_object_signals[ACTIVE_DESCENDANT_CHANGED] =
363     g_signal_new ("active_descendant_changed",
364                   G_TYPE_FROM_CLASS (klass),
365                   G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
366                   G_STRUCT_OFFSET (AtkObjectClass, active_descendant_changed),
367                   NULL, NULL,
368                   g_cclosure_marshal_VOID__POINTER,
369                   G_TYPE_NONE,
370                   1, G_TYPE_POINTER);
371 }
372
373 static void
374 atk_object_init  (AtkObject        *accessible,
375                   AtkObjectClass   *klass)
376 {
377   accessible->name = NULL;
378   accessible->description = NULL;
379   accessible->accessible_parent = NULL;
380   accessible->relation_set = atk_relation_set_new();
381   accessible->role = ATK_ROLE_UNKNOWN;
382 }
383
384 GType
385 atk_implementor_get_type (void)
386 {
387   static GType type = 0;
388
389   if (!type)
390     {
391       static const GTypeInfo typeInfo =
392       {
393         sizeof (AtkImplementorIface),
394         (GBaseInitFunc) NULL,
395         (GBaseFinalizeFunc) NULL,
396       } ;
397
398       type = g_type_register_static (G_TYPE_INTERFACE, "AtkImplementorIface", &typeInfo, 0) ;
399     }
400
401   return type;
402 }
403
404 /**
405  * atk_object_get_name:
406  * @accessible: an #AtkObject
407  *
408  * Gets the accessible name of the accessible.
409  *
410  * Returns: a character string representing the accessible name of the object.
411  **/
412 G_CONST_RETURN gchar*
413 atk_object_get_name (AtkObject *accessible)
414 {
415   AtkObjectClass *klass;
416
417   g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
418
419   klass = ATK_OBJECT_GET_CLASS (accessible);
420   if (klass->get_name)
421     return (klass->get_name) (accessible);
422   else
423     return NULL;
424 }
425
426 /**
427  * atk_object_get_description:
428  * @accessible: an #AtkObject
429  *
430  * Gets the accessible description of the accessible.
431  *
432  * Returns: a character string representing the accessible description
433  * of the accessible.
434  *
435  **/
436 G_CONST_RETURN gchar*
437 atk_object_get_description (AtkObject *accessible)
438 {
439   AtkObjectClass *klass;
440
441   g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
442
443   klass = ATK_OBJECT_GET_CLASS (accessible);
444   if (klass->get_description)
445     return (klass->get_description) (accessible);
446   else
447     return NULL;
448 }
449
450 /**
451  * atk_object_get_parent:
452  * @accessible: an #AtkObject
453  *
454  * Gets the accessible parent of the accessible.
455  *
456  * Returns: a #AtkObject representing the accessible parent of the accessible
457  **/
458 AtkObject*
459 atk_object_get_parent (AtkObject *accessible)
460 {
461   AtkObjectClass *klass;
462
463   g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
464
465   klass = ATK_OBJECT_GET_CLASS (accessible);
466   if (klass->get_parent)
467     return (klass->get_parent) (accessible);
468   else
469     return NULL;
470 }
471
472 /**
473  * atk_object_get_n_accessible_children:
474  * @accessible: an #AtkObject
475  *
476  * Gets the number of accessible children of the accessible.
477  *
478  * Returns: an integer representing the number of accessible children
479  * of the accessible.
480  **/
481 gint
482 atk_object_get_n_accessible_children (AtkObject *accessible)
483 {
484   AtkObjectClass *klass;
485
486   g_return_val_if_fail (ATK_IS_OBJECT (accessible), 0);
487
488   klass = ATK_OBJECT_GET_CLASS (accessible);
489   if (klass->get_n_children)
490     return (klass->get_n_children) (accessible);
491   else
492     return 0;
493 }
494
495 /**
496  * atk_object_ref_accessible_child:
497  * @accessible: an #AtkObject
498  * @i: a gint representing the position of the child, starting from 0
499  *
500  * Gets a reference to the specified accessible child of the object.
501  * The accessible children are 0-based so the first accessible child is
502  * at index 0, the second at index 1 and so on.
503  *
504  * Returns: an #AtkObject representing the specified accessible child
505  * of the accessible.
506  **/
507 AtkObject*
508 atk_object_ref_accessible_child (AtkObject   *accessible,
509                                  gint        i)
510 {
511   AtkObjectClass *klass;
512
513   g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
514
515   klass = ATK_OBJECT_GET_CLASS (accessible);
516   if (klass->ref_child)
517     return (klass->ref_child) (accessible, i);
518   else
519     return NULL;
520 }
521
522 /**
523  * atk_object_ref_relation_set:
524  * @accessible: an #AtkObject
525  *
526  * Gets the #AtkRelationSet associated with the object.
527  *
528  * Returns: an #AtkRelationSet representing the relation set of the object.
529  **/
530 AtkRelationSet*
531 atk_object_ref_relation_set (AtkObject *accessible)
532 {
533   AtkObjectClass *klass;
534
535   g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
536
537   klass = ATK_OBJECT_GET_CLASS (accessible);
538   if (klass->ref_relation_set)
539     return (klass->ref_relation_set) (accessible);
540   else
541     return NULL;
542 }
543
544 /**
545  * atk_role_register:
546  * @name: a character string describing the new role.
547  *
548  * Registers the role specified by @name.
549  *
550  * Returns: an #AtkRole for the new role.
551  **/
552 AtkRole
553 atk_role_register (const gchar *name)
554 {
555   if (!extra_roles)
556     extra_roles = g_ptr_array_new ();
557
558   g_ptr_array_add (extra_roles, g_strdup (name));
559   return extra_roles->len + ATK_ROLE_LAST_DEFINED;
560 }
561
562 /**
563  * atk_object_get_role:
564  * @accessible: an #AtkObject
565  *
566  * Gets the role of the accessible.
567  *
568  * Returns: an #AtkRole which is the role of the accessible
569  **/
570 AtkRole
571 atk_object_get_role (AtkObject *accessible) 
572 {
573   AtkObjectClass *klass;
574
575   g_return_val_if_fail (ATK_IS_OBJECT (accessible), ATK_ROLE_UNKNOWN);
576
577   klass = ATK_OBJECT_GET_CLASS (accessible);
578   if (klass->get_role)
579     return (klass->get_role) (accessible);
580   else
581     return ATK_ROLE_UNKNOWN;
582 }
583
584 /**
585  * atk_object_get_layer:
586  * @accessible: an #AtkObject
587  *
588  * Gets the layer of the accessible.
589  * DEPRECATED: use atk_component_get_layer instead!
590  *
591  * Returns: an #AtkLayer which is the layer of the accessible
592  **/
593 AtkLayer
594 atk_object_get_layer (AtkObject *accessible) 
595 {
596   AtkObjectClass *klass;
597
598   g_return_val_if_fail (ATK_IS_OBJECT (accessible), ATK_LAYER_INVALID);
599
600   klass = ATK_OBJECT_GET_CLASS (accessible);
601   if (klass->get_layer)
602     return (klass->get_layer) (accessible);
603   else
604     return ATK_LAYER_INVALID;
605 }
606
607 /**
608  * atk_object_get_mdi_zorder:
609  * @accessible: an #AtkObject
610  *
611  * Gets the zorder of the accessible. The value G_MININT will be returned 
612  * if the layer of the accessible is not ATK_LAYER_MDI.
613  * DEPRECATED: use atk_component_get_mdi_zorder instead!
614  *
615  * Returns: a gint which is the zorder of the accessible, i.e. the depth at 
616  * which the component is shown in relation to other components in the same 
617  * container.
618  **/
619 gint
620 atk_object_get_mdi_zorder (AtkObject *accessible) 
621 {
622   AtkObjectClass *klass;
623
624   g_return_val_if_fail (ATK_IS_OBJECT (accessible), G_MININT);
625
626   klass = ATK_OBJECT_GET_CLASS (accessible);
627   if (klass->get_mdi_zorder)
628     return (klass->get_mdi_zorder) (accessible);
629   else
630     return G_MININT;
631 }
632
633 /**
634  * atk_object_ref_state_set:
635  * @accessible: an #AtkObject
636  *
637  * Gets a reference to the state set of the accessible; the caller must
638  * unreference it when it is no longer needed.
639  *
640  * Returns: a reference to an #AtkStateSet which is the state
641  * set of the accessible
642  **/
643 AtkStateSet*
644 atk_object_ref_state_set (AtkObject *accessible) 
645 {
646   AtkObjectClass *klass;
647
648   g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
649
650   klass = ATK_OBJECT_GET_CLASS (accessible);
651   if (klass->ref_state_set)
652     return (klass->ref_state_set) (accessible);
653   else
654     return NULL;
655 }
656
657 /**
658  * atk_object_get_index_in_parent:
659  * @accessible: an #AtkObject
660  *
661  * Gets the 0-based index of this accessible in its parent; returns -1 if the
662  * accessible does not have an accessible parent.
663  *
664  * Returns: an integer which is the index of the accessible in its parent
665  **/
666 gint
667 atk_object_get_index_in_parent (AtkObject *accessible)
668 {
669   AtkObjectClass *klass;
670
671   g_return_val_if_fail (ATK_OBJECT (accessible), -1);
672
673   klass = ATK_OBJECT_GET_CLASS (accessible);
674   if (klass->get_index_in_parent)
675     return (klass->get_index_in_parent) (accessible);
676   else
677     return -1;
678 }
679
680 /**
681  * atk_object_set_name:
682  * @accessible: an #AtkObject
683  * @name: a character string to be set as the accessible name
684  *
685  * Sets the accessible name of the accessible.
686  **/
687 void
688 atk_object_set_name (AtkObject    *accessible,
689                      const gchar  *name)
690 {
691   AtkObjectClass *klass;
692
693   g_return_if_fail (ATK_IS_OBJECT (accessible));
694   g_return_if_fail (name != NULL);
695
696   klass = ATK_OBJECT_GET_CLASS (accessible);
697   if (klass->set_name)
698     {
699       (klass->set_name) (accessible, name);
700       g_object_notify (G_OBJECT (accessible), atk_object_name_property_name);
701     }
702 }
703
704 /**
705  * atk_object_set_description:
706  * @accessible: an #AtkObject
707  * @description : a character string to be set as the accessible description
708  *
709  * Sets the accessible description of the accessible.
710  **/
711 void
712 atk_object_set_description (AtkObject   *accessible,
713                             const gchar *description)
714 {
715   AtkObjectClass *klass;
716
717   g_return_if_fail (ATK_IS_OBJECT (accessible));
718   g_return_if_fail (description != NULL);
719
720   klass = ATK_OBJECT_GET_CLASS (accessible);
721   if (klass->set_description)
722     {
723       (klass->set_description) (accessible, description);
724       g_object_notify (G_OBJECT (accessible), atk_object_name_property_description);
725     }
726 }
727
728 /**
729  * atk_object_set_parent:
730  * @accessible: an #AtkObject
731  * @parent : an #AtkObject to be set as the accessible parent
732  *
733  * Sets the accessible parent of the accessible.
734  **/
735 void
736 atk_object_set_parent (AtkObject *accessible,
737                        AtkObject *parent)
738 {
739   AtkObjectClass *klass;
740
741   g_return_if_fail (ATK_IS_OBJECT (accessible));
742
743   klass = ATK_OBJECT_GET_CLASS (accessible);
744   if (klass->set_parent)
745     {
746       (klass->set_parent) (accessible, parent);
747       g_object_notify (G_OBJECT (accessible), atk_object_name_property_parent);
748     }
749 }
750
751 /**
752  * atk_object_set_role:
753  * @accessible: an #AtkObject
754  * @role : an #AtkRole to be set as the role
755  *
756  * Sets the role of the accessible.
757  **/
758 void
759 atk_object_set_role (AtkObject *accessible, 
760                      AtkRole   role)
761 {
762   AtkObjectClass *klass;
763
764   g_return_if_fail (ATK_IS_OBJECT (accessible));
765
766   klass = ATK_OBJECT_GET_CLASS (accessible);
767   if (klass->set_role)
768     {
769       (klass->set_role) (accessible, role);
770       g_object_notify (G_OBJECT (accessible), atk_object_name_property_role);
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       bindtextdomain (GETTEXT_PACKAGE, ATKLOCALEDIR);
1224 #ifdef HAVE_BIND_TEXTDOMAIN_CODESET
1225       bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
1226 #endif
1227     }
1228 #endif
1229
1230   switch (role)
1231     {
1232       case ATK_ROLE_INVALID:
1233         name = _("invalid");
1234         break;
1235       case ATK_ROLE_ACCEL_LABEL:
1236         name = _("accel-label");
1237         break;
1238       case ATK_ROLE_ALERT:
1239         name = _("alert");
1240         break;
1241       case ATK_ROLE_ANIMATION:
1242         name = _("animation");
1243         break;
1244       case ATK_ROLE_ARROW:
1245         name = _("arrow");
1246         break;
1247       case ATK_ROLE_CALENDAR:
1248         name = _("calendar");
1249         break;
1250       case ATK_ROLE_CANVAS:
1251         name = _("canvas");
1252         break;
1253       case ATK_ROLE_CHECK_BOX:
1254         name = _("check-box");
1255         break;
1256       case ATK_ROLE_CHECK_MENU_ITEM:
1257         name = _("check-menu-item");
1258         break;
1259       case ATK_ROLE_COLOR_CHOOSER:
1260         name = _("color-chooser");
1261         break;
1262       case ATK_ROLE_COLUMN_HEADER:
1263         name = _("column-header");
1264         break;
1265       case ATK_ROLE_COMBO_BOX:
1266         name = _("combo-box");
1267         break;
1268       case ATK_ROLE_DATE_EDITOR:
1269         name = _("date-editor");
1270         break;
1271       case ATK_ROLE_DESKTOP_ICON:
1272         name = _("desktop-icon");
1273         break;
1274       case ATK_ROLE_DESKTOP_FRAME:
1275         name = _("desktop-frame");
1276         break;
1277       case ATK_ROLE_DIAL:
1278         name = _("dial");
1279         break;
1280       case ATK_ROLE_DIALOG:
1281         name = _("dialog");
1282         break;
1283       case ATK_ROLE_DIRECTORY_PANE:
1284         name = _("directory-pane");
1285         break;
1286       case ATK_ROLE_DRAWING_AREA:
1287         name = _("drawing-area");
1288         break;
1289       case ATK_ROLE_FILE_CHOOSER:
1290         name = _("file-chooser");
1291         break;
1292       case ATK_ROLE_FILLER:
1293         name = _("filler");
1294         break;
1295       case ATK_ROLE_FONT_CHOOSER:
1296         name = _("font-chooser");
1297         break;
1298       case ATK_ROLE_FRAME:
1299         name = _("frame");
1300         break;
1301       case ATK_ROLE_GLASS_PANE:
1302         name = _("glass-pane");
1303         break;
1304       case ATK_ROLE_HTML_CONTAINER:
1305         name = _("html-container");
1306         break;
1307       case ATK_ROLE_ICON:
1308         name = _("icon");
1309         break;
1310       case ATK_ROLE_IMAGE:
1311         name = _("image");
1312         break;
1313       case ATK_ROLE_INTERNAL_FRAME:
1314         name = _("internal-frame");
1315         break;
1316       case ATK_ROLE_LABEL:
1317         name = _("label");
1318         break;
1319       case ATK_ROLE_LAYERED_PANE:
1320         name = _("layered-pane");
1321         break;
1322       case ATK_ROLE_LIST:
1323         name = _("list");
1324         break;
1325       case ATK_ROLE_LIST_ITEM:
1326         name = _("list-item");
1327         break;
1328       case ATK_ROLE_MENU:
1329         name = _("menu");
1330         break;
1331       case ATK_ROLE_MENU_BAR:
1332         name = _("menu-bar");
1333         break;
1334       case ATK_ROLE_MENU_ITEM:
1335         name = _("menu-item");
1336         break;
1337       case ATK_ROLE_OPTION_PANE:
1338         name = _("option-pane");
1339         break;
1340       case ATK_ROLE_PAGE_TAB:
1341         name = _("page-tab");
1342         break;
1343       case ATK_ROLE_PAGE_TAB_LIST:
1344         name = _("page-tab-list");
1345         break;
1346       case ATK_ROLE_PANEL:
1347         name = _("panel");
1348         break;
1349       case ATK_ROLE_PASSWORD_TEXT:
1350         name = _("password-text");
1351         break;
1352       case ATK_ROLE_POPUP_MENU:
1353         name = _("popup-menu");
1354         break;
1355       case ATK_ROLE_PROGRESS_BAR:
1356         name = _("progress-bar");
1357         break;
1358       case ATK_ROLE_PUSH_BUTTON:
1359         name = _("push-button");
1360         break;
1361       case ATK_ROLE_RADIO_BUTTON:
1362         name = _("radio-button");
1363         break;
1364       case ATK_ROLE_RADIO_MENU_ITEM:
1365         name = _("radio-menu-item");
1366         break;
1367       case ATK_ROLE_ROOT_PANE:
1368         name = _("root-pane");
1369         break;
1370       case ATK_ROLE_ROW_HEADER:
1371         name = _("row-header");
1372         break;
1373       case ATK_ROLE_SCROLL_BAR:
1374         name = _("scroll-bar");
1375         break;
1376       case ATK_ROLE_SCROLL_PANE:
1377         name = _("scroll-pane");
1378         break;
1379       case ATK_ROLE_SEPARATOR:
1380         name = _("separator");
1381         break;
1382       case ATK_ROLE_SLIDER:
1383         name = _("slider");
1384         break;
1385       case ATK_ROLE_SPLIT_PANE:
1386         name = _("split-pane");
1387         break;
1388       case ATK_ROLE_SPIN_BUTTON:
1389         name = _("spin-button");
1390         break;
1391       case ATK_ROLE_STATUSBAR:
1392         name = _("statusbar");
1393         break;
1394       case ATK_ROLE_TABLE:
1395         name = _("table");
1396         break;
1397       case ATK_ROLE_TABLE_CELL:
1398         name = _("table-cell");
1399         break;
1400       case ATK_ROLE_TABLE_COLUMN_HEADER:
1401         name = _("table-column-header");
1402         break;
1403       case ATK_ROLE_TABLE_ROW_HEADER:
1404         name = _("table-row-header");
1405         break;
1406       case ATK_ROLE_TEAR_OFF_MENU_ITEM:
1407         name = _("tear-off-menu-item");
1408         break;
1409       case ATK_ROLE_TERMINAL:
1410         name = _("terminal");
1411         break;
1412       case ATK_ROLE_TEXT:
1413         name = _("text");
1414         break;
1415       case ATK_ROLE_TOGGLE_BUTTON:
1416         name = _("toggle-button");
1417         break;
1418       case ATK_ROLE_TOOL_BAR:
1419         name = _("tool-bar");
1420         break;
1421       case ATK_ROLE_TOOL_TIP:
1422         name = _("tool-tip");
1423         break;
1424       case ATK_ROLE_TREE:
1425         name = _("tree");
1426         break;
1427       case ATK_ROLE_TREE_TABLE:
1428         name = _("tree-table");
1429         break;
1430       case ATK_ROLE_UNKNOWN:
1431         name = _("unknown");
1432         break;
1433       case ATK_ROLE_VIEWPORT:
1434         name = _("viewport");
1435         break;
1436       case ATK_ROLE_WINDOW:
1437         name = _("window");
1438         break;
1439       case ATK_ROLE_HEADER:
1440         name = _("header");
1441         break;
1442       case ATK_ROLE_FOOTER:
1443         name = _("footer");
1444         break;
1445       case ATK_ROLE_PARAGRAPH:
1446         name = _("paragraph");
1447         break;
1448       case ATK_ROLE_RULER:
1449         name = _("ruler");
1450         break;
1451       case ATK_ROLE_APPLICATION:
1452         name = _("application");
1453         break;
1454       default:
1455         name = atk_role_get_name (role);
1456         break;
1457     }
1458   return name;
1459 }
1460
1461 /**
1462  * atk_role_for_name:
1463  * @name: a string which is the (non-localized) name of an ATK role.
1464  *
1465  * Get the #AtkRole type corresponding to a rolew name.
1466  *
1467  * Returns: the #AtkRole enumerated type corresponding to the specified
1468 name,
1469  *          or #ATK_ROLE_INVALID if no matching role is found.
1470  **/
1471 AtkRole
1472 atk_role_for_name (const gchar *name)
1473 {
1474   GTypeClass *type_class;
1475   GEnumValue *value;
1476   AtkRole role = ATK_ROLE_INVALID;
1477
1478   g_return_val_if_fail (name, ATK_ROLE_INVALID);
1479
1480   type_class = g_type_class_ref (ATK_TYPE_ROLE);
1481   g_return_val_if_fail (G_IS_ENUM_CLASS (type_class), ATK_ROLE_INVALID);
1482
1483   value = g_enum_get_value_by_nick (G_ENUM_CLASS (type_class), name);
1484
1485   if (value)
1486     {
1487       role = value->value;
1488     }
1489   else
1490     {
1491      gint i;
1492
1493       if (extra_roles)
1494         {
1495           for (i = 0; i < extra_roles->len; i++)
1496             {
1497               gchar *extra_role = (gchar *)g_ptr_array_index (extra_roles, i);
1498
1499               g_return_val_if_fail (extra_role, ATK_ROLE_INVALID);
1500
1501               if (strcmp (name, extra_role) == 0)
1502                 {
1503                   role = i + 1 + ATK_ROLE_LAST_DEFINED;
1504                   break;
1505                 }
1506             }
1507         }
1508     }
1509   g_type_class_unref (type_class);
1510   
1511   return role;
1512 }
1513
1514 /**
1515  * atk_object_add_relationship:
1516  * @object: The #AtkObject to which an AtkRelation is to be added. 
1517  * @relationship: The #AtkRelationType of the relation
1518  * @target: The #AtkObject which is to be the target of the relation.
1519  *
1520  * Adds a relationship of the specified type with the specified target.
1521  *
1522  * Returns TRUE if the relationship is added.
1523  **/
1524 gboolean
1525 atk_object_add_relationship (AtkObject       *object,
1526                              AtkRelationType relationship,
1527                              AtkObject       *target)
1528 {
1529   AtkObject *array[1];
1530   AtkRelation *relation;
1531
1532   g_return_val_if_fail (ATK_IS_OBJECT (object), FALSE);
1533   g_return_val_if_fail (ATK_IS_OBJECT (target), FALSE);
1534
1535   array[0] = target;
1536   relation = atk_relation_new (array, 1, relationship);
1537   atk_relation_set_add (object->relation_set, relation);
1538   g_object_unref (relation);
1539
1540   return TRUE;
1541 }
1542
1543 /**
1544  * atk_object_remove_relationship:
1545  * @object: The #AtkObject from which an AtkRelation is to be removed. 
1546  * @relationship: The #AtkRelationType of the relation
1547  * @target: The #AtkObject which is the target of the relation to be removed.
1548  *
1549  * Removes a relationship of the specified type with the specified target.
1550  *
1551  * Returns TRUE if the relationship is removed.
1552  **/
1553 gboolean
1554 atk_object_remove_relationship (AtkObject       *object,
1555                                 AtkRelationType relationship,
1556                                 AtkObject       *target)
1557 {
1558   gint n_relations, i;
1559   gboolean ret = FALSE;
1560   AtkRelation *relation;
1561
1562   g_return_val_if_fail (ATK_IS_OBJECT (object), FALSE);
1563   g_return_val_if_fail (ATK_IS_OBJECT (target), FALSE);
1564
1565   n_relations = atk_relation_set_get_n_relations (object->relation_set);
1566   for (i = 0; i < n_relations; i++)
1567     {
1568       relation = atk_relation_set_get_relation (object->relation_set, i);
1569       if (atk_relation_get_relation_type (relation) == relationship)
1570         {
1571           GPtrArray *array;
1572
1573           array = atk_relation_get_target (relation);
1574         
1575           if (g_ptr_array_index (array, 0) == target)
1576             {
1577               atk_relation_set_remove (object->relation_set, relation); 
1578               ret = TRUE;
1579               break;
1580             }
1581         }
1582     }
1583
1584   return ret;
1585 }