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