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