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