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