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