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