Fixed bug in atkutil when no impl library (e.g. libgail) is loaded.
[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 #include "atk.h"
25 #include "atkmarshal.h"
26
27 static gchar *role_names[ATK_ROLE_LAST_DEFINED] = {
28   "invalid",
29   "accel_label",
30   "alert",
31   "animation",
32   "arrow",
33   "calendar",
34   "canvas",
35   "check_box",
36   "check_menu_item",
37   "color_chooser",
38   "column_header",
39   "combo_box",
40   "date_editor",
41   "desktop_icon",
42   "desktop_frame",
43   "dial",
44   "dialog",
45   "directory_pane",
46   "drawing_area",
47   "file_chooser",
48   "filler",
49   "font_chooser",
50   "frame",
51   "glass_pane",
52   "html_container",
53   "icon",
54   "image",
55   "internal_frame",
56   "label",
57   "layered_pane",
58   "list",
59   "list_item",
60   "menu",
61   "menu_bar",
62   "menu_item",
63   "option_pane",
64   "page_tab",
65   "page_tab_list",
66   "panel",
67   "password_text",
68   "popup_menu",
69   "progress_bar",
70   "push_button",
71   "radio_button",
72   "radio_menu_item",
73   "root_pane",
74   "row_header",
75   "scroll_bar",
76   "scroll_pane",
77   "separator",
78   "slider",
79   "split_pane",
80   "spin_button",
81   "statusbar",
82   "table",
83   "table_cell",
84   "table_column_header",
85   "table_row_header",
86   "tear_off_menu_item",
87   "terminal",
88   "text",
89   "toggle_button",
90   "tool_bar",
91   "tool_tip",
92   "tree",
93   "tree_table",
94   "unknown",
95   "viewport",
96   "window"
97 };
98
99 enum
100 {
101   PROP_0,  /* gobject convention */
102
103   PROP_NAME,
104   PROP_DESCRIPTION,
105   PROP_PARENT,      /* ancestry has changed */
106   PROP_VALUE,
107   PROP_ROLE,
108   PROP_LAYER,
109   PROP_MDI_ZORDER,
110   PROP_TABLE_CAPTION,
111   PROP_TABLE_COLUMN_DESCRIPTION,
112   PROP_TABLE_COLUMN_HEADER,
113   PROP_TABLE_ROW_DESCRIPTION,
114   PROP_TABLE_ROW_HEADER,
115   PROP_TABLE_SUMMARY,
116   PROP_LAST         /* gobject convention */
117 };
118
119 enum {
120   CHILDREN_CHANGED,
121   FOCUS_EVENT,
122   PROPERTY_CHANGE,
123   STATE_CHANGE,
124   VISIBLE_DATA_CHANGED,
125   
126   LAST_SIGNAL
127 };
128
129 static void            atk_object_class_init        (AtkObjectClass  *klass);
130 static void            atk_object_init              (AtkObject       *accessible,
131                                                      AtkObjectClass  *klass);
132 static AtkRelationSet* atk_object_real_ref_relation_set 
133                                                     (AtkObject       *accessible);
134
135 static void            atk_object_real_set_property (GObject         *object,
136                                                      guint            prop_id,
137                                                      const GValue    *value,
138                                                      GParamSpec      *pspec);
139 static void            atk_object_real_get_property (GObject         *object,
140                                                      guint            prop_id,
141                                                      GValue          *value,
142                                                      GParamSpec      *pspec);
143 static void            atk_object_finalize          (GObject         *object);
144 static G_CONST_RETURN gchar*
145                        atk_object_real_get_name     (AtkObject       *object);
146 static G_CONST_RETURN gchar*
147                        atk_object_real_get_description    
148                                                    (AtkObject       *object);
149 static AtkObject*      atk_object_real_get_parent  (AtkObject       *object);
150 static AtkRole         atk_object_real_get_role    (AtkObject       *object);
151 static AtkLayer        atk_object_real_get_layer   (AtkObject       *object);
152 static AtkStateSet*    atk_object_real_ref_state_set
153                                                    (AtkObject       *object);
154 static void            atk_object_real_set_name    (AtkObject       *object,
155                                                     const gchar     *name);
156 static void            atk_object_real_set_description
157                                                    (AtkObject       *object,
158                                                     const gchar     *description);
159 static void            atk_object_real_set_parent  (AtkObject       *object,
160                                                     AtkObject       *parent);
161 static void            atk_object_real_set_role    (AtkObject       *object,
162                                                     AtkRole         role);
163 static guint           atk_object_real_connect_property_change_handler
164                                                    (AtkObject       *obj,
165                                                     AtkPropertyChangeHandler
166                                                                     *handler);
167 static void            atk_object_real_remove_property_change_handler
168                                                    (AtkObject       *obj,
169                                                     guint           handler_id);
170 static void            atk_object_notify           (GObject         *obj,
171                                                     GParamSpec      *pspec);
172
173
174 static guint atk_object_signals[LAST_SIGNAL] = { 0, };
175
176 static gpointer parent_class = NULL;
177
178 static const gchar* atk_object_name_property_name = "accessible-name";
179 static const gchar* atk_object_name_property_description = "accessible-description";
180 static const gchar* atk_object_name_property_parent = "accessible-parent";
181 static const gchar* atk_object_name_property_value = "accessible-value";
182 static const gchar* atk_object_name_property_role = "accessible-role";
183 static const gchar* atk_object_name_property_component_layer = "accessible-component-layer";
184 static const gchar* atk_object_name_property_component_mdi_zorder = "accessible-component-mdi-zorder";
185 static const gchar* atk_object_name_property_table_caption = "accessible-table-caption";
186 static const gchar* atk_object_name_property_table_column_description = "accessible-table-column-description";
187 static const gchar* atk_object_name_property_table_column_header = "accessible-table-column-header";
188 static const gchar* atk_object_name_property_table_row_description = "accessible-table-row-description";
189 static const gchar* atk_object_name_property_table_row_header = "accessible-table-row-header";
190 static const gchar* atk_object_name_property_table_summary = "accessible-table-summary";
191
192 GType
193 atk_object_get_type (void)
194 {
195   static GType type = 0;
196
197   if (!type)
198     {
199       static const GTypeInfo typeInfo =
200       {
201         sizeof (AtkObjectClass),
202         (GBaseInitFunc) NULL,
203         (GBaseFinalizeFunc) NULL,
204         (GClassInitFunc) atk_object_class_init,
205         (GClassFinalizeFunc) NULL,
206         NULL,
207         sizeof (AtkObject),
208         0,
209         (GInstanceInitFunc) atk_object_init,
210       } ;
211       type = g_type_register_static (G_TYPE_OBJECT, "AtkObject", &typeInfo, 0) ;
212     }
213   return type;
214 }
215
216 static void
217 atk_object_class_init (AtkObjectClass *klass)
218 {
219   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
220
221   parent_class = g_type_class_ref (G_TYPE_OBJECT);
222
223   gobject_class->set_property = atk_object_real_set_property;
224   gobject_class->get_property = atk_object_real_get_property;
225   gobject_class->finalize = atk_object_finalize;
226   gobject_class->notify = atk_object_notify;
227
228   klass->get_name = atk_object_real_get_name;
229   klass->get_description = atk_object_real_get_description;
230   klass->get_parent = atk_object_real_get_parent;
231   klass->get_n_children = NULL;
232   klass->ref_child = NULL;
233   klass->get_index_in_parent = NULL;
234   klass->ref_relation_set = atk_object_real_ref_relation_set;
235   klass->get_role = atk_object_real_get_role;
236   klass->get_layer = atk_object_real_get_layer;
237   klass->get_mdi_zorder = NULL;
238   klass->ref_state_set = atk_object_real_ref_state_set;
239   klass->set_name = atk_object_real_set_name;
240   klass->set_description = atk_object_real_set_description;
241   klass->set_parent = atk_object_real_set_parent;
242   klass->set_role = atk_object_real_set_role;
243   klass->connect_property_change_handler = 
244          atk_object_real_connect_property_change_handler;
245   klass->remove_property_change_handler = 
246          atk_object_real_remove_property_change_handler;
247
248   /*
249    * We do not define default signal handlers here
250    */
251   klass->children_changed = NULL;
252   klass->focus_event = NULL;
253   klass->property_change = NULL;
254   klass->visible_data_changed = NULL;
255
256   g_object_class_install_property (gobject_class,
257                                    PROP_NAME,
258                                    g_param_spec_string (atk_object_name_property_name,
259                                                         "Accessible Name",
260                                                         "Object instance\'s name formatted for "
261                                                            "assistive technology access",
262                                                         NULL,
263                                                         G_PARAM_READWRITE));
264   g_object_class_install_property (gobject_class,
265                                    PROP_DESCRIPTION,
266                                    g_param_spec_string (atk_object_name_property_description,
267                                                         "Accessible Description",
268                                                         "Description of an object, formatted for "
269                                                         "assistive technology access",
270                                                         NULL,
271                                                         G_PARAM_READWRITE));
272   g_object_class_install_property (gobject_class,
273                                    PROP_PARENT,
274                                    g_param_spec_object (atk_object_name_property_parent,
275                                                         "Accessible Parent",
276                                                         "Is used to notify that the parent has changed ",
277                                                         ATK_TYPE_OBJECT,
278                                                         G_PARAM_READWRITE));
279   g_object_class_install_property (gobject_class,
280                                    PROP_VALUE,
281                                    g_param_spec_double (atk_object_name_property_value,
282                                                         "Accessible Value",
283                                                         "Is used to notify that the value has changed ",
284                                                         0.0,
285                                                         G_MAXDOUBLE,
286                                                         0.0,
287                                                         G_PARAM_READWRITE));
288   g_object_class_install_property (gobject_class,
289                                    PROP_ROLE,
290                                    g_param_spec_int    (atk_object_name_property_role,
291                                                         "Accessible Role",
292                                                         "The accessible role of this object ",
293                                                         0,
294                                                         G_MAXINT,
295                                                         0,
296                                                         G_PARAM_READWRITE));
297   g_object_class_install_property (gobject_class,
298                                    PROP_LAYER,
299                                    g_param_spec_int    (atk_object_name_property_component_layer,
300                                                         "Accessible Layer",
301                                                         "The accessible layer of this object ",
302                                                         0,
303                                                         G_MAXINT,
304                                                         0,
305                                                         G_PARAM_READABLE));
306   g_object_class_install_property (gobject_class,
307                                    PROP_MDI_ZORDER,
308                                    g_param_spec_int    (atk_object_name_property_component_mdi_zorder,
309                                                         "Accessible MDI Value",
310                                                         "The accessible MDI value of this object ",
311                                                         G_MININT,
312                                                         G_MAXINT,
313                                                         G_MININT,
314                                                         G_PARAM_READABLE));
315   g_object_class_install_property (gobject_class,
316                                    PROP_TABLE_CAPTION,
317                                    g_param_spec_string (atk_object_name_property_table_caption,
318                                                         "Accessible Table Caption",
319                                                         "Is used to notify that the table caption has changed ",
320                                                         NULL,
321                                                         G_PARAM_READWRITE));
322   g_object_class_install_property (gobject_class,
323                                    PROP_TABLE_COLUMN_HEADER,
324                                    g_param_spec_object (atk_object_name_property_table_column_header,
325                                                         "Accessible Table Column Header",
326                                                         "Is used to notify that the table column header has changed ",
327                                                         ATK_TYPE_OBJECT,
328                                                         G_PARAM_READWRITE));
329   g_object_class_install_property (gobject_class,
330                                    PROP_TABLE_COLUMN_DESCRIPTION,
331                                    g_param_spec_string (atk_object_name_property_table_column_description,
332                                                         "Accessible Table Column Description",
333                                                         "Is used to notify that the table columnscription has changed ",
334                                                         NULL,
335                                                         G_PARAM_READWRITE));
336   g_object_class_install_property (gobject_class,
337                                    PROP_TABLE_ROW_HEADER,
338                                    g_param_spec_object (atk_object_name_property_table_row_header,
339                                                         "Accessible Table Row Header",
340                                                         "Is used to notify that the table row header has changed ",
341                                                         ATK_TYPE_OBJECT,
342                                                         G_PARAM_READWRITE));
343   g_object_class_install_property (gobject_class,
344                                    PROP_TABLE_ROW_DESCRIPTION,
345                                    g_param_spec_string (atk_object_name_property_table_row_description,
346                                                         "Accessible Table Row Description",
347                                                         "Is used to notify that the table row description has changed ",
348                                                         NULL,
349                                                         G_PARAM_READWRITE));
350   g_object_class_install_property (gobject_class,
351                                    PROP_TABLE_SUMMARY,
352                                    g_param_spec_object (atk_object_name_property_table_summary,
353                                                         "Accessible Table Summary",
354                                                         "Is used to notify that the table summary has changed ",
355                                                         ATK_TYPE_OBJECT,
356                                                         G_PARAM_READWRITE));
357   /*
358    * The signal "children_changed" supports two details:
359    * "add" and "remove"
360    */
361   atk_object_signals[CHILDREN_CHANGED] =
362     g_signal_new ("children_changed",
363                   G_TYPE_FROM_CLASS (klass),
364                   G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
365                   G_STRUCT_OFFSET (AtkObjectClass, children_changed),
366                   NULL, NULL,
367                   g_cclosure_marshal_VOID__UINT_POINTER,
368                   G_TYPE_NONE,
369                   2, G_TYPE_UINT, G_TYPE_POINTER);
370   atk_object_signals[FOCUS_EVENT] =
371     g_signal_new ("focus_event",
372                   G_TYPE_FROM_CLASS (klass),
373                   G_SIGNAL_RUN_LAST,
374                   G_STRUCT_OFFSET (AtkObjectClass, focus_event), 
375                   NULL, NULL,
376                   g_cclosure_marshal_VOID__BOOLEAN,
377                   G_TYPE_NONE,
378                   1, G_TYPE_BOOLEAN);
379   atk_object_signals[PROPERTY_CHANGE] =
380     g_signal_new ("property_change",
381                   G_TYPE_FROM_CLASS (klass),
382                   G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
383                   G_STRUCT_OFFSET (AtkObjectClass, property_change),
384                   (GSignalAccumulator) NULL, NULL,
385                   g_cclosure_marshal_VOID__POINTER,
386                   G_TYPE_NONE, 1,
387                   G_TYPE_POINTER);
388   /*
389    * The "state_change" signal supports details, one for each accessible 
390    * state type
391    * (see atkstate.c).
392    */
393   atk_object_signals[STATE_CHANGE] =
394     g_signal_new ("state_change",
395                   G_TYPE_FROM_CLASS (klass),
396                   G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
397                   G_STRUCT_OFFSET (AtkObjectClass, state_change),
398                   (GSignalAccumulator) NULL, NULL,
399                   atk_marshal_VOID__STRING_BOOLEAN,
400                   G_TYPE_NONE, 2,
401                   G_TYPE_STRING,
402                   G_TYPE_BOOLEAN);
403   atk_object_signals[VISIBLE_DATA_CHANGED] =
404     g_signal_new ("visible_data_changed",
405                   G_TYPE_FROM_CLASS (klass),
406                   G_SIGNAL_RUN_LAST,
407                   G_STRUCT_OFFSET (AtkObjectClass, visible_data_changed),
408                   (GSignalAccumulator) NULL, NULL,
409                   g_cclosure_marshal_VOID__VOID,
410                   G_TYPE_NONE, 0);
411 }
412
413 static void
414 atk_object_init  (AtkObject        *accessible,
415                   AtkObjectClass   *klass)
416 {
417   accessible->name = NULL;
418   accessible->description = NULL;
419   accessible->accessible_parent = NULL;
420   accessible->relation_set = atk_relation_set_new();
421   accessible->role = ATK_ROLE_UNKNOWN;
422 }
423
424 GType
425 atk_implementor_get_type (void)
426 {
427   static GType type = 0;
428
429   if (!type)
430     {
431       static const GTypeInfo typeInfo =
432       {
433         sizeof (AtkImplementorIface),
434         (GBaseInitFunc) NULL,
435         (GBaseFinalizeFunc) NULL,
436       } ;
437
438       type = g_type_register_static (G_TYPE_INTERFACE, "AtkImplementorIface", &typeInfo, 0) ;
439     }
440
441   return type;
442 }
443
444 /**
445  * atk_object_get_name:
446  * @accessible: an #AtkObject
447  *
448  * Gets the accessible name of the accessible.
449  *
450  * Returns: a character string representing the accessible name of the object.
451  **/
452 G_CONST_RETURN gchar*
453 atk_object_get_name (AtkObject *accessible)
454 {
455   AtkObjectClass *klass;
456
457   g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
458
459   klass = ATK_OBJECT_GET_CLASS (accessible);
460   if (klass->get_name)
461     return (klass->get_name) (accessible);
462   else
463     return NULL;
464 }
465
466 /**
467  * atk_object_get_description:
468  * @accessible: an #AtkObject
469  *
470  * Gets the accessible description of the accessible.
471  *
472  * Returns: a character string representing the accessible description
473  * of the accessible.
474  *
475  **/
476 G_CONST_RETURN gchar*
477 atk_object_get_description (AtkObject *accessible)
478 {
479   AtkObjectClass *klass;
480
481   g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
482
483   klass = ATK_OBJECT_GET_CLASS (accessible);
484   if (klass->get_description)
485     return (klass->get_description) (accessible);
486   else
487     return NULL;
488 }
489
490 /**
491  * atk_object_get_parent:
492  * @accessible: an #AtkObject
493  *
494  * Gets the accessible parent of the accessible.
495  *
496  * Returns: a #AtkObject representing the accessible parent of the accessible
497  **/
498 AtkObject*
499 atk_object_get_parent (AtkObject *accessible)
500 {
501   AtkObjectClass *klass;
502
503   g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
504
505   klass = ATK_OBJECT_GET_CLASS (accessible);
506   if (klass->get_parent)
507     return (klass->get_parent) (accessible);
508   else
509     return NULL;
510 }
511
512 /**
513  * atk_object_get_n_accessible_children:
514  * @accessible: an #AtkObject
515  *
516  * Gets the number of accessible children of the accessible.
517  *
518  * Returns: an integer representing the number of accessible children
519  * of the accessible.
520  **/
521 gint
522 atk_object_get_n_accessible_children (AtkObject *accessible)
523 {
524   AtkObjectClass *klass;
525
526   g_return_val_if_fail (ATK_IS_OBJECT (accessible), 0);
527
528   klass = ATK_OBJECT_GET_CLASS (accessible);
529   if (klass->get_n_children)
530     return (klass->get_n_children) (accessible);
531   else
532     return 0;
533 }
534
535 /**
536  * atk_object_ref_accessible_child:
537  * @accessible: an #AtkObject
538  * @i: a gint representing the position of the child, starting from 0
539  *
540  * Gets a reference to the specified accessible child of the object.
541  * The accessible children are 0-based so the first accessible child is
542  * at index 0, the second at index 1 and so on.
543  *
544  * Returns: an #AtkObject representing the specified accessible child
545  * of the accessible.
546  **/
547 AtkObject*
548 atk_object_ref_accessible_child (AtkObject   *accessible,
549                                  gint        i)
550 {
551   AtkObjectClass *klass;
552
553   g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
554
555   klass = ATK_OBJECT_GET_CLASS (accessible);
556   if (klass->ref_child)
557     return (klass->ref_child) (accessible, i);
558   else
559     return NULL;
560 }
561
562 /**
563  * atk_object_ref_relation_set:
564  * @accessible: an #AtkObject
565  *
566  * Gets the #AtkRelationSet associated with the object.
567  *
568  * Returns: an #AtkRelationSet representing the relation set of the object.
569  **/
570 AtkRelationSet*
571 atk_object_ref_relation_set (AtkObject *accessible)
572 {
573   AtkObjectClass *klass;
574
575   g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
576
577   klass = ATK_OBJECT_GET_CLASS (accessible);
578   if (klass->ref_relation_set)
579     return (klass->ref_relation_set) (accessible);
580   else
581     return NULL;
582 }
583
584 /**
585  * atk_role_register:
586  * @name: a character string describing the new role.
587  *
588  * Registers the role specified by @name.
589  *
590  * Returns: an #AtkRole for the new role.
591  **/
592 AtkRole
593 atk_role_register (const gchar *name)
594 {
595   /* TODO: associate name with new type */
596   static guint type = ATK_ROLE_LAST_DEFINED;
597   return (++type);
598 }
599
600 /**
601  * atk_object_get_role:
602  * @accessible: an #AtkObject
603  *
604  * Gets the role of the accessible.
605  *
606  * Returns: an #AtkRole which is the role of the accessible
607  **/
608 AtkRole
609 atk_object_get_role (AtkObject *accessible) 
610 {
611   AtkObjectClass *klass;
612
613   g_return_val_if_fail (ATK_IS_OBJECT (accessible), ATK_ROLE_UNKNOWN);
614
615   klass = ATK_OBJECT_GET_CLASS (accessible);
616   if (klass->get_role)
617     return (klass->get_role) (accessible);
618   else
619     return ATK_ROLE_UNKNOWN;
620 }
621
622 /**
623  * atk_object_get_layer:
624  * @accessible: an #AtkObject
625  *
626  * Gets the layer of the accessible.
627  *
628  * Returns: an #AtkLayer which is the layer of the accessible
629  **/
630 AtkLayer
631 atk_object_get_layer (AtkObject *accessible) 
632 {
633   AtkObjectClass *klass;
634
635   g_return_val_if_fail (ATK_IS_OBJECT (accessible), ATK_LAYER_INVALID);
636
637   klass = ATK_OBJECT_GET_CLASS (accessible);
638   if (klass->get_layer)
639     return (klass->get_layer) (accessible);
640   else
641     return ATK_LAYER_INVALID;
642 }
643
644 /**
645  * atk_object_get_mdi_zorder:
646  * @accessible: an #AtkObject
647  *
648  * Gets the zorder of the accessible. The value G_MININT will be returned 
649  * if the layer of the accessible is not ATK_LAYER_MDI.
650  *
651  * Returns: a gint which is the zorder of the accessible, i.e. the depth at 
652  * which the component is shown in relation to other components in the same 
653  * container.
654  **/
655 gint
656 atk_object_get_mdi_zorder (AtkObject *accessible) 
657 {
658   AtkObjectClass *klass;
659
660   g_return_val_if_fail (ATK_IS_OBJECT (accessible), G_MININT);
661
662   klass = ATK_OBJECT_GET_CLASS (accessible);
663   if (klass->get_mdi_zorder)
664     return (klass->get_mdi_zorder) (accessible);
665   else
666     return G_MININT;
667 }
668
669 /**
670  * atk_object_ref_state_set:
671  * @accessible: an #AtkObject
672  *
673  * Gets a reference to the state set of the accessible; the caller must
674  * unreference it when it is no longer needed.
675  *
676  * Returns: a reference to an #AtkStateSet which is the state
677  * set of the accessible
678  **/
679 AtkStateSet*
680 atk_object_ref_state_set (AtkObject *accessible) 
681 {
682   AtkObjectClass *klass;
683
684   g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
685
686   klass = ATK_OBJECT_GET_CLASS (accessible);
687   if (klass->ref_state_set)
688     return (klass->ref_state_set) (accessible);
689   else
690     return NULL;
691 }
692
693 /**
694  * atk_object_get_index_in_parent:
695  * @accessible: an #AtkObject
696  *
697  * Gets the 0-based index of this accessible in its parent; returns -1 if the
698  * accessible does not have an accessible parent.
699  *
700  * Returns: an integer which is the index of the accessible in its parent
701  **/
702 gint
703 atk_object_get_index_in_parent (AtkObject *accessible)
704 {
705   AtkObjectClass *klass;
706
707   g_return_val_if_fail (ATK_OBJECT (accessible), -1);
708
709   klass = ATK_OBJECT_GET_CLASS (accessible);
710   if (klass->get_index_in_parent)
711     return (klass->get_index_in_parent) (accessible);
712   else
713     return -1;
714 }
715
716 /**
717  * atk_object_set_name:
718  * @accessible: an #AtkObject
719  * @name: a character string to be set as the accessible name
720  *
721  * Sets the accessible name of the accessible.
722  **/
723 void
724 atk_object_set_name (AtkObject    *accessible,
725                      const gchar  *name)
726 {
727   AtkObjectClass *klass;
728
729   g_return_if_fail (ATK_IS_OBJECT (accessible));
730   g_return_if_fail (name != NULL);
731
732   klass = ATK_OBJECT_GET_CLASS (accessible);
733   if (klass->set_name)
734     {
735       (klass->set_name) (accessible, name);
736       g_object_notify (G_OBJECT (accessible), atk_object_name_property_name);
737     }
738 }
739
740 /**
741  * atk_object_set_description:
742  * @accessible: an #AtkObject
743  * @description : a character string to be set as the accessible description
744  *
745  * Sets the accessible description of the accessible.
746  **/
747 void
748 atk_object_set_description (AtkObject   *accessible,
749                             const gchar *description)
750 {
751   AtkObjectClass *klass;
752
753   g_return_if_fail (ATK_IS_OBJECT (accessible));
754   g_return_if_fail (description != NULL);
755
756   klass = ATK_OBJECT_GET_CLASS (accessible);
757   if (klass->set_description)
758     {
759       (klass->set_description) (accessible, description);
760       g_object_notify (G_OBJECT (accessible), atk_object_name_property_description);
761     }
762 }
763
764 /**
765  * atk_object_set_parent:
766  * @accessible: an #AtkObject
767  * @parent : an #AtkObject to be set as the accessible parent
768  *
769  * Sets the accessible parent of the accessible.
770  **/
771 void
772 atk_object_set_parent (AtkObject *accessible,
773                        AtkObject *parent)
774 {
775   AtkObjectClass *klass;
776
777   g_return_if_fail (ATK_IS_OBJECT (accessible));
778
779   klass = ATK_OBJECT_GET_CLASS (accessible);
780   if (klass->set_parent)
781     {
782       (klass->set_parent) (accessible, parent);
783       g_object_notify (G_OBJECT (accessible), atk_object_name_property_parent);
784     }
785 }
786
787 /**
788  * atk_object_set_role:
789  * @accessible: an #AtkObject
790  * @role : an #AtkRole to be set as the role
791  *
792  * Sets the role of the accessible.
793  **/
794 void
795 atk_object_set_role (AtkObject *accessible, 
796                      AtkRole   role)
797 {
798   AtkObjectClass *klass;
799
800   g_return_if_fail (ATK_IS_OBJECT (accessible));
801
802   klass = ATK_OBJECT_GET_CLASS (accessible);
803   if (klass->set_role)
804     {
805       (klass->set_role) (accessible, role);
806       g_object_notify (G_OBJECT (accessible), atk_object_name_property_role);
807     }
808 }
809
810 /**
811  * atk_object_connect_property_change_handler:
812  * @accessible: an #AtkObject
813  * @handler : a function to be called when a property changes its value
814  *
815  * Specifies a function to be called when a property changes value.
816  *
817  * Returns: a #guint which is the handler id used in 
818  * atk_object_remove_property_change_handler()
819  **/
820 guint
821 atk_object_connect_property_change_handler (AtkObject *accessible,
822                                             AtkPropertyChangeHandler *handler)
823 {
824   AtkObjectClass *klass;
825
826   g_return_val_if_fail (ATK_IS_OBJECT (accessible), 0);
827   g_return_val_if_fail ((handler != NULL), 0);
828
829   klass = ATK_OBJECT_GET_CLASS (accessible);
830   if (klass->connect_property_change_handler)
831     return (klass->connect_property_change_handler) (accessible, handler);
832   else
833     return 0;
834 }
835
836 /**
837  * atk_object_remove_property_change_handler:
838  * @accessible: an #AtkObject
839  * @handler_id : a guint which identifies the handler to be removed.
840  * 
841  * Removes a property change handler.
842  **/
843 void
844 atk_object_remove_property_change_handler  (AtkObject *accessible,
845                                             guint      handler_id)
846 {
847   AtkObjectClass *klass;
848
849   g_return_if_fail (ATK_IS_OBJECT (accessible));
850
851   klass = ATK_OBJECT_GET_CLASS (accessible);
852   if (klass->remove_property_change_handler)
853     (klass->remove_property_change_handler) (accessible, handler_id);
854 }
855
856 /**
857  * atk_object_notify_state_change:
858  * @accessible: an #AtkObject
859  * @state: an #AtkState whose state is changed
860  * @value : a gboolean which indicates whether the state is being set on or off
861  * 
862  * Emits a state-change signal for the specified state. 
863  **/
864 void
865 atk_object_notify_state_change (AtkObject *accessible,
866                                 AtkState  state,
867                                 gboolean  value)
868 {
869   G_CONST_RETURN gchar* name;
870
871   name = atk_state_type_get_name (state);
872   g_signal_emit (accessible, atk_object_signals[STATE_CHANGE],
873                  g_quark_from_string (name),
874                  name, value, NULL);
875 }
876
877 /**
878  * atk_implementor_ref_accessible:
879  * @implementor: The #GObject instance which should implement #AtkImplementorIface
880  * if a non-null return value is required.
881  * 
882  * Gets a reference to an object's #AtkObject implementation, if
883  * the object implements #AtkObjectIface
884  *
885  * Returns: a reference to an object's #AtkObject implementation
886  */
887 AtkObject *
888 atk_implementor_ref_accessible (AtkImplementor *object)
889 {
890   AtkImplementorIface *iface;
891   AtkObject           *accessible = NULL;
892
893   g_return_val_if_fail (ATK_IS_IMPLEMENTOR (object), NULL);
894
895   iface = ATK_IMPLEMENTOR_GET_IFACE (object);
896
897   if (iface != NULL) 
898     accessible =  iface->ref_accessible (object);
899
900   g_return_val_if_fail ((accessible != NULL), NULL);
901
902   return accessible;
903 }
904
905 static AtkRelationSet*
906 atk_object_real_ref_relation_set (AtkObject *accessible)
907 {
908   g_return_val_if_fail (accessible->relation_set, NULL);
909   g_object_ref (accessible->relation_set); 
910
911   return accessible->relation_set;
912 }
913
914 static void
915 atk_object_real_set_property (GObject      *object,
916                               guint         prop_id,
917                               const GValue *value,
918                               GParamSpec   *pspec)
919 {
920   AtkObject *accessible;
921
922   accessible = ATK_OBJECT (object);
923
924   switch (prop_id)
925     {
926     case PROP_NAME:
927       atk_object_set_name (accessible, g_value_get_string (value));
928       break;
929     case PROP_DESCRIPTION:
930       atk_object_set_description (accessible, g_value_get_string (value));
931       break;
932     case PROP_ROLE:
933       atk_object_set_role (accessible, g_value_get_int (value));
934       break;
935     case PROP_PARENT:
936       atk_object_set_parent (accessible, g_value_get_object (value));
937       break;
938     case PROP_VALUE:
939       if (ATK_IS_VALUE (accessible))
940         atk_value_set_current_value (ATK_VALUE (accessible), value);
941       break;
942     default:
943       break;
944     }
945 }
946
947 static void
948 atk_object_real_get_property (GObject      *object,
949                               guint         prop_id,
950                               GValue       *value,
951                               GParamSpec   *pspec)
952 {
953   AtkObject *accessible;
954
955   accessible = ATK_OBJECT (object);
956
957   switch (prop_id)
958     {
959     case PROP_NAME:
960       g_value_set_string (value, atk_object_get_name (accessible));
961       break;
962     case PROP_DESCRIPTION:
963       g_value_set_string (value, atk_object_get_description (accessible));
964       break;
965     case PROP_ROLE:
966       g_value_set_int (value, atk_object_get_role (accessible));
967       break;
968     case PROP_LAYER:
969       g_value_set_int (value, atk_object_get_role (accessible));
970       break;
971     case PROP_MDI_ZORDER:
972       g_value_set_int (value, atk_object_get_mdi_zorder (accessible));
973       break;
974     case PROP_PARENT:
975       g_value_set_object (value, atk_object_get_parent (accessible));
976       break;
977     case PROP_VALUE:
978       if (ATK_IS_VALUE (accessible))
979         atk_value_get_current_value (ATK_VALUE (accessible), value);
980       break;
981     default:
982       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
983       break;
984     }
985 }
986
987 static void
988 atk_object_finalize (GObject *object)
989 {
990   AtkObject        *accessible;
991
992   g_return_if_fail (ATK_IS_OBJECT (object));
993
994   accessible = ATK_OBJECT (object);
995
996   g_free (accessible->name);
997   g_free (accessible->description);
998
999   /*
1000    * Free memory allocated for relation set if it have been allocated.
1001    */
1002   if (accessible->relation_set)
1003     g_object_unref (accessible->relation_set);
1004
1005   if (accessible->accessible_parent)
1006     g_object_unref (accessible->accessible_parent);
1007
1008   G_OBJECT_CLASS (parent_class)->finalize (object);
1009 }
1010
1011 static G_CONST_RETURN gchar*
1012 atk_object_real_get_name (AtkObject *object)
1013 {
1014   return object->name;
1015 }
1016
1017 static G_CONST_RETURN gchar*
1018 atk_object_real_get_description (AtkObject *object)
1019 {
1020   return object->description;
1021 }
1022
1023 static AtkObject*
1024 atk_object_real_get_parent (AtkObject       *object)
1025 {
1026   return object->accessible_parent;
1027 }
1028
1029 static AtkRole
1030 atk_object_real_get_role (AtkObject       *object)
1031 {
1032   return object->role;
1033 }
1034
1035 static AtkLayer
1036 atk_object_real_get_layer (AtkObject       *object)
1037 {
1038   return object->layer;
1039 }
1040
1041 static AtkStateSet*
1042 atk_object_real_ref_state_set (AtkObject *accessible) 
1043 {
1044   AtkStateSet *state_set;
1045   AtkObject *ap;
1046
1047   state_set = atk_state_set_new ();
1048
1049   ap = atk_object_get_parent (accessible);
1050   if (ap)
1051     if (ATK_IS_SELECTION (ap))
1052       {
1053         int i;
1054
1055         atk_state_set_add_state (state_set, ATK_STATE_SELECTABLE);
1056
1057         i = atk_object_get_index_in_parent (accessible);
1058         if (i >= 0)
1059           if (atk_selection_is_child_selected(ATK_SELECTION (ap), i))
1060             atk_state_set_add_state (state_set, ATK_STATE_SELECTED);
1061       } 
1062
1063   return state_set; 
1064 }
1065
1066 static void
1067 atk_object_real_set_name (AtkObject       *object,
1068                           const gchar     *name)
1069 {
1070   g_free (object->name);
1071   object->name = g_strdup (name);
1072 }
1073
1074 static void
1075 atk_object_real_set_description (AtkObject       *object,
1076                                  const gchar     *description)
1077 {
1078   g_free (object->description);
1079   object->description = g_strdup (description);
1080 }
1081
1082 static void
1083 atk_object_real_set_parent (AtkObject       *object,
1084                             AtkObject       *parent)
1085 {
1086   if (object->accessible_parent)
1087     g_object_unref (object->accessible_parent);
1088
1089   object->accessible_parent = parent;
1090   if (object->accessible_parent)
1091     g_object_ref (object->accessible_parent);
1092 }
1093
1094 static void
1095 atk_object_real_set_role (AtkObject *object,
1096                           AtkRole   role)
1097 {
1098   object->role = role;
1099 }
1100
1101 static guint
1102 atk_object_real_connect_property_change_handler (AtkObject                *obj,
1103                                                  AtkPropertyChangeHandler *handler)
1104 {
1105   return g_signal_connect_closure_by_id (obj,
1106                                          atk_object_signals[PROPERTY_CHANGE],
1107                                          0,
1108                                          g_cclosure_new (
1109                                          G_CALLBACK (handler), NULL,
1110                                          (GClosureNotify) NULL),
1111                                          FALSE);
1112 }
1113
1114 static void
1115 atk_object_real_remove_property_change_handler (AtkObject           *obj,
1116                                           guint               handler_id)
1117 {
1118   g_signal_handler_disconnect (obj, handler_id);
1119 }
1120
1121 /*
1122  * This function is a signal handler for notify signal which gets emitted
1123  * when a property changes value.
1124  *
1125  * It constructs an AtkPropertyValues structure and emits a "property_changed"
1126  * signal which causes the user specified AtkPropertyChangeHandler
1127  * to be called.
1128  */
1129 static void
1130 atk_object_notify (GObject     *obj,
1131                    GParamSpec  *pspec)
1132 {
1133   AtkPropertyValues values = { 0, };
1134
1135   g_value_init (&values.new_value, pspec->value_type);
1136   g_object_get_property (obj, pspec->name, &values.new_value);
1137   values.property_name = pspec->name;
1138   g_signal_emit (obj, atk_object_signals[PROPERTY_CHANGE],
1139                  g_quark_from_string (pspec->name),
1140                  &values, NULL);
1141 }
1142
1143 /**
1144  * atk_role_get_name:
1145  * @role: The #AtkRole whose name is required
1146  *
1147  * Gets the description string describing the #Roleype @role.
1148  *
1149  * Returns: the string describing the AtkRole
1150  */
1151 G_CONST_RETURN gchar*
1152 atk_role_get_name (AtkRole role)
1153 {
1154   gint n;
1155
1156   n = role;
1157
1158   if ((n >= 0) && (n < ATK_ROLE_LAST_DEFINED))
1159     return role_names[n];
1160
1161   return role_names[ATK_ROLE_INVALID];
1162 }
1163
1164 /**
1165  * atk_role_for_name:
1166  * @name: a string which is the (non-localized) name of an ATK role.
1167  *
1168  * Get the #AtkRole type corresponding to a rolew name.
1169  *
1170  * Returns: the #AtkRole enumerated type corresponding to the specified
1171 name,
1172  *          or #ATK_ROLE_INVALID if no matching role is found.
1173  **/
1174 AtkRole
1175 atk_role_for_name (const gchar *name)
1176 {
1177   gint i;
1178
1179   g_return_val_if_fail (name, ATK_ROLE_INVALID);
1180
1181   for (i = 0; i < ATK_ROLE_LAST_DEFINED; i++)
1182     {
1183       if (strcmp (name, role_names[i]) == 0)
1184         return i;
1185     }
1186   return ATK_ROLE_INVALID;
1187 }