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