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