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