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