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