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