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