Deprecate AtkObject::focus-event signal and all related methods
[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
559   /**
560    * AtkObject::focus-event:
561    * @atkobject: the object which received the signal
562    * @arg1: a boolean value which indicates whether the object gained
563    * or lost focus.
564    *
565    * The signal "focus-event" is emitted when an object gained or lost
566    * focus.
567    *
568    * Deprecated: Since 2.9.4. Use #AtkObject::state-change signal instead.
569    */
570   atk_object_signals[FOCUS_EVENT] =
571     g_signal_new ("focus_event",
572                   G_TYPE_FROM_CLASS (klass),
573                   G_SIGNAL_RUN_LAST,
574                   G_STRUCT_OFFSET (AtkObjectClass, focus_event), 
575                   NULL, NULL,
576                   g_cclosure_marshal_VOID__BOOLEAN,
577                   G_TYPE_NONE,
578                   1, G_TYPE_BOOLEAN);
579   atk_object_signals[PROPERTY_CHANGE] =
580     g_signal_new ("property_change",
581                   G_TYPE_FROM_CLASS (klass),
582                   G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
583                   G_STRUCT_OFFSET (AtkObjectClass, property_change),
584                   (GSignalAccumulator) NULL, NULL,
585                   g_cclosure_marshal_VOID__POINTER,
586                   G_TYPE_NONE, 1,
587                   G_TYPE_POINTER);
588   atk_object_signals[STATE_CHANGE] =
589     g_signal_new ("state_change",
590                   G_TYPE_FROM_CLASS (klass),
591                   G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
592                   G_STRUCT_OFFSET (AtkObjectClass, state_change),
593                   (GSignalAccumulator) NULL, NULL,
594                   atk_marshal_VOID__STRING_BOOLEAN,
595                   G_TYPE_NONE, 2,
596                   G_TYPE_STRING,
597                   G_TYPE_BOOLEAN);
598   atk_object_signals[VISIBLE_DATA_CHANGED] =
599     g_signal_new ("visible_data_changed",
600                   G_TYPE_FROM_CLASS (klass),
601                   G_SIGNAL_RUN_LAST,
602                   G_STRUCT_OFFSET (AtkObjectClass, visible_data_changed),
603                   (GSignalAccumulator) NULL, NULL,
604                   g_cclosure_marshal_VOID__VOID,
605                   G_TYPE_NONE, 0);
606   atk_object_signals[ACTIVE_DESCENDANT_CHANGED] =
607     g_signal_new ("active_descendant_changed",
608                   G_TYPE_FROM_CLASS (klass),
609                   G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
610                   G_STRUCT_OFFSET (AtkObjectClass, active_descendant_changed),
611                   NULL, NULL,
612                   g_cclosure_marshal_VOID__POINTER,
613                   G_TYPE_NONE,
614                   1, G_TYPE_POINTER);
615 }
616
617 static void
618 atk_object_init  (AtkObject        *accessible,
619                   AtkObjectClass   *klass)
620 {
621   accessible->name = NULL;
622   accessible->description = NULL;
623   accessible->accessible_parent = NULL;
624   accessible->relation_set = atk_relation_set_new();
625   accessible->role = ATK_ROLE_UNKNOWN;
626 }
627
628 GType
629 atk_implementor_get_type (void)
630 {
631   static GType type = 0;
632
633   if (!type)
634     {
635       static const GTypeInfo typeInfo =
636       {
637         sizeof (AtkImplementorIface),
638         (GBaseInitFunc) NULL,
639         (GBaseFinalizeFunc) NULL,
640       } ;
641
642       type = g_type_register_static (G_TYPE_INTERFACE, "AtkImplementorIface", &typeInfo, 0) ;
643     }
644
645   return type;
646 }
647
648 /**
649  * atk_object_get_name:
650  * @accessible: an #AtkObject
651  *
652  * Gets the accessible name of the accessible.
653  *
654  * Returns: a character string representing the accessible name of the object.
655  **/
656 const gchar*
657 atk_object_get_name (AtkObject *accessible)
658 {
659   AtkObjectClass *klass;
660
661   g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
662
663   klass = ATK_OBJECT_GET_CLASS (accessible);
664   if (klass->get_name)
665     return (klass->get_name) (accessible);
666   else
667     return NULL;
668 }
669
670 /**
671  * atk_object_get_description:
672  * @accessible: an #AtkObject
673  *
674  * Gets the accessible description of the accessible.
675  *
676  * Returns: a character string representing the accessible description
677  * of the accessible.
678  *
679  **/
680 const gchar*
681 atk_object_get_description (AtkObject *accessible)
682 {
683   AtkObjectClass *klass;
684
685   g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
686
687   klass = ATK_OBJECT_GET_CLASS (accessible);
688   if (klass->get_description)
689     return (klass->get_description) (accessible);
690   else
691     return NULL;
692 }
693
694 /**
695  * atk_object_get_parent:
696  * @accessible: an #AtkObject
697  *
698  * Gets the accessible parent of the accessible.
699  *
700  * Returns: (transfer none): a #AtkObject representing the accessible parent
701  * of the accessible
702  **/
703 AtkObject*
704 atk_object_get_parent (AtkObject *accessible)
705 {
706   AtkObjectClass *klass;
707
708   g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
709
710   klass = ATK_OBJECT_GET_CLASS (accessible);
711   if (klass->get_parent)
712     return (klass->get_parent) (accessible);
713   else
714     return NULL;
715 }
716
717 /**
718  * atk_object_get_n_accessible_children:
719  * @accessible: an #AtkObject
720  *
721  * Gets the number of accessible children of the accessible.
722  *
723  * Returns: an integer representing the number of accessible children
724  * of the accessible.
725  **/
726 gint
727 atk_object_get_n_accessible_children (AtkObject *accessible)
728 {
729   AtkObjectClass *klass;
730
731   g_return_val_if_fail (ATK_IS_OBJECT (accessible), 0);
732
733   klass = ATK_OBJECT_GET_CLASS (accessible);
734   if (klass->get_n_children)
735     return (klass->get_n_children) (accessible);
736   else
737     return 0;
738 }
739
740 /**
741  * atk_object_ref_accessible_child:
742  * @accessible: an #AtkObject
743  * @i: a gint representing the position of the child, starting from 0
744  *
745  * Gets a reference to the specified accessible child of the object.
746  * The accessible children are 0-based so the first accessible child is
747  * at index 0, the second at index 1 and so on.
748  *
749  * Returns: (transfer full): an #AtkObject representing the specified
750  * accessible child of the accessible.
751  **/
752 AtkObject*
753 atk_object_ref_accessible_child (AtkObject   *accessible,
754                                  gint        i)
755 {
756   AtkObjectClass *klass;
757
758   g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
759
760   klass = ATK_OBJECT_GET_CLASS (accessible);
761   if (klass->ref_child)
762     return (klass->ref_child) (accessible, i);
763   else
764     return NULL;
765 }
766
767 /**
768  * atk_object_ref_relation_set:
769  * @accessible: an #AtkObject
770  *
771  * Gets the #AtkRelationSet associated with the object.
772  *
773  * Returns: (transfer full): an #AtkRelationSet representing the relation set
774  * of the object.
775  **/
776 AtkRelationSet*
777 atk_object_ref_relation_set (AtkObject *accessible)
778 {
779   AtkObjectClass *klass;
780
781   g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
782
783   klass = ATK_OBJECT_GET_CLASS (accessible);
784   if (klass->ref_relation_set)
785     return (klass->ref_relation_set) (accessible);
786   else
787     return NULL;
788 }
789
790 /**
791  * atk_role_register:
792  * @name: a character string describing the new role.
793  *
794  * Registers the role specified by @name.
795  *
796  * Returns: an #AtkRole for the new role.
797  **/
798 AtkRole
799 atk_role_register (const gchar *name)
800 {
801   if (!role_names)
802     initialize_role_names ();
803
804   g_ptr_array_add (role_names, g_strdup (name));
805   return role_names->len - 1;
806 }
807
808 /**
809  * atk_object_get_role:
810  * @accessible: an #AtkObject
811  *
812  * Gets the role of the accessible.
813  *
814  * Returns: an #AtkRole which is the role of the accessible
815  **/
816 AtkRole
817 atk_object_get_role (AtkObject *accessible) 
818 {
819   AtkObjectClass *klass;
820
821   g_return_val_if_fail (ATK_IS_OBJECT (accessible), ATK_ROLE_UNKNOWN);
822
823   klass = ATK_OBJECT_GET_CLASS (accessible);
824   if (klass->get_role)
825     return (klass->get_role) (accessible);
826   else
827     return ATK_ROLE_UNKNOWN;
828 }
829
830 /**
831  * atk_object_get_layer:
832  * @accessible: an #AtkObject
833  *
834  * Gets the layer of the accessible.
835  *
836  * Deprecated: Use atk_component_get_layer instead.
837  *
838  * Returns: an #AtkLayer which is the layer of the accessible
839  **/
840 AtkLayer
841 atk_object_get_layer (AtkObject *accessible) 
842 {
843   AtkObjectClass *klass;
844
845   g_return_val_if_fail (ATK_IS_OBJECT (accessible), ATK_LAYER_INVALID);
846
847   klass = ATK_OBJECT_GET_CLASS (accessible);
848   if (klass->get_layer)
849     return (klass->get_layer) (accessible);
850   else
851     return ATK_LAYER_INVALID;
852 }
853
854 /**
855  * atk_object_get_mdi_zorder:
856  * @accessible: an #AtkObject
857  *
858  * Gets the zorder of the accessible. The value G_MININT will be returned 
859  * if the layer of the accessible is not ATK_LAYER_MDI.
860  *
861  * Deprecated: Use atk_component_get_mdi_zorder instead.
862  *
863  * Returns: a gint which is the zorder of the accessible, i.e. the depth at 
864  * which the component is shown in relation to other components in the same 
865  * container.
866  *
867  **/
868 gint
869 atk_object_get_mdi_zorder (AtkObject *accessible) 
870 {
871   AtkObjectClass *klass;
872
873   g_return_val_if_fail (ATK_IS_OBJECT (accessible), G_MININT);
874
875   klass = ATK_OBJECT_GET_CLASS (accessible);
876   if (klass->get_mdi_zorder)
877     return (klass->get_mdi_zorder) (accessible);
878   else
879     return G_MININT;
880 }
881
882 /**
883  * atk_object_ref_state_set:
884  * @accessible: an #AtkObject
885  *
886  * Gets a reference to the state set of the accessible; the caller must
887  * unreference it when it is no longer needed.
888  *
889  * Returns: (transfer full): a reference to an #AtkStateSet which is the state
890  * set of the accessible
891  **/
892 AtkStateSet*
893 atk_object_ref_state_set (AtkObject *accessible) 
894 {
895   AtkObjectClass *klass;
896
897   g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
898
899   klass = ATK_OBJECT_GET_CLASS (accessible);
900   if (klass->ref_state_set)
901     return (klass->ref_state_set) (accessible);
902   else
903     return NULL;
904 }
905
906 /**
907  * atk_object_get_index_in_parent:
908  * @accessible: an #AtkObject
909  *
910  * Gets the 0-based index of this accessible in its parent; returns -1 if the
911  * accessible does not have an accessible parent.
912  *
913  * Returns: an integer which is the index of the accessible in its parent
914  **/
915 gint
916 atk_object_get_index_in_parent (AtkObject *accessible)
917 {
918   AtkObjectClass *klass;
919
920   g_return_val_if_fail (ATK_OBJECT (accessible), -1);
921
922   klass = ATK_OBJECT_GET_CLASS (accessible);
923   if (klass->get_index_in_parent)
924     return (klass->get_index_in_parent) (accessible);
925   else
926     return -1;
927 }
928
929 /**
930  * atk_object_set_name:
931  * @accessible: an #AtkObject
932  * @name: a character string to be set as the accessible name
933  *
934  * Sets the accessible name of the accessible. You can't set the name
935  * to NULL. This is reserved for the initial value. In this aspect
936  * NULL is similar to ATK_ROLE_UNKNOWN. If you want to set the name to
937  * a empty value you can use "".
938  **/
939 void
940 atk_object_set_name (AtkObject    *accessible,
941                      const gchar  *name)
942 {
943   AtkObjectClass *klass;
944   gboolean notify = FALSE;
945
946   g_return_if_fail (ATK_IS_OBJECT (accessible));
947   g_return_if_fail (name != NULL);
948
949   klass = ATK_OBJECT_GET_CLASS (accessible);
950   if (klass->set_name)
951     {
952       /* Do not notify for initial name setting. See bug 665870 */
953       notify = (accessible->name != NULL);
954
955       (klass->set_name) (accessible, name);
956       if (notify)
957         g_object_notify (G_OBJECT (accessible), atk_object_name_property_name);
958     }
959 }
960
961 /**
962  * atk_object_set_description:
963  * @accessible: an #AtkObject
964  * @description: a character string to be set as the accessible description
965  *
966  * Sets the accessible description of the accessible. You can't set
967  * the description to NULL. This is reserved for the initial value. In
968  * this aspect NULL is similar to ATK_ROLE_UNKNOWN. If you want to set
969  * the name to a empty value you can use "".
970  **/
971 void
972 atk_object_set_description (AtkObject   *accessible,
973                             const gchar *description)
974 {
975   AtkObjectClass *klass;
976   gboolean notify = FALSE;
977
978   g_return_if_fail (ATK_IS_OBJECT (accessible));
979   g_return_if_fail (description != NULL);
980
981   klass = ATK_OBJECT_GET_CLASS (accessible);
982   if (klass->set_description)
983     {
984       /* Do not notify for initial name setting. See bug 665870 */
985       notify = (accessible->description != NULL);
986
987       (klass->set_description) (accessible, description);
988       if (notify)
989         g_object_notify (G_OBJECT (accessible),
990                          atk_object_name_property_description);
991     }
992 }
993
994 /**
995  * atk_object_set_parent:
996  * @accessible: an #AtkObject
997  * @parent: an #AtkObject to be set as the accessible parent
998  *
999  * Sets the accessible parent of the accessible.
1000  **/
1001 void
1002 atk_object_set_parent (AtkObject *accessible,
1003                        AtkObject *parent)
1004 {
1005   AtkObjectClass *klass;
1006
1007   g_return_if_fail (ATK_IS_OBJECT (accessible));
1008
1009   klass = ATK_OBJECT_GET_CLASS (accessible);
1010   if (klass->set_parent)
1011     {
1012       (klass->set_parent) (accessible, parent);
1013       g_object_notify (G_OBJECT (accessible), atk_object_name_property_parent);
1014     }
1015 }
1016
1017 /**
1018  * atk_object_set_role:
1019  * @accessible: an #AtkObject
1020  * @role: an #AtkRole to be set as the role
1021  *
1022  * Sets the role of the accessible.
1023  **/
1024 void
1025 atk_object_set_role (AtkObject *accessible, 
1026                      AtkRole   role)
1027 {
1028   AtkObjectClass *klass;
1029   AtkRole old_role;
1030
1031   g_return_if_fail (ATK_IS_OBJECT (accessible));
1032
1033   klass = ATK_OBJECT_GET_CLASS (accessible);
1034   if (klass->set_role)
1035     {
1036       old_role = atk_object_get_role (accessible);
1037       if (old_role != role)
1038         {
1039           (klass->set_role) (accessible, role);
1040           if (old_role != ATK_ROLE_UNKNOWN)
1041           /* Do not notify for initial role setting */
1042             g_object_notify (G_OBJECT (accessible), atk_object_name_property_role);
1043         }
1044     }
1045 }
1046
1047 /**
1048  * atk_object_connect_property_change_handler:
1049  * @accessible: an #AtkObject
1050  * @handler: a function to be called when a property changes its value
1051  *
1052  * Specifies a function to be called when a property changes value.
1053  *
1054  * Returns: a #guint which is the handler id used in 
1055  * atk_object_remove_property_change_handler()
1056  **/
1057 guint
1058 atk_object_connect_property_change_handler (AtkObject *accessible,
1059                                             AtkPropertyChangeHandler *handler)
1060 {
1061   AtkObjectClass *klass;
1062
1063   g_return_val_if_fail (ATK_IS_OBJECT (accessible), 0);
1064   g_return_val_if_fail ((handler != NULL), 0);
1065
1066   klass = ATK_OBJECT_GET_CLASS (accessible);
1067   if (klass->connect_property_change_handler)
1068     return (klass->connect_property_change_handler) (accessible, handler);
1069   else
1070     return 0;
1071 }
1072
1073 /**
1074  * atk_object_remove_property_change_handler:
1075  * @accessible: an #AtkObject
1076  * @handler_id: a guint which identifies the handler to be removed.
1077  * 
1078  * Removes a property change handler.
1079  **/
1080 void
1081 atk_object_remove_property_change_handler  (AtkObject *accessible,
1082                                             guint      handler_id)
1083 {
1084   AtkObjectClass *klass;
1085
1086   g_return_if_fail (ATK_IS_OBJECT (accessible));
1087
1088   klass = ATK_OBJECT_GET_CLASS (accessible);
1089   if (klass->remove_property_change_handler)
1090     (klass->remove_property_change_handler) (accessible, handler_id);
1091 }
1092
1093 /**
1094  * atk_object_notify_state_change:
1095  * @accessible: an #AtkObject
1096  * @state: an #AtkState whose state is changed
1097  * @value: a gboolean which indicates whether the state is being set on or off
1098  * 
1099  * Emits a state-change signal for the specified state. 
1100  **/
1101 void
1102 atk_object_notify_state_change (AtkObject *accessible,
1103                                 AtkState  state,
1104                                 gboolean  value)
1105 {
1106   const gchar* name;
1107
1108   g_return_if_fail (ATK_IS_OBJECT (accessible));
1109
1110   name = atk_state_type_get_name (state);
1111   g_signal_emit (accessible, atk_object_signals[STATE_CHANGE],
1112                  g_quark_from_string (name),
1113                  name, value, NULL);
1114 }
1115
1116 /**
1117  * atk_implementor_ref_accessible:
1118  * @implementor: The #GObject instance which should implement #AtkImplementorIface
1119  * if a non-null return value is required.
1120  * 
1121  * Gets a reference to an object's #AtkObject implementation, if
1122  * the object implements #AtkObjectIface
1123  *
1124  * Returns: (transfer full): a reference to an object's #AtkObject
1125  * implementation
1126  */
1127 AtkObject *
1128 atk_implementor_ref_accessible (AtkImplementor *implementor)
1129 {
1130   AtkImplementorIface *iface;
1131   AtkObject           *accessible = NULL;
1132
1133   g_return_val_if_fail (ATK_IS_IMPLEMENTOR (implementor), NULL);
1134
1135   iface = ATK_IMPLEMENTOR_GET_IFACE (implementor);
1136
1137   if (iface != NULL) 
1138     accessible =  iface->ref_accessible (implementor);
1139
1140   g_return_val_if_fail ((accessible != NULL), NULL);
1141
1142   return accessible;
1143 }
1144
1145         
1146 /**
1147  * atk_object_get_attributes:
1148  * @accessible: An #AtkObject.
1149  *
1150  * Get a list of properties applied to this object as a whole, as an #AtkAttributeSet consisting of 
1151  * name-value pairs. As such these attributes may be considered weakly-typed properties or annotations, 
1152  * as distinct from strongly-typed object data available via other get/set methods.
1153  * Not all objects have explicit "name-value pair" #AtkAttributeSet properties.
1154  *
1155  * Since: 1.12
1156  *
1157  * Returns: (transfer full): an #AtkAttributeSet consisting of all
1158  * explicit properties/annotations applied to the object, or an empty
1159  * set if the object has no name-value pair attributes assigned to
1160  * it. This #atkattributeset should be freed by a call to
1161  * atk_attribute_set_free().
1162  */
1163 AtkAttributeSet *
1164 atk_object_get_attributes (AtkObject                  *accessible)
1165 {
1166   AtkObjectClass *klass;
1167
1168   g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
1169
1170   klass = ATK_OBJECT_GET_CLASS (accessible);
1171   if (klass->get_attributes)
1172     return (klass->get_attributes) (accessible); 
1173   else 
1174     return NULL;
1175         
1176 }
1177
1178 static AtkRelationSet*
1179 atk_object_real_ref_relation_set (AtkObject *accessible)
1180 {
1181   g_return_val_if_fail (accessible->relation_set, NULL);
1182   g_object_ref (accessible->relation_set); 
1183
1184   return accessible->relation_set;
1185 }
1186
1187 static void
1188 atk_object_real_set_property (GObject      *object,
1189                               guint         prop_id,
1190                               const GValue *value,
1191                               GParamSpec   *pspec)
1192 {
1193   AtkObject *accessible;
1194
1195   accessible = ATK_OBJECT (object);
1196
1197   switch (prop_id)
1198     {
1199     case PROP_NAME:
1200       atk_object_set_name (accessible, g_value_get_string (value));
1201       break;
1202     case PROP_DESCRIPTION:
1203       atk_object_set_description (accessible, g_value_get_string (value));
1204       break;
1205     case PROP_ROLE:
1206       atk_object_set_role (accessible, g_value_get_int (value));
1207       break;
1208     case PROP_PARENT:
1209       atk_object_set_parent (accessible, g_value_get_object (value));
1210       break;
1211     case PROP_VALUE:
1212       if (ATK_IS_VALUE (accessible))
1213         atk_value_set_current_value (ATK_VALUE (accessible), value);
1214       break;
1215     case PROP_TABLE_SUMMARY:
1216       if (ATK_IS_TABLE (accessible))
1217         atk_table_set_summary (ATK_TABLE (accessible), g_value_get_object (value));
1218       break;
1219     case PROP_TABLE_CAPTION_OBJECT:
1220       if (ATK_IS_TABLE (accessible))
1221         atk_table_set_caption (ATK_TABLE (accessible), g_value_get_object (value));
1222       break;
1223     default:
1224       break;
1225     }
1226 }
1227
1228 static void
1229 atk_object_real_get_property (GObject      *object,
1230                               guint         prop_id,
1231                               GValue       *value,
1232                               GParamSpec   *pspec)
1233 {
1234   AtkObject *accessible;
1235
1236   accessible = ATK_OBJECT (object);
1237
1238   switch (prop_id)
1239     {
1240     case PROP_NAME:
1241       g_value_set_string (value, atk_object_get_name (accessible));
1242       break;
1243     case PROP_DESCRIPTION:
1244       g_value_set_string (value, atk_object_get_description (accessible));
1245       break;
1246     case PROP_ROLE:
1247       g_value_set_int (value, atk_object_get_role (accessible));
1248       break;
1249     case PROP_LAYER:
1250       if (ATK_IS_COMPONENT (accessible))
1251         g_value_set_int (value, atk_component_get_layer (ATK_COMPONENT (accessible)));
1252       break;
1253     case PROP_MDI_ZORDER:
1254       if (ATK_IS_COMPONENT (accessible))
1255         g_value_set_int (value, atk_component_get_mdi_zorder (ATK_COMPONENT (accessible)));
1256       break;
1257     case PROP_PARENT:
1258       g_value_set_object (value, atk_object_get_parent (accessible));
1259       break;
1260     case PROP_VALUE:
1261       if (ATK_IS_VALUE (accessible))
1262         atk_value_get_current_value (ATK_VALUE (accessible), value);
1263       break;
1264     case PROP_TABLE_SUMMARY:
1265       if (ATK_IS_TABLE (accessible))
1266         g_value_set_object (value, atk_table_get_summary (ATK_TABLE (accessible)));
1267       break;
1268     case PROP_TABLE_CAPTION_OBJECT:
1269       if (ATK_IS_TABLE (accessible))
1270         g_value_set_object (value, atk_table_get_caption (ATK_TABLE (accessible)));
1271       break;
1272     case PROP_HYPERTEXT_NUM_LINKS:
1273       if (ATK_IS_HYPERTEXT (accessible))
1274         g_value_set_int (value, atk_hypertext_get_n_links (ATK_HYPERTEXT (accessible)));
1275       break;
1276     default:
1277       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1278       break;
1279     }
1280 }
1281
1282 static void
1283 atk_object_finalize (GObject *object)
1284 {
1285   AtkObject        *accessible;
1286
1287   g_return_if_fail (ATK_IS_OBJECT (object));
1288
1289   accessible = ATK_OBJECT (object);
1290
1291   g_free (accessible->name);
1292   g_free (accessible->description);
1293
1294   /*
1295    * Free memory allocated for relation set if it have been allocated.
1296    */
1297   if (accessible->relation_set)
1298     g_object_unref (accessible->relation_set);
1299
1300   if (accessible->accessible_parent)
1301     g_object_unref (accessible->accessible_parent);
1302
1303   G_OBJECT_CLASS (parent_class)->finalize (object);
1304 }
1305
1306 static const gchar*
1307 atk_object_real_get_name (AtkObject *object)
1308 {
1309   return object->name;
1310 }
1311
1312 static const gchar*
1313 atk_object_real_get_description (AtkObject *object)
1314 {
1315   return object->description;
1316 }
1317
1318 static AtkObject*
1319 atk_object_real_get_parent (AtkObject       *object)
1320 {
1321   return object->accessible_parent;
1322 }
1323
1324 static AtkRole
1325 atk_object_real_get_role (AtkObject       *object)
1326 {
1327   return object->role;
1328 }
1329
1330 static AtkLayer
1331 atk_object_real_get_layer (AtkObject       *object)
1332 {
1333   return object->layer;
1334 }
1335
1336 static AtkStateSet*
1337 atk_object_real_ref_state_set (AtkObject *accessible) 
1338 {
1339   AtkStateSet *state_set;
1340   AtkObject *focus_object;
1341
1342   state_set = atk_state_set_new ();
1343
1344   focus_object = atk_get_focus_object ();
1345   if (focus_object == accessible)
1346     atk_state_set_add_state (state_set, ATK_STATE_FOCUSED);
1347
1348   return state_set; 
1349 }
1350
1351 static void
1352 atk_object_real_set_name (AtkObject       *object,
1353                           const gchar     *name)
1354 {
1355   g_free (object->name);
1356   object->name = g_strdup (name);
1357 }
1358
1359 static void
1360 atk_object_real_set_description (AtkObject       *object,
1361                                  const gchar     *description)
1362 {
1363   g_free (object->description);
1364   object->description = g_strdup (description);
1365 }
1366
1367 static void
1368 atk_object_real_set_parent (AtkObject       *object,
1369                             AtkObject       *parent)
1370 {
1371   if (object->accessible_parent)
1372     g_object_unref (object->accessible_parent);
1373
1374   object->accessible_parent = parent;
1375   if (object->accessible_parent)
1376     g_object_ref (object->accessible_parent);
1377 }
1378
1379 static void
1380 atk_object_real_set_role (AtkObject *object,
1381                           AtkRole   role)
1382 {
1383   object->role = role;
1384 }
1385
1386 static guint
1387 atk_object_real_connect_property_change_handler (AtkObject                *obj,
1388                                                  AtkPropertyChangeHandler *handler)
1389 {
1390   return g_signal_connect_closure_by_id (obj,
1391                                          atk_object_signals[PROPERTY_CHANGE],
1392                                          0,
1393                                          g_cclosure_new (
1394                                          G_CALLBACK (handler), NULL,
1395                                          (GClosureNotify) NULL),
1396                                          FALSE);
1397 }
1398
1399 static void
1400 atk_object_real_remove_property_change_handler (AtkObject           *obj,
1401                                           guint               handler_id)
1402 {
1403   g_signal_handler_disconnect (obj, handler_id);
1404 }
1405
1406 /**
1407  * atk_object_initialize:
1408  * @accessible: a #AtkObject
1409  * @data: a #gpointer which identifies the object for which the AtkObject was created.
1410  *
1411  * This function is called when implementing subclasses of #AtkObject.
1412  * It does initialization required for the new object. It is intended
1413  * that this function should called only in the ..._new() functions used
1414  * to create an instance of a subclass of #AtkObject
1415  **/
1416 void
1417 atk_object_initialize (AtkObject  *accessible,
1418                        gpointer   data)
1419 {
1420   AtkObjectClass *klass;
1421
1422   g_return_if_fail (ATK_IS_OBJECT (accessible));
1423
1424   klass = ATK_OBJECT_GET_CLASS (accessible);
1425   if (klass->initialize)
1426     klass->initialize (accessible, data);
1427 }
1428
1429 /*
1430  * This function is a signal handler for notify signal which gets emitted
1431  * when a property changes value.
1432  *
1433  * It constructs an AtkPropertyValues structure and emits a "property_changed"
1434  * signal which causes the user specified AtkPropertyChangeHandler
1435  * to be called.
1436  */
1437 static void
1438 atk_object_notify (GObject     *obj,
1439                    GParamSpec  *pspec)
1440 {
1441   AtkPropertyValues values = { NULL, };
1442
1443   g_value_init (&values.new_value, pspec->value_type);
1444   g_object_get_property (obj, pspec->name, &values.new_value);
1445   values.property_name = pspec->name;
1446   g_signal_emit (obj, atk_object_signals[PROPERTY_CHANGE],
1447                  g_quark_from_string (pspec->name),
1448                  &values, NULL);
1449   g_value_unset (&values.new_value);
1450 }
1451
1452 /**
1453  * atk_role_get_name:
1454  * @role: The #AtkRole whose name is required
1455  *
1456  * Gets the description string describing the #AtkRole @role.
1457  *
1458  * Returns: the string describing the AtkRole
1459  */
1460 const gchar*
1461 atk_role_get_name (AtkRole role)
1462 {
1463   g_return_val_if_fail (role >= 0, NULL);
1464
1465   if (!role_names)
1466     initialize_role_names ();
1467
1468   if (role < role_names->len)
1469     return g_ptr_array_index (role_names, role);
1470
1471   return NULL;
1472 }
1473
1474 /**
1475  * atk_role_get_localized_name:
1476  * @role: The #AtkRole whose localized name is required
1477  *
1478  * Gets the localized description string describing the #AtkRole @role.
1479  *
1480  * Returns: the localized string describing the AtkRole
1481  **/
1482 const gchar*
1483 atk_role_get_localized_name (AtkRole role)
1484 {
1485   gettext_initialization ();
1486
1487   return dgettext (GETTEXT_PACKAGE, atk_role_get_name (role));
1488 }
1489
1490 static const gchar*
1491 atk_object_real_get_object_locale (AtkObject *object)
1492 {
1493   return setlocale (LC_MESSAGES, NULL);
1494 }
1495
1496 /**
1497  * atk_object_get_object_locale:
1498  * @accessible: an #AtkObject
1499  *
1500  * Gets a UTF-8 string indicating the POSIX-style LC_MESSAGES locale
1501  * of @accessible.
1502  *
1503  * Since: 2.7.90
1504  *
1505  * Returns: a UTF-8 string indicating the POSIX-style LC_MESSAGES
1506  *          locale of @accessible.
1507  **/
1508 const gchar*
1509 atk_object_get_object_locale (AtkObject *accessible)
1510 {
1511   AtkObjectClass *klass;
1512
1513   g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
1514
1515   klass = ATK_OBJECT_GET_CLASS (accessible);
1516   if (klass->get_object_locale)
1517     return (klass->get_object_locale) (accessible);
1518   else
1519     return NULL;
1520 }
1521
1522
1523 /**
1524  * atk_role_for_name:
1525  * @name: a string which is the (non-localized) name of an ATK role.
1526  *
1527  * Get the #AtkRole type corresponding to a rolew name.
1528  *
1529  * Returns: the #AtkRole enumerated type corresponding to the specified name,
1530  *          or #ATK_ROLE_INVALID if no matching role is found.
1531  **/
1532 AtkRole
1533 atk_role_for_name (const gchar *name)
1534 {
1535   AtkRole role = ATK_ROLE_INVALID;
1536   gint i;
1537
1538   g_return_val_if_fail (name, ATK_ROLE_INVALID);
1539
1540   if (!role_names)
1541     initialize_role_names ();
1542
1543   for (i = 0; i < role_names->len; i++)
1544     {
1545       gchar *role_name = (gchar *)g_ptr_array_index (role_names, i);
1546
1547       g_return_val_if_fail (role_name, ATK_ROLE_INVALID);
1548
1549       if (strcmp (name, role_name) == 0)
1550         {
1551           role = i;
1552           break;
1553         }
1554     }
1555
1556   return role;
1557 }
1558
1559 /**
1560  * atk_object_add_relationship:
1561  * @object: The #AtkObject to which an AtkRelation is to be added. 
1562  * @relationship: The #AtkRelationType of the relation
1563  * @target: The #AtkObject which is to be the target of the relation.
1564  *
1565  * Adds a relationship of the specified type with the specified target.
1566  *
1567  * Returns TRUE if the relationship is added.
1568  **/
1569 gboolean
1570 atk_object_add_relationship (AtkObject       *object,
1571                              AtkRelationType relationship,
1572                              AtkObject       *target)
1573 {
1574   AtkObject *array[1];
1575   AtkRelation *relation;
1576
1577   g_return_val_if_fail (ATK_IS_OBJECT (object), FALSE);
1578   g_return_val_if_fail (ATK_IS_OBJECT (target), FALSE);
1579
1580   if (atk_relation_set_contains_target (object->relation_set,
1581                                         relationship, target))
1582     return FALSE;
1583
1584   array[0] = target;
1585   relation = atk_relation_new (array, 1, relationship);
1586   atk_relation_set_add (object->relation_set, relation);
1587   g_object_unref (relation);
1588
1589   return TRUE;
1590 }
1591
1592 /**
1593  * atk_object_remove_relationship:
1594  * @object: The #AtkObject from which an AtkRelation is to be removed. 
1595  * @relationship: The #AtkRelationType of the relation
1596  * @target: The #AtkObject which is the target of the relation to be removed.
1597  *
1598  * Removes a relationship of the specified type with the specified target.
1599  *
1600  * Returns TRUE if the relationship is removed.
1601  **/
1602 gboolean
1603 atk_object_remove_relationship (AtkObject       *object,
1604                                 AtkRelationType relationship,
1605                                 AtkObject       *target)
1606 {
1607   gboolean ret = FALSE;
1608   AtkRelation *relation;
1609   GPtrArray *array;
1610
1611   g_return_val_if_fail (ATK_IS_OBJECT (object), FALSE);
1612   g_return_val_if_fail (ATK_IS_OBJECT (target), FALSE);
1613
1614   relation = atk_relation_set_get_relation_by_type (object->relation_set, relationship);
1615
1616   if (relation)
1617     {
1618       ret = atk_relation_remove_target (relation, target);
1619       array = atk_relation_get_target (relation);
1620       if (!array || array->len == 0)
1621         atk_relation_set_remove (object->relation_set, relation);
1622     }
1623   return ret;
1624 }
1625
1626 static void
1627 atk_object_real_initialize (AtkObject *accessible,
1628                             gpointer  data)
1629 {
1630   return;
1631 }