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