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