Updated gtk-doc comment blocks for Oisin Boydell
[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_LAST         /* gobject convention */
39 };
40
41 enum {
42   CHILDREN_CHANGED,
43   FOCUS_EVENT,
44   LAST_SIGNAL
45 };
46
47 static void            atk_object_class_init       (AtkObjectClass  *klass);
48 static void            atk_object_init             (AtkObject       *accessible,
49                                                     AtkObjectClass  *klass);
50 static AtkRelationSet* atk_object_real_ref_relation_set (AtkObject *accessible);
51
52 static void            atk_object_real_set_property(GObject         *object,
53                                                     guint            prop_id,
54                                                     const GValue    *value,
55                                                     GParamSpec      *pspec);
56 static void            atk_object_real_get_property(GObject         *object,
57                                                     guint            prop_id,
58                                                     GValue          *value,
59                                                     GParamSpec      *pspec);
60 static void            atk_object_finalize         (GObject         *object);
61 static void            atk_object_real_set_role    (AtkObject       *object,
62                                                     AtkRole         role);
63
64 static guint atk_object_signals[LAST_SIGNAL] = { 0, };
65
66 static gpointer parent_class = NULL;
67
68 static const gchar* atk_object_name_property_name = "accessible-name";
69 static const gchar* atk_object_name_property_state = "accessible-state";
70 static const gchar* atk_object_name_property_description = "accessible-description";
71 static const gchar* atk_object_name_property_child = "accessible-child";
72 static const gchar* atk_object_name_property_parent = "accessible-parent";
73
74 GType
75 atk_object_get_type (void)
76 {
77   static GType type = 0;
78
79   if (!type)
80     {
81       static const GTypeInfo typeInfo =
82       {
83         sizeof (AtkObjectClass),
84         (GBaseInitFunc) NULL,
85         (GBaseFinalizeFunc) NULL,
86         (GClassInitFunc) atk_object_class_init,
87         (GClassFinalizeFunc) NULL,
88         NULL,
89         sizeof (AtkObject),
90         0,
91         (GInstanceInitFunc) atk_object_init,
92       } ;
93       type = g_type_register_static (G_TYPE_OBJECT, "AtkObject", &typeInfo, 0) ;
94     }
95   return type;
96 }
97
98 static void
99 atk_object_class_init (AtkObjectClass *klass)
100 {
101   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
102
103   parent_class = g_type_class_ref (G_TYPE_OBJECT);
104
105   gobject_class->set_property = atk_object_real_set_property;
106   gobject_class->get_property = atk_object_real_get_property;
107   gobject_class->finalize = atk_object_finalize;
108
109   klass->ref_relation_set = atk_object_real_ref_relation_set;
110   klass->set_role = atk_object_real_set_role;
111
112   /*
113    * We do not define default signal handlers here
114    */
115   klass->focus_event = NULL;
116   klass->children_changed = NULL;
117
118   g_object_class_install_property (gobject_class,
119                                    PROP_NAME,
120                                    g_param_spec_string (atk_object_name_property_name,
121                                                         "Accessible Name",
122                                                         "Object instance\'s name formatted for "
123                                                            "assistive technology access",
124                                                         NULL,
125                                                         G_PARAM_READWRITE));
126   g_object_class_install_property (gobject_class,
127                                    PROP_DESCRIPTION,
128                                    g_param_spec_string (atk_object_name_property_description,
129                                                         "Accessible Description",
130                                                         "Description of an object, formatted for "
131                                                         "assistive technology access",
132                                                         NULL,
133                                                         G_PARAM_READWRITE));
134   g_object_class_install_property (gobject_class,
135                                    PROP_STATE,
136                                    g_param_spec_int    (atk_object_name_property_state,
137                                                         "Accessible State Set",
138                                                         "The accessible state set of this object "
139                                                         "or its UI component",
140                                                         0,
141                                                         G_MAXINT,
142                                                         0,
143                                                         G_PARAM_READWRITE));
144   g_object_class_install_property (gobject_class,
145                                    PROP_CHILD,
146                                    g_param_spec_object (atk_object_name_property_child,
147                                                         "Accessible Child",
148                                                         "Is used to notify that a child has been added or removed ",
149                                                         ATK_TYPE_OBJECT,
150                                                         G_PARAM_READWRITE));
151    g_object_class_install_property (gobject_class,
152                                     PROP_PARENT,
153                                    g_param_spec_object (atk_object_name_property_parent,
154                                                         "Accessible Parent",
155                                                         "Is used to notify that the parent has been changed ",
156                                                         ATK_TYPE_OBJECT,
157                                                         G_PARAM_READWRITE));
158 #if 0
159   g_object_class_install_property (gobject_class,
160                                    PROP_TEXT,
161                                    g_param_spec_ccallback ("accessible_text", "Accessible Text",
162                                                            "This object\'s accessible text contents",
163                                                            G_PARAM_READWRITE));
164   g_object_class_install_property (gobject_class,
165                                    PROP_CARET,
166                                    g_param_spec_ccallback ("accessible_caret", "Accessible Text Caret",
167                                                            "The current text caret state and position "
168                                                            "for this component",
169                                                            G_PARAM_READWRITE));
170 #endif
171   /*
172    * The signal "children_changed" supports two details:
173    * "add" and "remove"
174    */
175   atk_object_signals[CHILDREN_CHANGED] =
176     g_signal_newc ("children_changed",
177                    G_TYPE_FROM_CLASS (klass),
178                    G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
179                    G_STRUCT_OFFSET (AtkObjectClass, children_changed),
180                    NULL, NULL,
181                    g_cclosure_marshal_VOID__UINT_POINTER,
182                    G_TYPE_NONE,
183                    2, G_TYPE_UINT, ATK_TYPE_OBJECT);
184   atk_object_signals[FOCUS_EVENT] =
185     g_signal_newc ("focus_event",
186                    G_TYPE_FROM_CLASS (klass),
187                    G_SIGNAL_RUN_LAST,
188                    G_STRUCT_OFFSET (AtkObjectClass, focus_event), 
189                    NULL, NULL,
190                    g_cclosure_marshal_VOID__BOOLEAN,
191                    G_TYPE_NONE,
192                    1, G_TYPE_BOOLEAN);
193 }
194
195 static void
196 atk_object_init  (AtkObject        *accessible,
197                   AtkObjectClass   *klass)
198 {
199 }
200
201 GType
202 atk_implementor_get_type (void)
203 {
204   static GType type = 0;
205
206   if (!type)
207     {
208       static const GTypeInfo typeInfo =
209       {
210         sizeof (AtkImplementorIface),
211         (GBaseInitFunc) NULL,
212         (GBaseFinalizeFunc) NULL,
213       } ;
214
215       type = g_type_register_static (G_TYPE_INTERFACE, "AtkImplementorIface", &typeInfo, 0) ;
216     }
217
218   return type;
219 }
220
221 /**
222  * atk_object_get_name:
223  * @accessible: an #AtkObject
224  *
225  * Gets the accessible name of the accessible
226  *
227  * Returns: a character string representing the accessible name of the object.
228  **/
229 G_CONST_RETURN gchar*
230 atk_object_get_name (AtkObject *accessible)
231 {
232   AtkObjectClass *klass;
233
234   g_return_val_if_fail (accessible != NULL, NULL);
235   g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
236
237   klass = ATK_OBJECT_GET_CLASS (accessible);
238   if (klass->get_name)
239     return (klass->get_name) (accessible);
240   else
241     return NULL;
242 }
243
244 /**
245  * atk_object_get_description:
246  * @accessible: an #AtkObject
247  *
248  * Gets the accessible description of the accessible
249  *
250  * Returns: a character string representing the accessible description
251  * of the accessible.
252  *
253  **/
254 G_CONST_RETURN gchar*
255 atk_object_get_description (AtkObject *accessible)
256 {
257   AtkObjectClass *klass;
258
259   g_return_val_if_fail (accessible != NULL, NULL);
260   g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
261
262   klass = ATK_OBJECT_GET_CLASS (accessible);
263   if (klass->get_description)
264     return (klass->get_description) (accessible);
265   else
266     return NULL;
267 }
268
269 /**
270  * atk_object_get_parent:
271  * @accessible: an #AtkObject
272  *
273  * Gets the accessible parent of the accessible
274  *
275  * Returns: a #AtkObject representing the accessible parent of the accessible
276  **/
277 AtkObject*
278 atk_object_get_parent (AtkObject *accessible)
279 {
280   AtkObjectClass *klass;
281
282   g_return_val_if_fail (accessible != NULL, NULL);
283   g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
284
285   klass = ATK_OBJECT_GET_CLASS (accessible);
286   if (klass->get_parent)
287     return (klass->get_parent) (accessible);
288   else
289     return NULL;
290 }
291
292 /**
293  * atk_object_get_n_accessible_children:
294  * @accessible: an #AtkObject
295  *
296  * Gets the number of accessible children of the accessible
297  *
298  * Returns: an integer representing the number of accessible children
299  * of the accessible.
300  **/
301 gint
302 atk_object_get_n_accessible_children (AtkObject *accessible)
303 {
304   AtkObjectClass *klass;
305
306   g_return_val_if_fail (accessible != NULL, 0);
307   g_return_val_if_fail (ATK_IS_OBJECT (accessible), 0);
308
309   klass = ATK_OBJECT_GET_CLASS (accessible);
310   if (klass->get_n_children)
311     return (klass->get_n_children) (accessible);
312   else
313     return 0;
314 }
315
316 /**
317  * atk_object_ref_accessible_child:
318  * @accessible: an #AtkObject
319  * @i: a gint representing the position of the child, starting from 0
320  *
321  * Gets a reference to the specified accessible child of the object.
322  * The accessible children are 0-based so the first accessible child is
323  * at index 0, the second at index 1 and so on.
324  *
325  * Returns: an #AtkObject representing the specified accessible child
326  * of the accessible.
327  **/
328 AtkObject*
329 atk_object_ref_accessible_child (AtkObject   *accessible,
330                                  gint        i)
331 {
332   AtkObjectClass *klass;
333
334   g_return_val_if_fail (accessible != NULL, NULL);
335   g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
336
337   klass = ATK_OBJECT_GET_CLASS (accessible);
338   if (klass->ref_child)
339     return (klass->ref_child) (accessible, i);
340   else
341     return NULL;
342 }
343
344 /**
345  * atk_object_ref_relation_set:
346  * @accessible: an #AtkObject
347  *
348  * Gets the RelationSet associated with the object
349  *
350  * Returns: an #AtkRelationSet representing the relation set of the object.
351  **/
352 AtkRelationSet*
353 atk_object_ref_relation_set (AtkObject *accessible)
354 {
355   AtkObjectClass *klass;
356
357   g_return_val_if_fail (accessible != NULL, NULL);
358   g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
359
360   klass = ATK_OBJECT_GET_CLASS (accessible);
361   if (klass->ref_relation_set)
362     return (klass->ref_relation_set) (accessible);
363   else
364     return NULL;
365 }
366
367 /**
368  * atk_role_register:
369  * @name: a character string describing the new role.
370  *
371  * Returns: an #AtkRole for the new role.
372  **/
373 AtkRole
374 atk_role_register (const gchar *name)
375 {
376   /* TODO: associate name with new type */
377   static guint type = ATK_ROLE_LAST_DEFINED;
378   return (++type);
379 }
380
381 /**
382  * atk_object_get_role:
383  * @accessible: an #AtkObject
384  *
385  * Gets the role of the accessible
386  *
387  * Returns: an #AtkRole which is the role of the accessible
388  **/
389 AtkRole
390 atk_object_get_role (AtkObject *accessible) {
391   AtkObjectClass *klass;
392
393   g_return_val_if_fail (accessible != NULL, ATK_ROLE_UNKNOWN);
394   g_return_val_if_fail (ATK_IS_OBJECT (accessible), ATK_ROLE_UNKNOWN);
395
396   klass = ATK_OBJECT_GET_CLASS (accessible);
397   if (klass->get_role)
398     return (klass->get_role) (accessible);
399   else
400     return ATK_ROLE_UNKNOWN;
401 }
402
403 /**
404  * atk_object_ref_state_set:
405  * @accessible: an #AtkObject
406  *
407  * Gets a reference to the state set of the accessible; the caller should
408  * unreference it.
409  *
410  * Returns: a reference to an #AtkStateSet which is the state
411  * set of the accessible
412  **/
413 AtkStateSet*
414 atk_object_ref_state_set (AtkObject *accessible) {
415   AtkObjectClass *klass;
416
417   g_return_val_if_fail (accessible != NULL, NULL);
418   g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
419
420   klass = ATK_OBJECT_GET_CLASS (accessible);
421   if (klass->ref_state_set)
422     return (klass->ref_state_set) (accessible);
423   else
424     return NULL;
425 }
426
427 /**
428  * atk_object_get_index_in_parent:
429  * @accessible: an #AtkObject
430  *
431  * Gets the 0-based index of this accessible in its parent; returns -1 if the
432  * accessible does not have an accessible parent.
433  *
434  * Returns: an integer which is the index of the accessible in its parent
435  **/
436 gint
437 atk_object_get_index_in_parent (AtkObject *accessible)
438 {
439   AtkObjectClass *klass;
440
441   g_return_val_if_fail (accessible != NULL, -1);
442   g_return_val_if_fail (ATK_OBJECT (accessible), -1);
443
444   klass = ATK_OBJECT_GET_CLASS (accessible);
445   if (klass->get_index_in_parent)
446     return (klass->get_index_in_parent) (accessible);
447   else
448     return -1;
449 }
450
451 /**
452  * atk_object_set_name:
453  * @accessible: an #AtkObject
454  * @name: a character string to be set as the accessible name
455  *
456  * Sets the accessible name of the accessible
457  **/
458 void
459 atk_object_set_name (AtkObject    *accessible,
460                      const gchar  *name)
461 {
462   AtkObjectClass *klass;
463
464   g_return_if_fail (accessible != NULL);
465   g_return_if_fail (ATK_IS_OBJECT (accessible));
466   g_return_if_fail (name != NULL);
467
468   klass = ATK_OBJECT_GET_CLASS (accessible);
469   if (klass->set_name)
470   {
471     (klass->set_name) (accessible, name);
472     g_object_notify (G_OBJECT (accessible), atk_object_name_property_name);
473   }
474 }
475
476 /**
477  * atk_object_set_description:
478  * @accessible: an #AtkObject
479  * @description : a character string to be set as the accessible description
480  *
481  * Sets the accessible description of the accessible
482  **/
483 void
484 atk_object_set_description (AtkObject   *accessible,
485                             const gchar *description)
486 {
487   AtkObjectClass *klass;
488
489   g_return_if_fail (accessible != NULL);
490   g_return_if_fail (ATK_IS_OBJECT (accessible));
491   g_return_if_fail (description != NULL);
492
493   klass = ATK_OBJECT_GET_CLASS (accessible);
494   if (klass->set_description)
495   {
496     (klass->set_description) (accessible, description);
497     g_object_notify (G_OBJECT (accessible), atk_object_name_property_description);
498   }
499 }
500
501 /**
502  * atk_object_set_parent:
503  * @accessible: an #AtkObject
504  * @parent : an #AtkObject to be set as the accessible parent
505  *
506  * Sets the accessible parent of the accessible
507  **/
508 void
509 atk_object_set_parent (AtkObject *accessible,
510                        AtkObject *parent)
511 {
512   AtkObjectClass *klass;
513
514   g_return_if_fail (accessible != NULL);
515   g_return_if_fail (ATK_IS_OBJECT (accessible));
516
517   klass = ATK_OBJECT_GET_CLASS (accessible);
518   if (klass->set_parent)
519     (klass->set_parent) (accessible, parent);
520 }
521
522 /**
523  * atk_object_set_role:
524  * @accessible: an #AtkObject
525  * @role : an #AtkRole to be set as the role
526  *
527  * Sets the role of the accessible
528  **/
529 void
530 atk_object_set_role (AtkObject *accessible, 
531                      AtkRole   role)
532 {
533   AtkObjectClass *klass;
534
535   g_return_if_fail (accessible != NULL);
536   g_return_if_fail (ATK_IS_OBJECT (accessible));
537
538   klass = ATK_OBJECT_GET_CLASS (accessible);
539   if (klass->set_role)
540     (klass->set_role) (accessible, role);
541 }
542
543 /**
544  * atk_object_connect_property_change_handler:
545  * @accessible: an #AtkObject
546  * @handler : a function to be called when a property changes its value
547  *
548  * Specifies a function to be called when a property changes value.
549  *
550  * Returns: a #guint which is the handler id used in 
551  * atk_object_remove_property_change_handler()
552  **/
553 guint
554 atk_object_connect_property_change_handler (AtkObject *accessible,
555                                             AtkPropertyChangeHandler *handler)
556 {
557   AtkObjectClass *klass;
558
559   g_return_val_if_fail (accessible != NULL, 0);
560   g_return_val_if_fail (ATK_IS_OBJECT (accessible), 0);
561   g_return_val_if_fail ((handler != NULL), 0);
562
563   klass = ATK_OBJECT_GET_CLASS (accessible);
564   if (klass->connect_property_change_handler)
565     return (klass->connect_property_change_handler) (accessible, handler);
566   else
567     return 0;
568 }
569
570 /**
571  * atk_object_remove_property_change_handler:
572  * @accessible: an #AtkObject
573  * @handler_id : a guint which identifies the handler to be removed.
574  * 
575  * Removes a property change handler.
576  **/
577 void
578 atk_object_remove_property_change_handler  (AtkObject *accessible,
579                                             guint      handler_id)
580 {
581   AtkObjectClass *klass;
582
583   g_return_if_fail (accessible != NULL);
584   g_return_if_fail (ATK_IS_OBJECT (accessible));
585
586   klass = ATK_OBJECT_GET_CLASS (accessible);
587   if (klass->remove_property_change_handler)
588     (klass->remove_property_change_handler) (accessible, handler_id);
589 }
590
591 /**
592  * atk_implementor_ref_accessible:
593  * @implementor: The #GObject instance which should implement #AtkImplementorIface
594  * if a non-null return value is required.
595  * 
596  * Gets a reference to an object's #AtkObject implementation, if
597  * the object implements #AtkObjectIface
598  *
599  * Returns: a reference to an object's #AtkObject implementation
600  */
601 AtkObject *
602 atk_implementor_ref_accessible (AtkImplementor *object)
603 {
604   AtkImplementorIface *iface;
605   AtkObject           *accessible = NULL;
606
607   g_return_val_if_fail (object != NULL, NULL);
608   g_return_val_if_fail (ATK_IS_IMPLEMENTOR (object), NULL);
609
610   iface = ATK_IMPLEMENTOR_GET_IFACE (object);
611
612   if (iface != NULL) 
613     accessible =  iface->ref_accessible (object);
614
615   g_return_val_if_fail ((accessible != NULL), NULL);
616
617   return accessible;
618 }
619
620 static AtkRelationSet*
621 atk_object_real_ref_relation_set (AtkObject *accessible)
622 {
623   if (accessible->relation_set)
624     g_object_ref (accessible->relation_set); 
625
626   return accessible->relation_set;
627 }
628
629 static void
630 atk_object_real_set_property (GObject      *object,
631                               guint         prop_id,
632                               const GValue *value,
633                               GParamSpec   *pspec)
634 {
635   AtkObject *accessible;
636
637   accessible = ATK_OBJECT (object);
638
639   switch (prop_id)
640   {
641     case PROP_NAME:
642       atk_object_set_name (accessible, g_value_get_string (value));
643       break;
644     case PROP_DESCRIPTION:
645       atk_object_set_description (accessible, g_value_get_string (value));
646       break;
647     case PROP_STATE:
648       g_print ("This interface does not support setting the state set of an accessible object\n");
649       break;
650     default:
651       break;
652   }
653 }
654
655 static void
656 atk_object_real_get_property (GObject      *object,
657                               guint         prop_id,
658                               GValue       *value,
659                               GParamSpec   *pspec)
660 {
661   AtkObject *accessible;
662
663   accessible = ATK_OBJECT (object);
664
665   switch (prop_id)
666   {
667     case PROP_NAME:
668       g_value_set_string (value, atk_object_get_name (accessible));
669       break;
670     case PROP_DESCRIPTION:
671       g_value_set_string (value, atk_object_get_description (accessible));
672       break;
673     default:
674       break;
675   }
676 }
677
678 static void
679 atk_object_finalize (GObject *object)
680 {
681   AtkObject        *accessible;
682
683   g_return_if_fail (ATK_IS_OBJECT (object));
684
685   accessible = ATK_OBJECT (object);
686
687   g_free (accessible->name);
688   g_free (accessible->description);
689
690   /*
691    * Free memory allocated for relation set if it have been allocated.
692    */
693   if (accessible->relation_set)
694   {
695     g_object_unref (accessible->relation_set);
696   }
697
698   G_OBJECT_CLASS (parent_class)->finalize (object);
699 }
700
701 static void
702 atk_object_real_set_role (AtkObject *object,
703                           AtkRole   role)
704 {
705   object->role = role;
706 }