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