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