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