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