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