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