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