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