*** empty log message ***
[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
766   g_return_if_fail (ATK_IS_OBJECT (accessible));
767
768   klass = ATK_OBJECT_GET_CLASS (accessible);
769   if (klass->set_role)
770     {
771       (klass->set_role) (accessible, role);
772       g_object_notify (G_OBJECT (accessible), atk_object_name_property_role);
773     }
774 }
775
776 /**
777  * atk_object_connect_property_change_handler:
778  * @accessible: an #AtkObject
779  * @handler : a function to be called when a property changes its value
780  *
781  * Specifies a function to be called when a property changes value.
782  *
783  * Returns: a #guint which is the handler id used in 
784  * atk_object_remove_property_change_handler()
785  **/
786 guint
787 atk_object_connect_property_change_handler (AtkObject *accessible,
788                                             AtkPropertyChangeHandler *handler)
789 {
790   AtkObjectClass *klass;
791
792   g_return_val_if_fail (ATK_IS_OBJECT (accessible), 0);
793   g_return_val_if_fail ((handler != NULL), 0);
794
795   klass = ATK_OBJECT_GET_CLASS (accessible);
796   if (klass->connect_property_change_handler)
797     return (klass->connect_property_change_handler) (accessible, handler);
798   else
799     return 0;
800 }
801
802 /**
803  * atk_object_remove_property_change_handler:
804  * @accessible: an #AtkObject
805  * @handler_id : a guint which identifies the handler to be removed.
806  * 
807  * Removes a property change handler.
808  **/
809 void
810 atk_object_remove_property_change_handler  (AtkObject *accessible,
811                                             guint      handler_id)
812 {
813   AtkObjectClass *klass;
814
815   g_return_if_fail (ATK_IS_OBJECT (accessible));
816
817   klass = ATK_OBJECT_GET_CLASS (accessible);
818   if (klass->remove_property_change_handler)
819     (klass->remove_property_change_handler) (accessible, handler_id);
820 }
821
822 /**
823  * atk_object_notify_state_change:
824  * @accessible: an #AtkObject
825  * @state: an #AtkState whose state is changed
826  * @value : a gboolean which indicates whether the state is being set on or off
827  * 
828  * Emits a state-change signal for the specified state. 
829  **/
830 void
831 atk_object_notify_state_change (AtkObject *accessible,
832                                 AtkState  state,
833                                 gboolean  value)
834 {
835   G_CONST_RETURN gchar* name;
836
837   name = atk_state_type_get_name (state);
838   g_signal_emit (accessible, atk_object_signals[STATE_CHANGE],
839                  g_quark_from_string (name),
840                  name, value, NULL);
841 }
842
843 /**
844  * atk_implementor_ref_accessible:
845  * @implementor: The #GObject instance which should implement #AtkImplementorIface
846  * if a non-null return value is required.
847  * 
848  * Gets a reference to an object's #AtkObject implementation, if
849  * the object implements #AtkObjectIface
850  *
851  * Returns: a reference to an object's #AtkObject implementation
852  */
853 AtkObject *
854 atk_implementor_ref_accessible (AtkImplementor *object)
855 {
856   AtkImplementorIface *iface;
857   AtkObject           *accessible = NULL;
858
859   g_return_val_if_fail (ATK_IS_IMPLEMENTOR (object), NULL);
860
861   iface = ATK_IMPLEMENTOR_GET_IFACE (object);
862
863   if (iface != NULL) 
864     accessible =  iface->ref_accessible (object);
865
866   g_return_val_if_fail ((accessible != NULL), NULL);
867
868   return accessible;
869 }
870
871 static AtkRelationSet*
872 atk_object_real_ref_relation_set (AtkObject *accessible)
873 {
874   g_return_val_if_fail (accessible->relation_set, NULL);
875   g_object_ref (accessible->relation_set); 
876
877   return accessible->relation_set;
878 }
879
880 static void
881 atk_object_real_set_property (GObject      *object,
882                               guint         prop_id,
883                               const GValue *value,
884                               GParamSpec   *pspec)
885 {
886   AtkObject *accessible;
887
888   accessible = ATK_OBJECT (object);
889
890   switch (prop_id)
891     {
892     case PROP_NAME:
893       atk_object_set_name (accessible, g_value_get_string (value));
894       break;
895     case PROP_DESCRIPTION:
896       atk_object_set_description (accessible, g_value_get_string (value));
897       break;
898     case PROP_ROLE:
899       atk_object_set_role (accessible, g_value_get_int (value));
900       break;
901     case PROP_PARENT:
902       atk_object_set_parent (accessible, g_value_get_object (value));
903       break;
904     case PROP_VALUE:
905       if (ATK_IS_VALUE (accessible))
906         atk_value_set_current_value (ATK_VALUE (accessible), value);
907       break;
908     case PROP_TABLE_SUMMARY:
909       if (ATK_IS_TABLE (accessible))
910         atk_table_set_summary (ATK_TABLE (accessible), g_value_get_object (value));
911       break;
912     case PROP_TABLE_CAPTION_OBJECT:
913       if (ATK_IS_TABLE (accessible))
914         atk_table_set_caption (ATK_TABLE (accessible), g_value_get_object (value));
915       break;
916     default:
917       break;
918     }
919 }
920
921 static void
922 atk_object_real_get_property (GObject      *object,
923                               guint         prop_id,
924                               GValue       *value,
925                               GParamSpec   *pspec)
926 {
927   AtkObject *accessible;
928
929   accessible = ATK_OBJECT (object);
930
931   switch (prop_id)
932     {
933     case PROP_NAME:
934       g_value_set_string (value, atk_object_get_name (accessible));
935       break;
936     case PROP_DESCRIPTION:
937       g_value_set_string (value, atk_object_get_description (accessible));
938       break;
939     case PROP_ROLE:
940       g_value_set_int (value, atk_object_get_role (accessible));
941       break;
942     case PROP_LAYER:
943       if (ATK_IS_COMPONENT (accessible))
944         g_value_set_int (value, atk_component_get_layer (ATK_COMPONENT (accessible)));
945       break;
946     case PROP_MDI_ZORDER:
947       if (ATK_IS_COMPONENT (accessible))
948         g_value_set_int (value, atk_component_get_mdi_zorder (ATK_COMPONENT (accessible)));
949       break;
950     case PROP_PARENT:
951       g_value_set_object (value, atk_object_get_parent (accessible));
952       break;
953     case PROP_VALUE:
954       if (ATK_IS_VALUE (accessible))
955         atk_value_get_current_value (ATK_VALUE (accessible), value);
956       break;
957     case PROP_TABLE_SUMMARY:
958       if (ATK_IS_TABLE (accessible))
959         g_value_set_object (value, atk_table_get_summary (ATK_TABLE (accessible)));
960       break;
961     case PROP_TABLE_CAPTION_OBJECT:
962       if (ATK_IS_TABLE (accessible))
963         g_value_set_object (value, atk_table_get_caption (ATK_TABLE (accessible)));
964       break;
965     default:
966       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
967       break;
968     }
969 }
970
971 static void
972 atk_object_finalize (GObject *object)
973 {
974   AtkObject        *accessible;
975
976   g_return_if_fail (ATK_IS_OBJECT (object));
977
978   accessible = ATK_OBJECT (object);
979
980   g_free (accessible->name);
981   g_free (accessible->description);
982
983   /*
984    * Free memory allocated for relation set if it have been allocated.
985    */
986   if (accessible->relation_set)
987     g_object_unref (accessible->relation_set);
988
989   if (accessible->accessible_parent)
990     g_object_unref (accessible->accessible_parent);
991
992   G_OBJECT_CLASS (parent_class)->finalize (object);
993 }
994
995 static G_CONST_RETURN gchar*
996 atk_object_real_get_name (AtkObject *object)
997 {
998   return object->name;
999 }
1000
1001 static G_CONST_RETURN gchar*
1002 atk_object_real_get_description (AtkObject *object)
1003 {
1004   return object->description;
1005 }
1006
1007 static AtkObject*
1008 atk_object_real_get_parent (AtkObject       *object)
1009 {
1010   return object->accessible_parent;
1011 }
1012
1013 static AtkRole
1014 atk_object_real_get_role (AtkObject       *object)
1015 {
1016   return object->role;
1017 }
1018
1019 static AtkLayer
1020 atk_object_real_get_layer (AtkObject       *object)
1021 {
1022   return object->layer;
1023 }
1024
1025 static AtkStateSet*
1026 atk_object_real_ref_state_set (AtkObject *accessible) 
1027 {
1028   AtkStateSet *state_set;
1029   AtkObject *ap;
1030
1031   state_set = atk_state_set_new ();
1032
1033   ap = atk_object_get_parent (accessible);
1034   if (ap)
1035     if (ATK_IS_SELECTION (ap))
1036       {
1037         int i;
1038
1039         atk_state_set_add_state (state_set, ATK_STATE_SELECTABLE);
1040
1041         i = atk_object_get_index_in_parent (accessible);
1042         if (i >= 0)
1043           if (atk_selection_is_child_selected(ATK_SELECTION (ap), i))
1044             atk_state_set_add_state (state_set, ATK_STATE_SELECTED);
1045       } 
1046
1047   return state_set; 
1048 }
1049
1050 static void
1051 atk_object_real_set_name (AtkObject       *object,
1052                           const gchar     *name)
1053 {
1054   g_free (object->name);
1055   object->name = g_strdup (name);
1056 }
1057
1058 static void
1059 atk_object_real_set_description (AtkObject       *object,
1060                                  const gchar     *description)
1061 {
1062   g_free (object->description);
1063   object->description = g_strdup (description);
1064 }
1065
1066 static void
1067 atk_object_real_set_parent (AtkObject       *object,
1068                             AtkObject       *parent)
1069 {
1070   if (object->accessible_parent)
1071     g_object_unref (object->accessible_parent);
1072
1073   object->accessible_parent = parent;
1074   if (object->accessible_parent)
1075     g_object_ref (object->accessible_parent);
1076 }
1077
1078 static void
1079 atk_object_real_set_role (AtkObject *object,
1080                           AtkRole   role)
1081 {
1082   object->role = role;
1083 }
1084
1085 static guint
1086 atk_object_real_connect_property_change_handler (AtkObject                *obj,
1087                                                  AtkPropertyChangeHandler *handler)
1088 {
1089   return g_signal_connect_closure_by_id (obj,
1090                                          atk_object_signals[PROPERTY_CHANGE],
1091                                          0,
1092                                          g_cclosure_new (
1093                                          G_CALLBACK (handler), NULL,
1094                                          (GClosureNotify) NULL),
1095                                          FALSE);
1096 }
1097
1098 static void
1099 atk_object_real_remove_property_change_handler (AtkObject           *obj,
1100                                           guint               handler_id)
1101 {
1102   g_signal_handler_disconnect (obj, handler_id);
1103 }
1104
1105 /**
1106  * atk_object_initialize:
1107  * @accessible: a #AtkObject
1108  * @data: a #gpointer which identifies the object for which the AtkObject was created.
1109  *
1110  * This function is called when implementing subclasses of #AtkObject.
1111  * It does initialization required for the new object. It is intended
1112  * that this function should called only in the ..._new() functions used
1113  * to create an instance of a subclass of #AtkObject
1114  **/
1115 void
1116 atk_object_initialize (AtkObject  *accessible,
1117                        gpointer   data)
1118 {
1119   AtkObjectClass *klass;
1120
1121   g_return_if_fail (ATK_IS_OBJECT (accessible));
1122
1123   klass = ATK_OBJECT_GET_CLASS (accessible);
1124   if (klass->initialize)
1125     klass->initialize (accessible, data);
1126 }
1127
1128 /*
1129  * This function is a signal handler for notify signal which gets emitted
1130  * when a property changes value.
1131  *
1132  * It constructs an AtkPropertyValues structure and emits a "property_changed"
1133  * signal which causes the user specified AtkPropertyChangeHandler
1134  * to be called.
1135  */
1136 static void
1137 atk_object_notify (GObject     *obj,
1138                    GParamSpec  *pspec)
1139 {
1140   AtkPropertyValues values = { 0, };
1141
1142   g_value_init (&values.new_value, pspec->value_type);
1143   g_object_get_property (obj, pspec->name, &values.new_value);
1144   values.property_name = pspec->name;
1145   g_signal_emit (obj, atk_object_signals[PROPERTY_CHANGE],
1146                  g_quark_from_string (pspec->name),
1147                  &values, NULL);
1148   g_value_unset (&values.new_value);
1149 }
1150
1151 /**
1152  * atk_role_get_name:
1153  * @role: The #AtkRole whose name is required
1154  *
1155  * Gets the description string describing the #AtkRole @role.
1156  *
1157  * Returns: the string describing the AtkRole
1158  */
1159 G_CONST_RETURN gchar*
1160 atk_role_get_name (AtkRole role)
1161 {
1162   GTypeClass *type_class;
1163   GEnumValue *value;
1164   gchar *name = NULL;
1165
1166   type_class = g_type_class_ref (ATK_TYPE_ROLE);
1167   g_return_val_if_fail (G_IS_ENUM_CLASS (type_class), NULL);
1168
1169   value = g_enum_get_value (G_ENUM_CLASS (type_class), role);
1170
1171   if (value)
1172     {
1173       name = value->value_nick;
1174     }
1175   else
1176     {
1177       if (extra_roles)
1178         {
1179           gint n = role;
1180
1181           n -= ATK_ROLE_LAST_DEFINED + 1;
1182
1183           if (n < extra_roles->len)
1184             name = g_ptr_array_index (extra_roles, n);
1185         }
1186     }
1187   g_type_class_unref (type_class);
1188   return name;
1189 }
1190
1191 #ifdef G_OS_WIN32
1192
1193 #undef ATKLOCALEDIR
1194
1195 #define ATKLOCALEDIR get_atk_locale_dir()
1196
1197 G_WIN32_DLLMAIN_FOR_DLL_NAME(static, dll_name)
1198
1199 static char *
1200 get_atk_locale_dir (void)
1201 {
1202   return g_win32_get_package_installation_subdirectory
1203     (GETTEXT_PACKAGE, dll_name, "lib/locale");
1204 }
1205
1206 #endif
1207
1208 /**
1209  * atk_role_get_localized_name:
1210  * @role: The #AtkRole whose localized name is required
1211  *
1212  * Gets the localized description string describing the #AtkRole @role.
1213  *
1214  * Returns: the localized string describing the AtkRole
1215  **/
1216 G_CONST_RETURN gchar*
1217 atk_role_get_localized_name (AtkRole role)
1218 {
1219   G_CONST_RETURN gchar *name;
1220   gboolean gettext_initialized = FALSE;
1221
1222 #ifdef ENABLE_NLS
1223   if (!gettext_initialized)
1224     {
1225       bindtextdomain (GETTEXT_PACKAGE, ATKLOCALEDIR);
1226 #ifdef HAVE_BIND_TEXTDOMAIN_CODESET
1227       bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
1228 #endif
1229     }
1230 #endif
1231
1232   switch (role)
1233     {
1234       case ATK_ROLE_INVALID:
1235         name = _("invalid");
1236         break;
1237       case ATK_ROLE_ACCEL_LABEL:
1238         name = _("accel-label");
1239         break;
1240       case ATK_ROLE_ALERT:
1241         name = _("alert");
1242         break;
1243       case ATK_ROLE_ANIMATION:
1244         name = _("animation");
1245         break;
1246       case ATK_ROLE_ARROW:
1247         name = _("arrow");
1248         break;
1249       case ATK_ROLE_CALENDAR:
1250         name = _("calendar");
1251         break;
1252       case ATK_ROLE_CANVAS:
1253         name = _("canvas");
1254         break;
1255       case ATK_ROLE_CHECK_BOX:
1256         name = _("check-box");
1257         break;
1258       case ATK_ROLE_CHECK_MENU_ITEM:
1259         name = _("check-menu-item");
1260         break;
1261       case ATK_ROLE_COLOR_CHOOSER:
1262         name = _("color-chooser");
1263         break;
1264       case ATK_ROLE_COLUMN_HEADER:
1265         name = _("column-header");
1266         break;
1267       case ATK_ROLE_COMBO_BOX:
1268         name = _("combo-box");
1269         break;
1270       case ATK_ROLE_DATE_EDITOR:
1271         name = _("date-editor");
1272         break;
1273       case ATK_ROLE_DESKTOP_ICON:
1274         name = _("desktop-icon");
1275         break;
1276       case ATK_ROLE_DESKTOP_FRAME:
1277         name = _("desktop-frame");
1278         break;
1279       case ATK_ROLE_DIAL:
1280         name = _("dial");
1281         break;
1282       case ATK_ROLE_DIALOG:
1283         name = _("dialog");
1284         break;
1285       case ATK_ROLE_DIRECTORY_PANE:
1286         name = _("directory-pane");
1287         break;
1288       case ATK_ROLE_DRAWING_AREA:
1289         name = _("drawing-area");
1290         break;
1291       case ATK_ROLE_FILE_CHOOSER:
1292         name = _("file-chooser");
1293         break;
1294       case ATK_ROLE_FILLER:
1295         name = _("filler");
1296         break;
1297       case ATK_ROLE_FONT_CHOOSER:
1298         name = _("font-chooser");
1299         break;
1300       case ATK_ROLE_FRAME:
1301         name = _("frame");
1302         break;
1303       case ATK_ROLE_GLASS_PANE:
1304         name = _("glass-pane");
1305         break;
1306       case ATK_ROLE_HTML_CONTAINER:
1307         name = _("html-container");
1308         break;
1309       case ATK_ROLE_ICON:
1310         name = _("icon");
1311         break;
1312       case ATK_ROLE_IMAGE:
1313         name = _("image");
1314         break;
1315       case ATK_ROLE_INTERNAL_FRAME:
1316         name = _("internal-frame");
1317         break;
1318       case ATK_ROLE_LABEL:
1319         name = _("label");
1320         break;
1321       case ATK_ROLE_LAYERED_PANE:
1322         name = _("layered-pane");
1323         break;
1324       case ATK_ROLE_LIST:
1325         name = _("list");
1326         break;
1327       case ATK_ROLE_LIST_ITEM:
1328         name = _("list-item");
1329         break;
1330       case ATK_ROLE_MENU:
1331         name = _("menu");
1332         break;
1333       case ATK_ROLE_MENU_BAR:
1334         name = _("menu-bar");
1335         break;
1336       case ATK_ROLE_MENU_ITEM:
1337         name = _("menu-item");
1338         break;
1339       case ATK_ROLE_OPTION_PANE:
1340         name = _("option-pane");
1341         break;
1342       case ATK_ROLE_PAGE_TAB:
1343         name = _("page-tab");
1344         break;
1345       case ATK_ROLE_PAGE_TAB_LIST:
1346         name = _("page-tab-list");
1347         break;
1348       case ATK_ROLE_PANEL:
1349         name = _("panel");
1350         break;
1351       case ATK_ROLE_PASSWORD_TEXT:
1352         name = _("password-text");
1353         break;
1354       case ATK_ROLE_POPUP_MENU:
1355         name = _("popup-menu");
1356         break;
1357       case ATK_ROLE_PROGRESS_BAR:
1358         name = _("progress-bar");
1359         break;
1360       case ATK_ROLE_PUSH_BUTTON:
1361         name = _("push-button");
1362         break;
1363       case ATK_ROLE_RADIO_BUTTON:
1364         name = _("radio-button");
1365         break;
1366       case ATK_ROLE_RADIO_MENU_ITEM:
1367         name = _("radio-menu-item");
1368         break;
1369       case ATK_ROLE_ROOT_PANE:
1370         name = _("root-pane");
1371         break;
1372       case ATK_ROLE_ROW_HEADER:
1373         name = _("row-header");
1374         break;
1375       case ATK_ROLE_SCROLL_BAR:
1376         name = _("scroll-bar");
1377         break;
1378       case ATK_ROLE_SCROLL_PANE:
1379         name = _("scroll-pane");
1380         break;
1381       case ATK_ROLE_SEPARATOR:
1382         name = _("separator");
1383         break;
1384       case ATK_ROLE_SLIDER:
1385         name = _("slider");
1386         break;
1387       case ATK_ROLE_SPLIT_PANE:
1388         name = _("split-pane");
1389         break;
1390       case ATK_ROLE_SPIN_BUTTON:
1391         name = _("spin-button");
1392         break;
1393       case ATK_ROLE_STATUSBAR:
1394         name = _("statusbar");
1395         break;
1396       case ATK_ROLE_TABLE:
1397         name = _("table");
1398         break;
1399       case ATK_ROLE_TABLE_CELL:
1400         name = _("table-cell");
1401         break;
1402       case ATK_ROLE_TABLE_COLUMN_HEADER:
1403         name = _("table-column-header");
1404         break;
1405       case ATK_ROLE_TABLE_ROW_HEADER:
1406         name = _("table-row-header");
1407         break;
1408       case ATK_ROLE_TEAR_OFF_MENU_ITEM:
1409         name = _("tear-off-menu-item");
1410         break;
1411       case ATK_ROLE_TERMINAL:
1412         name = _("terminal");
1413         break;
1414       case ATK_ROLE_TEXT:
1415         name = _("text");
1416         break;
1417       case ATK_ROLE_TOGGLE_BUTTON:
1418         name = _("toggle-button");
1419         break;
1420       case ATK_ROLE_TOOL_BAR:
1421         name = _("tool-bar");
1422         break;
1423       case ATK_ROLE_TOOL_TIP:
1424         name = _("tool-tip");
1425         break;
1426       case ATK_ROLE_TREE:
1427         name = _("tree");
1428         break;
1429       case ATK_ROLE_TREE_TABLE:
1430         name = _("tree-table");
1431         break;
1432       case ATK_ROLE_UNKNOWN:
1433         name = _("unknown");
1434         break;
1435       case ATK_ROLE_VIEWPORT:
1436         name = _("viewport");
1437         break;
1438       case ATK_ROLE_WINDOW:
1439         name = _("window");
1440         break;
1441       case ATK_ROLE_HEADER:
1442         name = _("header");
1443         break;
1444       case ATK_ROLE_FOOTER:
1445         name = _("footer");
1446         break;
1447       case ATK_ROLE_PARAGRAPH:
1448         name = _("paragraph");
1449         break;
1450       case ATK_ROLE_RULER:
1451         name = _("ruler");
1452         break;
1453       case ATK_ROLE_APPLICATION:
1454         name = _("application");
1455         break;
1456       default:
1457         name = atk_role_get_name (role);
1458         break;
1459     }
1460   return name;
1461 }
1462
1463 /**
1464  * atk_role_for_name:
1465  * @name: a string which is the (non-localized) name of an ATK role.
1466  *
1467  * Get the #AtkRole type corresponding to a rolew name.
1468  *
1469  * Returns: the #AtkRole enumerated type corresponding to the specified
1470 name,
1471  *          or #ATK_ROLE_INVALID if no matching role is found.
1472  **/
1473 AtkRole
1474 atk_role_for_name (const gchar *name)
1475 {
1476   GTypeClass *type_class;
1477   GEnumValue *value;
1478   AtkRole role = ATK_ROLE_INVALID;
1479
1480   g_return_val_if_fail (name, ATK_ROLE_INVALID);
1481
1482   type_class = g_type_class_ref (ATK_TYPE_ROLE);
1483   g_return_val_if_fail (G_IS_ENUM_CLASS (type_class), ATK_ROLE_INVALID);
1484
1485   value = g_enum_get_value_by_nick (G_ENUM_CLASS (type_class), name);
1486
1487   if (value)
1488     {
1489       role = value->value;
1490     }
1491   else
1492     {
1493      gint i;
1494
1495       if (extra_roles)
1496         {
1497           for (i = 0; i < extra_roles->len; i++)
1498             {
1499               gchar *extra_role = (gchar *)g_ptr_array_index (extra_roles, i);
1500
1501               g_return_val_if_fail (extra_role, ATK_ROLE_INVALID);
1502
1503               if (strcmp (name, extra_role) == 0)
1504                 {
1505                   role = i + 1 + ATK_ROLE_LAST_DEFINED;
1506                   break;
1507                 }
1508             }
1509         }
1510     }
1511   g_type_class_unref (type_class);
1512   
1513   return role;
1514 }
1515
1516 /**
1517  * atk_object_add_relationship:
1518  * @object: The #AtkObject to which an AtkRelation is to be added. 
1519  * @relationship: The #AtkRelationType of the relation
1520  * @target: The #AtkObject which is to be the target of the relation.
1521  *
1522  * Adds a relationship of the specified type with the specified target.
1523  *
1524  * Returns TRUE if the relationship is added.
1525  **/
1526 gboolean
1527 atk_object_add_relationship (AtkObject       *object,
1528                              AtkRelationType relationship,
1529                              AtkObject       *target)
1530 {
1531   AtkObject *array[1];
1532   AtkRelation *relation;
1533
1534   g_return_val_if_fail (ATK_IS_OBJECT (object), FALSE);
1535   g_return_val_if_fail (ATK_IS_OBJECT (target), FALSE);
1536
1537   array[0] = target;
1538   relation = atk_relation_new (array, 1, relationship);
1539   atk_relation_set_add (object->relation_set, relation);
1540   g_object_unref (relation);
1541
1542   return TRUE;
1543 }
1544
1545 /**
1546  * atk_object_remove_relationship:
1547  * @object: The #AtkObject from which an AtkRelation is to be removed. 
1548  * @relationship: The #AtkRelationType of the relation
1549  * @target: The #AtkObject which is the target of the relation to be removed.
1550  *
1551  * Removes a relationship of the specified type with the specified target.
1552  *
1553  * Returns TRUE if the relationship is removed.
1554  **/
1555 gboolean
1556 atk_object_remove_relationship (AtkObject       *object,
1557                                 AtkRelationType relationship,
1558                                 AtkObject       *target)
1559 {
1560   gint n_relations, i;
1561   gboolean ret = FALSE;
1562   AtkRelation *relation;
1563
1564   g_return_val_if_fail (ATK_IS_OBJECT (object), FALSE);
1565   g_return_val_if_fail (ATK_IS_OBJECT (target), FALSE);
1566
1567   n_relations = atk_relation_set_get_n_relations (object->relation_set);
1568   for (i = 0; i < n_relations; i++)
1569     {
1570       relation = atk_relation_set_get_relation (object->relation_set, i);
1571       if (atk_relation_get_relation_type (relation) == relationship)
1572         {
1573           GPtrArray *array;
1574
1575           array = atk_relation_get_target (relation);
1576         
1577           if (g_ptr_array_index (array, 0) == target)
1578             {
1579               atk_relation_set_remove (object->relation_set, relation); 
1580               ret = TRUE;
1581               break;
1582             }
1583         }
1584     }
1585
1586   return ret;
1587 }
1588
1589 static void
1590 atk_object_real_initialize (AtkObject *accessible,
1591                             gpointer  data)
1592 {
1593   return;
1594 }