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