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