Change "property-change" signal to allow detail (i.e. property name) and
[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
26 /* New GObject properties registered by AtkObject */
27 enum
28 {
29   PROP_0,  /* gobject convention */
30
31   PROP_NAME,
32   PROP_DESCRIPTION,
33   PROP_PARENT,      /* ancestry has changed */
34   PROP_CHILD,       /* a child has been added or removed */
35   PROP_STATE,       /* AtkStateSet for the object has changed */
36   PROP_TEXT,        /* Used only by AtkText implementors */
37   PROP_CARET,       /* Used only by AtkText implementors */
38   PROP_SELECTION,
39   PROP_VALUE,
40   PROP_VISIBLE_DATA,
41   PROP_ROLE,
42   PROP_TABLE_CAPTION,
43   PROP_TABLE_COLUMN_DESCRIPTION,
44   PROP_TABLE_COLUMN_HEADER,
45   PROP_TABLE_ROW_DESCRIPTION,
46   PROP_TABLE_ROW_HEADER,
47   PROP_TABLE_SUMMARY,
48   PROP_MODEL,
49   PROP_LAST         /* gobject convention */
50 };
51
52 enum {
53   CHILDREN_CHANGED,
54   FOCUS_EVENT,
55   PROPERTY_CHANGE,
56
57   LAST_SIGNAL
58 };
59
60 static void            atk_object_class_init        (AtkObjectClass  *klass);
61 static void            atk_object_init              (AtkObject       *accessible,
62                                                      AtkObjectClass  *klass);
63 static AtkRelationSet* atk_object_real_ref_relation_set 
64                                                     (AtkObject       *accessible);
65
66 static void            atk_object_real_set_property (GObject         *object,
67                                                      guint            prop_id,
68                                                      const GValue    *value,
69                                                      GParamSpec      *pspec);
70 static void            atk_object_real_get_property (GObject         *object,
71                                                      guint            prop_id,
72                                                      GValue          *value,
73                                                      GParamSpec      *pspec);
74 static void            atk_object_finalize          (GObject         *object);
75 static G_CONST_RETURN gchar*
76                        atk_object_real_get_name     (AtkObject       *object);
77 static G_CONST_RETURN gchar*
78                        atk_object_real_get_description    
79                                                    (AtkObject       *object);
80 static AtkObject*      atk_object_real_get_parent  (AtkObject       *object);
81 static AtkRole         atk_object_real_get_role    (AtkObject       *object);
82 static AtkStateSet*    atk_object_real_ref_state_set
83                                                    (AtkObject       *object);
84 static void            atk_object_real_set_name    (AtkObject       *object,
85                                                     const gchar     *name);
86 static void            atk_object_real_set_description
87                                                    (AtkObject       *object,
88                                                     const gchar     *description);
89 static void            atk_object_real_set_parent  (AtkObject       *object,
90                                                     AtkObject       *parent);
91 static void            atk_object_real_set_role    (AtkObject       *object,
92                                                     AtkRole         role);
93 static guint           atk_object_real_connect_property_change_handler
94                                                    (AtkObject       *obj,
95                                                     AtkPropertyChangeHandler
96                                                                     *handler);
97 static void            atk_object_real_remove_property_change_handler
98                                                    (AtkObject       *obj,
99                                                     guint           handler_id);
100 static void            atk_object_notify           (GObject         *obj,
101                                                     GParamSpec      *pspec);
102
103
104 static guint atk_object_signals[LAST_SIGNAL] = { 0, };
105
106 static gpointer parent_class = NULL;
107
108 static const gchar* atk_object_name_property_name = "accessible-name";
109 static const gchar* atk_object_name_property_state = "accessible-state";
110 static const gchar* atk_object_name_property_description = "accessible-description";
111 static const gchar* atk_object_name_property_child = "accessible-child";
112 static const gchar* atk_object_name_property_parent = "accessible-parent";
113 static const gchar* atk_object_name_property_text = "accessible-text";
114 static const gchar* atk_object_name_property_caret = "accessible-caret";
115 static const gchar* atk_object_name_property_selection = "accessible-selection";
116 static const gchar* atk_object_name_property_value = "accessible-value";
117 static const gchar* atk_object_name_property_visible = "accessible-visible-data";
118 static const gchar* atk_object_name_property_role = "accessible-role";
119 static const gchar* atk_object_name_property_table_caption = "accessible-table-caption";
120 static const gchar* atk_object_name_property_table_column_description = "accessible-table-column-description";
121 static const gchar* atk_object_name_property_table_column_header = "accessible-table-column-header";
122 static const gchar* atk_object_name_property_table_row_description = "accessible-table-row-description";
123 static const gchar* atk_object_name_property_table_row_header = "accessible-table-row-header";
124 static const gchar* atk_object_name_property_table_summary = "accessible-table-summary";
125 static const gchar* atk_object_name_property_model = "accessible-model";
126
127 GType
128 atk_object_get_type (void)
129 {
130   static GType type = 0;
131
132   if (!type)
133     {
134       static const GTypeInfo typeInfo =
135       {
136         sizeof (AtkObjectClass),
137         (GBaseInitFunc) NULL,
138         (GBaseFinalizeFunc) NULL,
139         (GClassInitFunc) atk_object_class_init,
140         (GClassFinalizeFunc) NULL,
141         NULL,
142         sizeof (AtkObject),
143         0,
144         (GInstanceInitFunc) atk_object_init,
145       } ;
146       type = g_type_register_static (G_TYPE_OBJECT, "AtkObject", &typeInfo, 0) ;
147     }
148   return type;
149 }
150
151 static void
152 atk_object_class_init (AtkObjectClass *klass)
153 {
154   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
155
156   parent_class = g_type_class_ref (G_TYPE_OBJECT);
157
158   gobject_class->set_property = atk_object_real_set_property;
159   gobject_class->get_property = atk_object_real_get_property;
160   gobject_class->finalize = atk_object_finalize;
161   gobject_class->notify = atk_object_notify;
162
163   klass->get_name = atk_object_real_get_name;
164   klass->get_description = atk_object_real_get_description;
165   klass->get_parent = atk_object_real_get_parent;
166   klass->get_n_children = NULL;
167   klass->ref_child = NULL;
168   klass->get_index_in_parent = NULL;
169   klass->ref_relation_set = atk_object_real_ref_relation_set;
170   klass->get_role = atk_object_real_get_role;
171   klass->ref_state_set = atk_object_real_ref_state_set;
172   klass->set_name = atk_object_real_set_name;
173   klass->set_description = atk_object_real_set_description;
174   klass->set_parent = atk_object_real_set_parent;
175   klass->set_role = atk_object_real_set_role;
176   klass->connect_property_change_handler = 
177          atk_object_real_connect_property_change_handler;
178   klass->remove_property_change_handler = 
179          atk_object_real_remove_property_change_handler;
180
181   /*
182    * We do not define default signal handlers here
183    */
184   klass->children_changed = NULL;
185   klass->focus_event = NULL;
186   klass->property_change = NULL;
187
188   g_object_class_install_property (gobject_class,
189                                    PROP_NAME,
190                                    g_param_spec_string (atk_object_name_property_name,
191                                                         "Accessible Name",
192                                                         "Object instance\'s name formatted for "
193                                                            "assistive technology access",
194                                                         NULL,
195                                                         G_PARAM_READWRITE));
196   g_object_class_install_property (gobject_class,
197                                    PROP_DESCRIPTION,
198                                    g_param_spec_string (atk_object_name_property_description,
199                                                         "Accessible Description",
200                                                         "Description of an object, formatted for "
201                                                         "assistive technology access",
202                                                         NULL,
203                                                         G_PARAM_READWRITE));
204   g_object_class_install_property (gobject_class,
205                                    PROP_STATE,
206                                    g_param_spec_int    (atk_object_name_property_state,
207                                                         "Accessible State Set",
208                                                         "The accessible state set of this object "
209                                                         "or its UI component",
210                                                         0,
211                                                         G_MAXINT,
212                                                         0,
213                                                         G_PARAM_READWRITE));
214   g_object_class_install_property (gobject_class,
215                                    PROP_CHILD,
216                                    g_param_spec_object (atk_object_name_property_child,
217                                                         "Accessible Child",
218                                                         "Is used to notify that a child has been added or removed ",
219                                                         ATK_TYPE_OBJECT,
220                                                         G_PARAM_READWRITE));
221   g_object_class_install_property (gobject_class,
222                                    PROP_PARENT,
223                                    g_param_spec_object (atk_object_name_property_parent,
224                                                         "Accessible Parent",
225                                                         "Is used to notify that the parent has changed ",
226                                                         ATK_TYPE_OBJECT,
227                                                         G_PARAM_READWRITE));
228   g_object_class_install_property (gobject_class,
229                                    PROP_TEXT,
230                                    g_param_spec_object (atk_object_name_property_text,
231                                                         "Accessible Text",
232                                                         "Is used to notify that the text has changed ",
233                                                         ATK_TYPE_OBJECT,
234                                                         G_PARAM_READWRITE));
235   g_object_class_install_property (gobject_class,
236                                    PROP_CARET,
237                                    g_param_spec_int    (atk_object_name_property_caret,
238                                                         "Accessible Caret",
239                                                         "Is used to notify that the caret position has changed ",
240                                                         0,
241                                                         G_MAXINT,
242                                                         0,
243                                                         G_PARAM_READWRITE));
244   g_object_class_install_property (gobject_class,
245                                    PROP_SELECTION,
246                                    g_param_spec_object (atk_object_name_property_selection,
247                                                         "Accessible Selection",
248                                                         "Is used to notify that the selection has changed ",
249                                                         ATK_TYPE_OBJECT,
250                                                         G_PARAM_READWRITE));
251   g_object_class_install_property (gobject_class,
252                                    PROP_VALUE,
253                                    g_param_spec_double (atk_object_name_property_value,
254                                                         "Accessible Value",
255                                                         "Is used to notify that the value has changed ",
256                                                         0.0,
257                                                         G_MAXDOUBLE,
258                                                         0.0,
259                                                         G_PARAM_READWRITE));
260   g_object_class_install_property (gobject_class,
261                                    PROP_VISIBLE_DATA,
262                                    g_param_spec_object (atk_object_name_property_visible,
263                                                         "Accessible Visible Data",
264                                                         "Is used to notify that the visual appearance of the object has changed ",
265                                                         ATK_TYPE_OBJECT,
266                                                         G_PARAM_READWRITE));
267   g_object_class_install_property (gobject_class,
268                                    PROP_ROLE,
269                                    g_param_spec_int    (atk_object_name_property_role,
270                                                         "Accessible Role",
271                                                         "The accessible role this object ",
272                                                         0,
273                                                         G_MAXINT,
274                                                         0,
275                                                         G_PARAM_READWRITE));
276   g_object_class_install_property (gobject_class,
277                                    PROP_TABLE_CAPTION,
278                                    g_param_spec_string (atk_object_name_property_table_caption,
279                                                         "Accessible Table Caption",
280                                                         "Is used to notify that the table caption has changed ",
281                                                         NULL,
282                                                         G_PARAM_READWRITE));
283   g_object_class_install_property (gobject_class,
284                                    PROP_TABLE_COLUMN_HEADER,
285                                    g_param_spec_object (atk_object_name_property_table_column_header,
286                                                         "Accessible Table Column Header",
287                                                         "Is used to notify that the table column header has changed ",
288                                                         ATK_TYPE_OBJECT,
289                                                         G_PARAM_READWRITE));
290   g_object_class_install_property (gobject_class,
291                                    PROP_TABLE_COLUMN_DESCRIPTION,
292                                    g_param_spec_string (atk_object_name_property_table_column_description,
293                                                         "Accessible Table Column Description",
294                                                         "Is used to notify that the table columnscription has changed ",
295                                                         NULL,
296                                                         G_PARAM_READWRITE));
297   g_object_class_install_property (gobject_class,
298                                    PROP_TABLE_ROW_HEADER,
299                                    g_param_spec_object (atk_object_name_property_table_row_header,
300                                                         "Accessible Table Row Header",
301                                                         "Is used to notify that the table row header has changed ",
302                                                         ATK_TYPE_OBJECT,
303                                                         G_PARAM_READWRITE));
304   g_object_class_install_property (gobject_class,
305                                    PROP_TABLE_ROW_DESCRIPTION,
306                                    g_param_spec_string (atk_object_name_property_table_row_description,
307                                                         "Accessible Table Row Description",
308                                                         "Is used to notify that the table row description has changed ",
309                                                         NULL,
310                                                         G_PARAM_READWRITE));
311   g_object_class_install_property (gobject_class,
312                                    PROP_TABLE_SUMMARY,
313                                    g_param_spec_object (atk_object_name_property_table_summary,
314                                                         "Accessible Table Summary",
315                                                         "Is used to notify that the table summary has changed ",
316                                                         ATK_TYPE_OBJECT,
317                                                         G_PARAM_READWRITE));
318   g_object_class_install_property (gobject_class,
319                                    PROP_MODEL,
320                                    g_param_spec_object (atk_object_name_property_model,
321                                                         "Accessible Model",
322                                                         "Is used to notify that the model for Table or Tree has changed ",
323                                                         ATK_TYPE_OBJECT,
324                                                         G_PARAM_READWRITE));
325   /*
326    * The signal "children_changed" supports two details:
327    * "add" and "remove"
328    */
329   atk_object_signals[CHILDREN_CHANGED] =
330     g_signal_new ("children_changed",
331                   G_TYPE_FROM_CLASS (klass),
332                   G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
333                   G_STRUCT_OFFSET (AtkObjectClass, children_changed),
334                   NULL, NULL,
335                   g_cclosure_marshal_VOID__UINT_POINTER,
336                   G_TYPE_NONE,
337                   2, G_TYPE_UINT, G_TYPE_POINTER);
338   atk_object_signals[FOCUS_EVENT] =
339     g_signal_new ("focus_event",
340                   G_TYPE_FROM_CLASS (klass),
341                   G_SIGNAL_RUN_LAST,
342                   G_STRUCT_OFFSET (AtkObjectClass, focus_event), 
343                   NULL, NULL,
344                   g_cclosure_marshal_VOID__BOOLEAN,
345                   G_TYPE_NONE,
346                   1, G_TYPE_BOOLEAN);
347   atk_object_signals[PROPERTY_CHANGE] =
348     g_signal_new ("property_change",
349                   G_TYPE_FROM_CLASS (klass),
350                   G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
351                   G_STRUCT_OFFSET (AtkObjectClass, property_change),
352                   (GSignalAccumulator) NULL, NULL,
353                   g_cclosure_marshal_VOID__POINTER,
354                   G_TYPE_NONE, 1,
355                   G_TYPE_POINTER);
356 }
357
358 static void
359 atk_object_init  (AtkObject        *accessible,
360                   AtkObjectClass   *klass)
361 {
362   accessible->name = NULL;
363   accessible->description = NULL;
364   accessible->accessible_parent = NULL;
365   accessible->relation_set = atk_relation_set_new();
366   accessible->role = ATK_ROLE_UNKNOWN;
367 }
368
369 GType
370 atk_implementor_get_type (void)
371 {
372   static GType type = 0;
373
374   if (!type)
375     {
376       static const GTypeInfo typeInfo =
377       {
378         sizeof (AtkImplementorIface),
379         (GBaseInitFunc) NULL,
380         (GBaseFinalizeFunc) NULL,
381       } ;
382
383       type = g_type_register_static (G_TYPE_INTERFACE, "AtkImplementorIface", &typeInfo, 0) ;
384     }
385
386   return type;
387 }
388
389 /**
390  * atk_object_get_name:
391  * @accessible: an #AtkObject
392  *
393  * Gets the accessible name of the accessible.
394  *
395  * Returns: a character string representing the accessible name of the object.
396  **/
397 G_CONST_RETURN gchar*
398 atk_object_get_name (AtkObject *accessible)
399 {
400   AtkObjectClass *klass;
401
402   g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
403
404   klass = ATK_OBJECT_GET_CLASS (accessible);
405   if (klass->get_name)
406     return (klass->get_name) (accessible);
407   else
408     return NULL;
409 }
410
411 /**
412  * atk_object_get_description:
413  * @accessible: an #AtkObject
414  *
415  * Gets the accessible description of the accessible.
416  *
417  * Returns: a character string representing the accessible description
418  * of the accessible.
419  *
420  **/
421 G_CONST_RETURN gchar*
422 atk_object_get_description (AtkObject *accessible)
423 {
424   AtkObjectClass *klass;
425
426   g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
427
428   klass = ATK_OBJECT_GET_CLASS (accessible);
429   if (klass->get_description)
430     return (klass->get_description) (accessible);
431   else
432     return NULL;
433 }
434
435 /**
436  * atk_object_get_parent:
437  * @accessible: an #AtkObject
438  *
439  * Gets the accessible parent of the accessible.
440  *
441  * Returns: a #AtkObject representing the accessible parent of the accessible
442  **/
443 AtkObject*
444 atk_object_get_parent (AtkObject *accessible)
445 {
446   AtkObjectClass *klass;
447
448   g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
449
450   klass = ATK_OBJECT_GET_CLASS (accessible);
451   if (klass->get_parent)
452     return (klass->get_parent) (accessible);
453   else
454     return NULL;
455 }
456
457 /**
458  * atk_object_get_n_accessible_children:
459  * @accessible: an #AtkObject
460  *
461  * Gets the number of accessible children of the accessible.
462  *
463  * Returns: an integer representing the number of accessible children
464  * of the accessible.
465  **/
466 gint
467 atk_object_get_n_accessible_children (AtkObject *accessible)
468 {
469   AtkObjectClass *klass;
470
471   g_return_val_if_fail (ATK_IS_OBJECT (accessible), 0);
472
473   klass = ATK_OBJECT_GET_CLASS (accessible);
474   if (klass->get_n_children)
475     return (klass->get_n_children) (accessible);
476   else
477     return 0;
478 }
479
480 /**
481  * atk_object_ref_accessible_child:
482  * @accessible: an #AtkObject
483  * @i: a gint representing the position of the child, starting from 0
484  *
485  * Gets a reference to the specified accessible child of the object.
486  * The accessible children are 0-based so the first accessible child is
487  * at index 0, the second at index 1 and so on.
488  *
489  * Returns: an #AtkObject representing the specified accessible child
490  * of the accessible.
491  **/
492 AtkObject*
493 atk_object_ref_accessible_child (AtkObject   *accessible,
494                                  gint        i)
495 {
496   AtkObjectClass *klass;
497
498   g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
499
500   klass = ATK_OBJECT_GET_CLASS (accessible);
501   if (klass->ref_child)
502     return (klass->ref_child) (accessible, i);
503   else
504     return NULL;
505 }
506
507 /**
508  * atk_object_ref_relation_set:
509  * @accessible: an #AtkObject
510  *
511  * Gets the #AtkRelationSet associated with the object.
512  *
513  * Returns: an #AtkRelationSet representing the relation set of the object.
514  **/
515 AtkRelationSet*
516 atk_object_ref_relation_set (AtkObject *accessible)
517 {
518   AtkObjectClass *klass;
519
520   g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
521
522   klass = ATK_OBJECT_GET_CLASS (accessible);
523   if (klass->ref_relation_set)
524     return (klass->ref_relation_set) (accessible);
525   else
526     return NULL;
527 }
528
529 /**
530  * atk_role_register:
531  * @name: a character string describing the new role.
532  *
533  * Registers the role specified by @name.
534  *
535  * Returns: an #AtkRole for the new role.
536  **/
537 AtkRole
538 atk_role_register (const gchar *name)
539 {
540   /* TODO: associate name with new type */
541   static guint type = ATK_ROLE_LAST_DEFINED;
542   return (++type);
543 }
544
545 /**
546  * atk_object_get_role:
547  * @accessible: an #AtkObject
548  *
549  * Gets the role of the accessible.
550  *
551  * Returns: an #AtkRole which is the role of the accessible
552  **/
553 AtkRole
554 atk_object_get_role (AtkObject *accessible) 
555 {
556   AtkObjectClass *klass;
557
558   g_return_val_if_fail (ATK_IS_OBJECT (accessible), ATK_ROLE_UNKNOWN);
559
560   klass = ATK_OBJECT_GET_CLASS (accessible);
561   if (klass->get_role)
562     return (klass->get_role) (accessible);
563   else
564     return ATK_ROLE_UNKNOWN;
565 }
566
567 /**
568  * atk_object_ref_state_set:
569  * @accessible: an #AtkObject
570  *
571  * Gets a reference to the state set of the accessible; the caller must
572  * unreference it when it is no longer needed.
573  *
574  * Returns: a reference to an #AtkStateSet which is the state
575  * set of the accessible
576  **/
577 AtkStateSet*
578 atk_object_ref_state_set (AtkObject *accessible) 
579 {
580   AtkObjectClass *klass;
581
582   g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
583
584   klass = ATK_OBJECT_GET_CLASS (accessible);
585   if (klass->ref_state_set)
586     return (klass->ref_state_set) (accessible);
587   else
588     return NULL;
589 }
590
591 /**
592  * atk_object_get_index_in_parent:
593  * @accessible: an #AtkObject
594  *
595  * Gets the 0-based index of this accessible in its parent; returns -1 if the
596  * accessible does not have an accessible parent.
597  *
598  * Returns: an integer which is the index of the accessible in its parent
599  **/
600 gint
601 atk_object_get_index_in_parent (AtkObject *accessible)
602 {
603   AtkObjectClass *klass;
604
605   g_return_val_if_fail (ATK_OBJECT (accessible), -1);
606
607   klass = ATK_OBJECT_GET_CLASS (accessible);
608   if (klass->get_index_in_parent)
609     return (klass->get_index_in_parent) (accessible);
610   else
611     return -1;
612 }
613
614 /**
615  * atk_object_set_name:
616  * @accessible: an #AtkObject
617  * @name: a character string to be set as the accessible name
618  *
619  * Sets the accessible name of the accessible.
620  **/
621 void
622 atk_object_set_name (AtkObject    *accessible,
623                      const gchar  *name)
624 {
625   AtkObjectClass *klass;
626
627   g_return_if_fail (ATK_IS_OBJECT (accessible));
628   g_return_if_fail (name != NULL);
629
630   klass = ATK_OBJECT_GET_CLASS (accessible);
631   if (klass->set_name)
632   {
633     (klass->set_name) (accessible, name);
634     g_object_notify (G_OBJECT (accessible), atk_object_name_property_name);
635   }
636 }
637
638 /**
639  * atk_object_set_description:
640  * @accessible: an #AtkObject
641  * @description : a character string to be set as the accessible description
642  *
643  * Sets the accessible description of the accessible.
644  **/
645 void
646 atk_object_set_description (AtkObject   *accessible,
647                             const gchar *description)
648 {
649   AtkObjectClass *klass;
650
651   g_return_if_fail (ATK_IS_OBJECT (accessible));
652   g_return_if_fail (description != NULL);
653
654   klass = ATK_OBJECT_GET_CLASS (accessible);
655   if (klass->set_description)
656   {
657     (klass->set_description) (accessible, description);
658     g_object_notify (G_OBJECT (accessible), atk_object_name_property_description);
659   }
660 }
661
662 /**
663  * atk_object_set_parent:
664  * @accessible: an #AtkObject
665  * @parent : an #AtkObject to be set as the accessible parent
666  *
667  * Sets the accessible parent of the accessible.
668  **/
669 void
670 atk_object_set_parent (AtkObject *accessible,
671                        AtkObject *parent)
672 {
673   AtkObjectClass *klass;
674
675   g_return_if_fail (ATK_IS_OBJECT (accessible));
676
677   klass = ATK_OBJECT_GET_CLASS (accessible);
678   if (klass->set_parent)
679     (klass->set_parent) (accessible, parent);
680 }
681
682 /**
683  * atk_object_set_role:
684  * @accessible: an #AtkObject
685  * @role : an #AtkRole to be set as the role
686  *
687  * Sets the role of the accessible.
688  **/
689 void
690 atk_object_set_role (AtkObject *accessible, 
691                      AtkRole   role)
692 {
693   AtkObjectClass *klass;
694
695   g_return_if_fail (ATK_IS_OBJECT (accessible));
696
697   klass = ATK_OBJECT_GET_CLASS (accessible);
698   if (klass->set_role)
699     (klass->set_role) (accessible, role);
700 }
701
702 /**
703  * atk_object_connect_property_change_handler:
704  * @accessible: an #AtkObject
705  * @handler : a function to be called when a property changes its value
706  *
707  * Specifies a function to be called when a property changes value.
708  *
709  * Returns: a #guint which is the handler id used in 
710  * atk_object_remove_property_change_handler()
711  **/
712 guint
713 atk_object_connect_property_change_handler (AtkObject *accessible,
714                                             AtkPropertyChangeHandler *handler)
715 {
716   AtkObjectClass *klass;
717
718   g_return_val_if_fail (ATK_IS_OBJECT (accessible), 0);
719   g_return_val_if_fail ((handler != NULL), 0);
720
721   klass = ATK_OBJECT_GET_CLASS (accessible);
722   if (klass->connect_property_change_handler)
723     return (klass->connect_property_change_handler) (accessible, handler);
724   else
725     return 0;
726 }
727
728 /**
729  * atk_object_remove_property_change_handler:
730  * @accessible: an #AtkObject
731  * @handler_id : a guint which identifies the handler to be removed.
732  * 
733  * Removes a property change handler.
734  **/
735 void
736 atk_object_remove_property_change_handler  (AtkObject *accessible,
737                                             guint      handler_id)
738 {
739   AtkObjectClass *klass;
740
741   g_return_if_fail (ATK_IS_OBJECT (accessible));
742
743   klass = ATK_OBJECT_GET_CLASS (accessible);
744   if (klass->remove_property_change_handler)
745     (klass->remove_property_change_handler) (accessible, handler_id);
746 }
747
748 /**
749  * atk_implementor_ref_accessible:
750  * @implementor: The #GObject instance which should implement #AtkImplementorIface
751  * if a non-null return value is required.
752  * 
753  * Gets a reference to an object's #AtkObject implementation, if
754  * the object implements #AtkObjectIface
755  *
756  * Returns: a reference to an object's #AtkObject implementation
757  */
758 AtkObject *
759 atk_implementor_ref_accessible (AtkImplementor *object)
760 {
761   AtkImplementorIface *iface;
762   AtkObject           *accessible = NULL;
763
764   g_return_val_if_fail (ATK_IS_IMPLEMENTOR (object), NULL);
765
766   iface = ATK_IMPLEMENTOR_GET_IFACE (object);
767
768   if (iface != NULL) 
769     accessible =  iface->ref_accessible (object);
770
771   g_return_val_if_fail ((accessible != NULL), NULL);
772
773   return accessible;
774 }
775
776 static AtkRelationSet*
777 atk_object_real_ref_relation_set (AtkObject *accessible)
778 {
779   g_return_val_if_fail (accessible->relation_set, NULL);
780   g_object_ref (accessible->relation_set); 
781
782   return accessible->relation_set;
783 }
784
785 static void
786 atk_object_real_set_property (GObject      *object,
787                               guint         prop_id,
788                               const GValue *value,
789                               GParamSpec   *pspec)
790 {
791   AtkObject *accessible;
792
793   accessible = ATK_OBJECT (object);
794
795   switch (prop_id)
796   {
797     case PROP_NAME:
798       atk_object_set_name (accessible, g_value_get_string (value));
799       break;
800     case PROP_DESCRIPTION:
801       atk_object_set_description (accessible, g_value_get_string (value));
802       break;
803     case PROP_STATE:
804       g_print ("This interface does not support setting the state set of an accessible object\n");
805       break;
806     case PROP_VALUE:
807       if (ATK_IS_VALUE (accessible))
808         atk_value_set_current_value (ATK_VALUE (accessible), value);
809       break;
810     default:
811       break;
812   }
813 }
814
815 static void
816 atk_object_real_get_property (GObject      *object,
817                               guint         prop_id,
818                               GValue       *value,
819                               GParamSpec   *pspec)
820 {
821   AtkObject *accessible;
822
823   accessible = ATK_OBJECT (object);
824
825   switch (prop_id)
826   {
827     case PROP_NAME:
828       g_value_set_string (value, atk_object_get_name (accessible));
829       break;
830     case PROP_DESCRIPTION:
831       g_value_set_string (value, atk_object_get_description (accessible));
832       break;
833     case PROP_VALUE:
834       if (ATK_IS_VALUE (accessible))
835         atk_value_get_current_value (ATK_VALUE (accessible), value);
836       break;
837     default:
838       break;
839   }
840 }
841
842 static void
843 atk_object_finalize (GObject *object)
844 {
845   AtkObject        *accessible;
846
847   g_return_if_fail (ATK_IS_OBJECT (object));
848
849   accessible = ATK_OBJECT (object);
850
851   g_free (accessible->name);
852   g_free (accessible->description);
853
854   /*
855    * Free memory allocated for relation set if it have been allocated.
856    */
857   if (accessible->relation_set)
858     g_object_unref (accessible->relation_set);
859
860   if (accessible->accessible_parent)
861     g_object_unref (accessible->accessible_parent);
862
863   G_OBJECT_CLASS (parent_class)->finalize (object);
864 }
865
866 static G_CONST_RETURN gchar*
867 atk_object_real_get_name (AtkObject *object)
868 {
869   return object->name;
870 }
871
872 static G_CONST_RETURN gchar*
873 atk_object_real_get_description (AtkObject *object)
874 {
875   return object->description;
876 }
877
878 static AtkObject*
879 atk_object_real_get_parent (AtkObject       *object)
880 {
881   return object->accessible_parent;
882 }
883
884 static AtkRole
885 atk_object_real_get_role (AtkObject       *object)
886 {
887   return object->role;
888 }
889
890 static AtkStateSet*
891 atk_object_real_ref_state_set (AtkObject *accessible) 
892 {
893   AtkStateSet *state_set;
894   AtkObject *ap;
895
896   state_set = atk_state_set_new ();
897
898   ap = atk_object_get_parent (accessible);
899   if (ap)
900   {
901     if (ATK_IS_SELECTION (ap))
902     {
903       int i;
904
905       atk_state_set_add_state (state_set, ATK_STATE_SELECTABLE);
906
907       i = atk_object_get_index_in_parent (accessible);
908       if (i >= 0)
909       {
910         if (atk_selection_is_child_selected(ATK_SELECTION (ap), i))
911         {
912           atk_state_set_add_state (state_set, ATK_STATE_SELECTED);
913         } 
914       } 
915     } 
916   }
917   return state_set; 
918 }
919
920 static void
921 atk_object_real_set_name (AtkObject       *object,
922                           const gchar     *name)
923 {
924   g_free (object->name);
925   object->name = g_strdup (name);
926 }
927
928 static void
929 atk_object_real_set_description (AtkObject       *object,
930                                  const gchar     *description)
931 {
932   g_free (object->description);
933   object->description = g_strdup (description);
934 }
935
936 static void
937 atk_object_real_set_parent (AtkObject       *object,
938                             AtkObject       *parent)
939 {
940   if (object->accessible_parent)
941     g_object_unref (object->accessible_parent);
942
943   object->accessible_parent = parent;
944   if (object->accessible_parent)
945     g_object_ref (object->accessible_parent);
946 }
947
948 static void
949 atk_object_real_set_role (AtkObject *object,
950                           AtkRole   role)
951 {
952   object->role = role;
953 }
954
955 static guint
956 atk_object_real_connect_property_change_handler (AtkObject                *obj,
957                                                  AtkPropertyChangeHandler *handler)
958 {
959   return g_signal_connect_closure_by_id (obj,
960                                          atk_object_signals[PROPERTY_CHANGE],
961                                          0,
962                                          g_cclosure_new (
963                                          G_CALLBACK (handler), NULL,
964                                          (GClosureNotify) NULL),
965                                          FALSE);
966 }
967
968 static void
969 atk_object_real_remove_property_change_handler (AtkObject           *obj,
970                                           guint               handler_id)
971 {
972   g_signal_handler_disconnect (obj, handler_id);
973 }
974
975 /*
976  * This function is a signal handler for notify signal which gets emitted
977  * when a property changes value.
978  *
979  * It constructs an AtkPropertyValues structure and emits a "property_changed"
980  * signal which causes the user specified AtkPropertyChangeHandler
981  * to be called.
982  */
983 static void
984 atk_object_notify (GObject     *obj,
985                    GParamSpec  *pspec)
986 {
987   AtkPropertyValues values;
988
989   memset (&values.old_value, 0, sizeof (GValue));
990   memset (&values.new_value, 0, sizeof (GValue));
991   g_value_init (&values.new_value, pspec->value_type);
992   g_object_get_property(obj, pspec->name, &values.new_value);
993   values.property_name = pspec->name;
994   g_signal_emit (obj, atk_object_signals[PROPERTY_CHANGE],
995                  g_quark_from_string (pspec->name),
996                  &values, NULL);
997 }
998